# Release Notes
# Версия 1.5 Daytona
Следующее изменение вступит в силу с активацией фичи № 23 “Boost Block Reward”.
Коэффициент ×10 применяется к вознаграждению за блок в течение 300 000 блоков на Mainnet (2000 блоков на Testnet и Stagenet) с момента активации фичи:
- Вознаграждение за блок станет равным 60 WAVES.
- Генератор блока, Waves DAO и смарт-контракт для выкупа XTN будут получать по 20 WAVES каждый.
- Вознаграждение может увеличиться или уменьшиться на 5 WAVES в результате голосования генераторов блоков.
Подробнее в разделе Монетарная политика, управляемая сообществом.
Изменения, перечисленные ниже, вступили в силу с активацией фичи № 22 “Light Node”.
# Развитие протокола
- Генератор блока, наряду с ключевым блоком и микроблоками, распространяет в сети снапшоты состояния. Снапшоты содержат изменения состояния блокчейна: балансов, записей данных, установленных скриптов и др., порожденные транзакциями, включенными в блок. Подробнее о протоколе Waves 1.5
- В случае несоответствия полученного по сети снапшота и блока, генерирующая нода может оспорить блок и получить вознаграждение вместо первоначального генератора.
- Прочие ноды получают возможность работать в легком режиме, применяя готовые снапшоты вместо валидации транзакций, и тем самым значительно ускорить обработку блоков. Легкий режим включается и отключается с помощью настройки
waves.enable-light-mode
(значение по умолчаниюno
). - В заголовок блока добавлены:
- поле
state_hash
, которое содержит хеш изменений состояния блокчейна, - сообщение
challenged_header
содержит поля заголовка блока, который был оспорен данным блоком.
- поле
- В ордер в составе транзакции обмена добавлено поле
attachment
. - Добавлена проверка на корректность длины ID токена в приложенном платеже при валидации транзакции вызова скрипта.
# База данных ноды
- Вместо LevelDB теперь используется RocksDB. Структура хранилища была обновлена, чтобы использовать улучшения и оптимизации RocksDB. При обновлении ноды потребуется заново импортировать блокчейн.
# Версия Java
- Для запуска ноды требуется OpenJDK версии 11 или 17. Версия 8 больше не поддерживается.
# Ride
- Выпущена версия 8 Стандартной библиотеки.
- Добавлены встроенные функции:
- replaceByIndex — заменяет элемент в списке по индексу.
- calculateDelay — вычисляет временную задержку перед генерацией блока.
- В структуру Order добавлено поле
attachment
. - Снижена сложность функций и операторов c аргументами типа BigInt.
- Отключена возможность установки скриптов, использующих Стандартную библиотеку версии 1–3, на аккаунты и ассеты. Ранее установленные скрипты продолжают работать.
# Node REST API
- В ответ методов, возвращающих блок или заголовок блока, добавлены поля заголовка блока
stateHash
иchallengedHeader
. - В ответ методов, возвращающих транзакции, добавлены поля
order1.attachment
иorder2.attachment
в составе транзакции обмена. - Добавлено значение
elided
поляapplicationStatus
для транзакций любого типа, ставших невалидными в результате оспаривания блока. - Удалены устаревшие методы API:
/debug/stateChanges/address/{address}/limit/{limit}
/debug/stateChanges/info/{id}
/debug/rollback-to/{id}
/assets/broadcast/*
/assets/[transfer,masstransfer,…]
/alias/broadcast/create
/alias/create
/leasing/lease
/leasing/cancel
/leasing/broadcast/*
POST /addresses/data
/blocks/signature
/utils/script/compile
/addresses/verify/{address}
/addresses/sign/{address}
/addresses/verifyText/{address}
/addresses/signText/{address}
/blocks/first
# Версия 1.4 Zegema
Следующее изменение вступит в силу с активацией фичи № 21 “Cease XTN buy-back”, но не ранее чем через 100 000 блоков после активации фичи № 19 на Mainnet (2000 блоков на Testnet, 1000 блоков на Stagenet):
- Зачисление доли вознаграждения за блок смарт-контракту для выкупа XTN будет прекращено. Его долю будет получать генератор блока.
Изменения, перечисленные ниже, вступили в силу с активацией фичи № 20 “Capped XTN buy-back & DAO amounts”.
Развитие протокола:
Распределение вознаграждения за блок корректируется следующим образом:
- Если активирована фича № 19 и вознаграждение за блок более 6 WAVES, то Waves DAO и смарт-контракт для выкупа XTN получают по 2 WAVES, а генератор блока — остальное.
- Если активирована фича № 19 и вознаграждение за блок составляет от 2 до 6 WAVES, то Waves DAO и смарт-контракт для выкупа XTN получают по
(R - 2) / 2
WAVES (подразумевается целочисленное деление), гдеR
— вознаграждение за блок. - Если фича № 19 не активирована или вознаграждение за блок менее 2 WAVES, генератор блока получает вознаграждение за блок полностью.
Период, на который устанавливается размер вознаграждения за блок, сокращается до 50 000 блоков. Голосование за размер вознаграждения по-прежнему проходит в последние 10 000 блоков этого периода.
Node REST API:
В ответ методов, возвращающих блок или заголовок блока, добавлено распределение вознаграждения за блок между адресами.
Пример:
{ ... "rewardShares": { "3MtmVzUQQj1keBsr3Pq5DYkutZzu5H8wdgA": 200000000, "3Myb6G8DkdBb8YcZzhrky65HrmiNuac3kvS": 100000000, "3N13KQpdY3UU7JkWUBD9kN7t7xuUgeyYMTT": 100000000 } }
Изменения, перечисленные ниже, вступили в силу с активацией фичи № 19 “Block Reward Distribution”.
Развитие протокола:
- Вознаграждение за блок распределяется между генератором блока, Waves DAO и смарт-контрактом для выкупа XTN. Waves DAO и смарт-контракт для выкупа XTN получают ⅓ вознаграждения за блок (подразумевается целочисленное деление), а генератор блока — остальное.
Ride:
- Выпущена версия 7 Стандартной библиотеки.
- В структуру BlockInfo, возвращаемую встроенной функцией blockInfoByHeight, добавлено поле
rewards: List[(Address, Int)]
.
Node REST API:
- В ответ метода
/blockchain/rewards
добавлены поляdaoAddress
иxtnBuybackAddress
.
Изменения, перечисленные ниже, вступили в силу с активацией фичи № 17 “Ride V6, MetaMask support”.
# Развитие протокола
- Добавлена поддержка Ethereum-like транзакций, выполняющих перевод токена или вызов dApp-скрипта. Благодаря этому пользователи MetaMask могут подписывать транзакции и отправлять их на блокчейн Waves. Подробнее
- Добавлена поддержка ордеров с подписью ECDSA в транзакции обмена. Благодаря этому пользователи могут подписывать ордера с помощью MetaMask. Подробнее
- Для ордера версии 4 добавлен параметр
priceMode
, который позволяет устанавливать цену аналогично ордеру версии 3. - Изменена минимальная комиссия за транзакцию установки скрипта: теперь комиссия зависит от размера скрипта.
- Слабые публичные ключи больше не могут использоваться для подписания транзакций.
# Ride
Выпущена версия 6 Стандартной библиотеки.
Максимальная сложность вызываемой функции скрипта dApp в Стандартной библиотеке версии 6 увеличена до 52 000.
Максимальная суммарная сложность всех вызываемых функций и скриптов ассетов в одной транзакции зависит от версии Стандартной библиотеки dApp-скрипта, который вызван первым:
- Если первый dApp-скрипт использует версию 6, то суммарная сложность — не более 52 000.
- Если первый dApp-скрипт использует версию 5, то суммарная сложность — не более 26 000. Если далее вызываются функции скриптов версии 6, их сложность может превышать 10 000 и ограничена только суммарной сложностью транзакции.
Сложность скрипта отправителя не учитывается в этом лимите.
Новые правила оценки сложности снижают общую сложность скрипта.
Максимальный размер dApp-скрипта увеличен до 160 Кбайт независимо от версии Стандартной библиотеки.
Общее количество действий скрипта
ScriptTransfer
,Lease
,LeaseCancel
, выполняемых всеми вызываемыми функциями в одной транзакции, — не более 100.Общее количество действий скрипта
Issue
,Reissue
,Burn
,SponsorFee
, выполняемых всеми вызываемыми функциями в одной транзакции, — не более 30.Вызываемые функции больше не принимают аргументы типа Union.
Добавлены встроенные функции:
Изменено ограничение на второй параметр функций строки и функций массива байтов
drop
,dropRight
,take
,takeRight
.Изменены ограничения на размер входных и выходных данных для встроенных функций строки makeString и split; сложность этих функций уменьшена до 1. Добавлены семейства аналогичных функций с различной сложностью в зависимости от размера данных.
Изменена сложность некоторых встроенных функций. Сложность всех функций представлена в разделе Встроенные функции.
Введено ограничение на общее количество платежей, приложенных к вызовам dApp-скриптов, в одной транзакции: не более 100. Ограничение не зависит от используемых версий Стандартной библиотеки.
# Node REST API
- В конфигурацию ноды добавлена группа настроек CORS. Старые настройки
waves.rest-api.cors
иwaves.rest-api.api-key-different-host
отключены.
# Ломающие изменения
Добавлена поддержка Ethereum-like транзакций, выполняющих перевод токена или вызов dApp-скрипта. JSON-представление транзакции зависит от ее содержания:
Пример перевода
{ "type": 18, "id": "C4Fwdsygb6uL6iZ2dd6dHCdnw5FB2oZNCdpQ1F5kQ7Q9", "fee": 210000, "feeAssetId": null, "timestamp": 1634807137059, "version": 1, "chainId": 83, "bytes": "0xf87486017ca21943238502540be4008303345094ae50afd342b8f397bcd1c2af3fd658d5080674058806f05b59d3b200008081caa0e87f0e273e8ad894ab196198747a0363b66c5bd056f1e09bb6f8b18f6c11dbafa07dd6b2ac30d2d1ac1196a34a8db5adbd8f69b8f349b15f45c6bbf4040de7519d", "sender": "3MTPx4QwYZg78QwAw4Pdm3feBpwe9qMzL5X", "senderPublicKey": "2ZWaWoMYAdkKfUUYwKng29Dgq1ggBPYtbsrvKBxxKcP3SkpXy1USEJiPPL6U7H7ECD3bD3QcZy2mmtN9EzsK2SHV", "height": 1040780, "applicationStatus": "succeeded", "payload": { "type": "transfer", "recipient": "3MgUB2QfTH8jMLYwuNrYq2SSUJdGcjvBk6n", "asset": null, "amount": 50000000 }
Пример вызова скрипта
{ "type": 18, "id": "2Y67uLthNfzEBpEJFyrP7MKqPYTFYjM5nz2NnETZVUYU", "fee": 500000, "feeAssetId": null, "timestamp": 1634881836984, "version": 1, "chainId": 83, "bytes": "0xf9011186017ca68d17b88502540be4008307a120940ea8e14f313237aac31995f9c19a7e0f78c1cc2b80b8a409abf90e0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000064672696461790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000081caa0ecb7124f915bd366186a6451aabdde3fbf0db94caa78a6b8d6115bb5ce6407d8a077ab1e756d343b9927c3c4add5c797915aef2de112576213d6a30ce5e040ba3c", "sender": "3MRejoFLZ6FsXRjVEzBpnQ27s61FDLLDGxh", "senderPublicKey": "3nFhfAYDSRS4UrU22HaAuFT4YHZD5Et3vy7fBTcTxefuAVXs8pHRR4pvpAzvMbmskwjWB7PxFKqPNsioRVZ9mxaa", "height": 1042032, "applicationStatus": "succeeded", "payload": { "type": "invocation", "dApp": "3MRuzZVauiiX2DGwNyP8Tv7idDGUy1VG5bJ", "call": { "function": "saveString", "args": [ { "type": "string", "value": "Friday" } ] }, "payment": [], "stateChanges": { "data": [ { "key": "str_1042032", "type": "string", "value": "Friday" } ], "transfers": [], "issues": [], "reissues": [], "burns": [], "sponsorFees": [], "leases": [], "leaseCancels": [], "invokes": [] } } }
Особенности JSON-представления Ethereum-like транзакции:
- поле
sender
содержит адрес в представлении Waves в кодировке base58, - поле
senderPublicKey
размером 64 байта в кодировке base58, - поле
bytes
содержит байты Ethereum-like транзакции целиком, включая подпись ECDSA, в кодировке HEX. - массив
proofs
отсутствует.
- поле
Добавлена поддержка транзакций обмена, содержащих ордер (или оба ордера) с подписью ECDSA.
Пример ордера с подписью ECDSA
"order1": { "version": 4, "id": "2Wx5ctbaU9GqQYXtEkqsin6drfu6SuADdwAyvuYnwai9", "sender": "3FzoJXUesFqzf4nmMYejpUDYmFJvkwEiQG6", "senderPublicKey": "5BQPcwDXaZexgonPb8ipDrLRXY3RHn1kFLP9fqp1s6M6xiRhC4LvsAq2HueXCMzkpuXsrLnuBA3SdkJyuhNZXMCd", "matcherPublicKey": "9BUoYQYq7K38mkk61q8aMH9kD9fKSVL1Fib7FbH6nUkQ", "assetPair": { "amountAsset": "5fQPsn8hoaVddFG26cWQ5QFdqxWtUPNaZ9zH2E6LYzFn", "priceAsset": null }, "orderType": "buy", "amount": 1, "price": 100, "timestamp": 1, "expiration": 123, "matcherFee": 100000, "signature": "", "proofs": [], "matcherFeeAssetId": null, "eip712Signature": "0xe5ff562bfb0296e95b631365599c87f1c5002597bf56a131f289765275d2580f5344c62999404c37cd858ea037328ac91eca16ad1ce69c345ebb52fde70b66251c" }
Особенности JSON-представления ордера с подписью ECDSA:
- поле
sender
содержит адрес в представлении Waves в кодировке base58, - поле
senderPublicKey
размером 64 байта в кодировке base58, - поле
eip712Signature
содержит подпись ECDSA в кодировке HEX, - массив
proofs
отсутствует.
- поле
# Версия 1.3 Jumeirah
Изменения, перечисленные ниже, вступили в силу с активацией фичи № 16 “Ride V5, dApp-to-dApp invocations”.
# Развитие протокола
- Вызов dApp из dApp. Вызываемая функция dApp-скрипта может выполнять вложенные вызовы. Из dApp можно вызвать вызываемую функцию другого dApp или того же самого dApp, в том числе функция может вызвать сама себя. Все вызванные функции выполняются в рамках одной транзакции вызова скрипта. Подробнее о вызове dApp из dApp
- Изменения для транзакции вызова скрипта:
- Отменена дополнительная комиссия 0,004 WAVES за выполнение скриптов ассетов в платежах и действиях скрипта.
- Транзакция может содержать до 10 приложенных платежей.
- Суммарная сложность всех вызываемых функций и скриптов ассетов в одной транзакции — не более 26 000 (cложность скрипта отправителя не учитывается в этом лимите).
- Максимальная сложность вызываемой функции скрипта dApp изменена на 10 000.
- Для всех типов транзакций отменена дополнительная комиссия 0,004 WAVES за отправку транзакции со смарт-аккаунта или dApp, в случае если сложность скрипта аккаунта или функции-верификатора dApp-скрипта не превышает 200.
# Ride
Выпущена версия 5 Стандартной библиотеки.
Реализована возможность обрабатывать в dApp до 10 платежей, приложенных к транзакции вызова скрипта.
Начиная с версии 5 Стандартной библиотеки, при выполнении dApp-скрипта приложенные к вызову платежи считаются уже зачисленными на баланс dApp (в отличие от версий 4 и 3, где платежи не отражаются на балансе до окончания выполнения скрипта).
Добавлены функции для вызова dApp из dApp:
Добавлены нетерпеливые переменные, которые вычисляются до следующего выражения, чтобы гарантировать порядок выполнения и применения действий скрипта вызываемых функций.
Изменен формат результата вызываемой функции: добавлено возвращаемое значение.
Изменена структура Invocation: в случае вызова dApp из dApp она содержит адрес и публичный ключ как отправителя транзакции вызова скрипта, так и аккаунта dApp, который вызывает функцию.
Общее количество действий скрипта
Issue
,Reissue
,Burn
,SponsorFee
,ScriptTransfer
,Lease
,LeaseCancel
, выполняемых всеми вызываемыми функциями в одной транзакции, — не более 30.Общее количество действий скрипта
BinaryEntry
,BooleanEntry
,IntegerEntry
,StringEntry
,DeleteEntry
, выполняемых всеми вызываемыми функциями в одной транзакции, — не более 100.Добавлены действия скрипта, которые может выполнять вызываемая функция:
- Lease — передает WAVES в лизинг.
- LeaseCancel — прекращает лизинг.
С помощью действий
Lease
иLeaseCancel
можно изменить сумму лизинга, в частности, извлечь часть средств из лизинга. Если в одном вызове скрипта отменить лизинг на большую сумму и создать новый лизинг на меньшую сумму с тем же получателем, генерирующий баланс получателя уменьшится на разницу. Если же отправить две отдельные транзакции — транзакцию отмены лизинга и транзакцию лизинга, они могут попасть в разные блоки, и тогда генерирующий баланс сразу же уменьшится на сумму отмененного лизинга, а увеличится на сумму нового лизинга только через 1000 блоков.Добавлена встроенная функция calculateLeaseId для получения ID лизинга, сформированного структурой
Lease
.Добавлен произвольный тип данных — Any.
Добавлен тип данных BigInt размером 64 байта (512 бит) и поддерживающие его функции:
- fraction(BigInt, BigInt, BigInt): BigInt
- fraction(BigInt, BigInt, BigInt, Union): BigInt
- log(BigInt, Int, BigInt, Int, Int, Union): BigInt
- max(List[BigInt]): BigInt
- median(List[BigInt]): BigInt
- min(List[BigInt]): BigInt
- pow(BigInt, Int, BigInt, Int, Int, Union): BigInt
- parseBigInt(String): BigInt|Unit
- parseBigIntValue(String): BigInt
- toBigInt(ByteVector): BigInt
- toBigInt(ByteVector, Int, Int): BigInt
- toBigInt(Int): BigInt
- toBytes(BigInt): ByteVector
- toInt(BigInt): Int
- toString(BigInt): String
Добавлены встроенные функции:
- isDataStorageUntouched — проверяет, что хранилище данных указанного аккаунта никогда не содержало записей.
- scriptHash — возвращает BLAKE2b-256-хеш скрипта, установленного на аккаунте.
- fraction(Int, Int, Int, Union): BigInt — умножает два целых числа и делит на третье без переполнения, применяя указанный метод округления.
Добавлены встроенные функции хранилища данных аккаунта, позволяющие dApp-скрипту читать записи из собственного хранилища данных:
getBinary(key: String): ByteVector|Unit
getBinaryValue(key: String): ByteVector
getBoolean(key: String): Boolean|Unit
getBooleanValue(key: String): Boolean
getInteger(key: String): Int|Unit
getIntegerValue(key: String): Int
getString(key: String): String|Unit
getStringValue(key: String): String
Максимальная сложность вызываемой функции скрипта dApp изменена на 10 000.
# Node REST API
# Ломающие изменения
Лизинг может быть создан не только в результате транзакции лизинга, но и в результате транзакции вызова скрипта с помощью действия скрипта Lease
. Поэтому изменен формат ответа следующих методов:
- В ответе методов
/transactions/address/{address}/limit/{limit}
и/transactions/info/{id}
для транзакции отмены лизинга структураlease
теперь содержит не транзакцию лизинга, а структуру с параметрами лизинга. /leasing/active/{address}
возвращает не массив транзакций лизинга, а массив структур c параметрами лизингов.
Формат
"lease": {
"id": "7bRbb9DH6V2ztdbmsZhWLdhTPQD14t8W38GjrtW8ug1N",
"originTransactionId": "7bRbb9DH6V2ztdbmsZhWLdhTPQD14t8W38GjrtW8ug1N",
"sender": "3MqqqDw65oL423pjsdeAS5vcRyXa9bmruGx",
"recipient": "3Mz9N7YPfZPWGd4yYaX6H53Gcgrq6ifYiH7",
"amount": 400000000,
"height": 1560062,
"status": "canceled"
}
Поле originTransactionId
может содержать идентификатор транзакции лизинга или транзакции вызова скрипта.
# Семантические изменения
Результат вызова dApp из dApp добавлен в виде массива
invokes
в структуруstateChanges
, возвращаемую следующими методами:/transactions/info/{id}
/transactions/address/{address}/limit/{limit}
Каждый элемент массива
invokes
, в свою очередь, содержитstateChanges
.Формат
"stateChanges": { "data": [ { "key": "test_key_1", "type": "integer", "value": 14 }, { "key": "test_key_2", "type": "integer", "value": 999000000 } ], "transfers": [], "issues": [], "reissues": [], "burns": [], "sponsorFees": [], "leases": [], "leaseCancels": [], "invokes": [ { "dApp": "3N4o9UGcFTDxcJptFG2yimYpLqLLoD44diX", "call": { "function": "bar", "args": [ { "type": "Int", "value": 7 } ] }, "payments": [ { "asset": "25FEqEjRkqK6yCkiT7Lz6SAYz7gUFCtxfCChnrVFD5AT", "amount": 1000000 } ], "stateChanges": { "data": [], "transfers": [ { "address": "3ND86XoiA9ytxysBCvhkRQez82R3d6wZBzP", "asset": null, "amount": 100000000 } ], "issues": [], "reissues": [], "burns": [], "sponsorFees": [], "leases": [], "leaseCancels": [], "invokes": [] } } ] }
Результат действий скрипта
Lease
иLeaseCancel
также добавлен в структуруstateChanges
.Формат
"stateChanges": { "data": [], "transfers": [], "issues": [], "reissues": [], "burns": [], "sponsorFees": [], "leases": [{ "id": "94PfEzE3yCo1wVrZGubMwqJgNYLHVBxae5psdeZu9c1c", "originTransactionId": "Dc5fzXUKVDd22PbJFt2T5RSsNieFCJwwpuWUsGR4YDZs", "sender": "3MopBTg99nDNv4gfQf76WnuPrnPq1TppDEp", "recipient": "3MT5dAS4Zr2g8MBLSPnbyAM18pf7A2PUuMY", "amount": 444444, "height": 817572, "status": "active" }], "leaseCancels": [{ "id": "5NTgkz8rT8RwSSLbBhyE6yev824Ff8NLStzMreGFEpWk", "originTransactionId": "Fr8pwXPK81rXRGs9rwpZaQKHPa8irY3GL4bWXUGemvZi", "sender": "3MopBTg99nDNv4gfQf76WnuPrnPq1TppDEp", "recipient": "3MT5dAS4Zr2g8MBLSPnbyAM18pf7A2PUuMY", "amount": 12000000, "height": 817540, "status": "canceled" }], "invokes": [] }
Результат действий скрипта
Lease
иLeaseCancel
добавлен в структуруtrace
, возвращаемую следующими методами:/transactions/broadcast
c параметромtrace=true
/debug/validate
Формат
"trace": [ { "id": "3MosFNQAFGskNDnYzRBgMbfod6xXPdG96ME", "type": "dApp", "vars": [ { "name": "amount", "type": "integer", "value": 12345 } ], "result": { "leases": [ { "id": "F3ZmBbig3gekPu4a8fyrZGiU53MFxtFSWKw5dTyTMvq7", "originTransactionId": "6GLmdBZZeevtbomFYif5ys7Ltf2DuXMGP29bLrSoX9HA", "sender": "3MUAwJP3ThWNrRcxwAB8QHrvo7BEQbRFdu9", "recipient": "3MbwwebM61Y11UFZwkdQ1gXUJjY27ww1r6z", "amount": 200000000, "height": 739442 }, ], "leaseCancels": [ { "id": "DH7N1XW7tTNwHBmFsfeArP6hWfzrC4fGcsKPEMfFZpPL", "originTransactionId": "DH7N1XW7tTNwHBmFsfeArP6hWfzrC4fGcsKPEMfFZpPL", "sender": "3MUAwJP3ThWNrRcxwAB8QHrvo7BEQbRFdu9", "recipient": "3MbwwebM61Y11UFZwkdQ1gXUJjY27ww1r6z", "amount": 300000000, "height": 739436 } ] } } ]
# Улучшения
Новый метод
/leasing/info
возвращает параметры лизингов с указанными идентификаторами.Формат
[ { "id": "DNZ8tpZt6i9fTRW6b7UmBV9LHNmX4c5EgeTMhcNk3ReB", "originTransactionId": "Dc5fzXUKVDd22PbJFt2T5RSsNieFCJwwpuWUsGR4YDZs", "sender": "3MgPxT7piLX6u3yqDFNUTPL93b5dhdpuYKH", "recipient": "3MT5dAS4Zr2g8MBLSPnbyAM18pf7A2PUuMY", "amount": 222222, "height": 817572, "status": "active", "cancelHeight": null, "cancelTransactionId": null }, { "id": "5NTgkz8rT8RwSSLbBhyE6yev824Ff8NLStzMreGFEpWk", "originTransactionId": "Fr8pwXPK81rXRGs9rwpZaQKHPa8irY3GL4bWXUGemvZi", "sender": "3MopBTg99nDNv4gfQf76WnuPrnPq1TppDEp", "recipient": "3MT5dAS4Zr2g8MBLSPnbyAM18pf7A2PUuMY", "amount": 12000000, "height": 817540, "status": "canceled", "cancelHeight": 817572, "cancelTransactionId": "Dc5fzXUKVDd22PbJFt2T5RSsNieFCJwwpuWUsGR4YDZs" } ]
Если база данных на ноде не была перестроена после активации фичи № 16, метод не возвращает поле
leaseCancelTransactionId
для лизингов, отмененных до активации фичи № 16.Новый метод
/blocks/heightByTimestamp/{timestamp}
возвращает высоту блокчейна в указанный момент времени.
# Версия 1.2 Malibu
Изменения, перечисленные ниже, вступили в силу с активацией фичи № 15 “Ride V4, VRF, Protobuf, Failed transactions”.
# Развитие протокола
- Усовершенствован механизм генерации блоков за счет использования VRF (Verifiable random function). Это улучшение позволяет противостоять атакам типа stake grinding, при помощи которых злоумышленники пытаются повысить для себя вероятность генерации блока.
- Добавлено сохранение транзакций с неудачным результатом выполнения скрипта. Транзакции вызова скрипта и транзакции обмена сохраняются на блокчейне и за них взимается комиссия, даже если результат выполнения dApp-скрипта или скрипта ассета был неудачным (при условии что транзакция прошла проверку подписи отправителя или проверку скриптом аккаунта, а при вызове скрипта сложность вычислений превысила порог для сохранения неуспешных транзакций). Подробнее
- Реализована возможность изменять наименование и описание ассета. Для этого добавлен новый тип транзакции — транзакция обновления информации ассета. Изменение возможно не чаще чем через 10 блоков на Stagenet и не чаще чем через 100 000 блоков на Mainnet и Testnet.
- Реализована возможность удалять записи в хранилище данных аккаунта. Это действие может быть выполнено при помощи транзакции данных либо структуры DeleteEntry языка Ride.
- Снижена минимальная комиссия за транзакцию довыпуска и транзакцию спонсирования — с 1 до 0,001 WAVES.
- Бинарные форматы транзакций реализованы на основе protobuf.
- В транзакции выпуска формат полей
name
иdescription
изменен с bytes на string. - В транзакции данных максимальный размер данных увеличен до 165 890 байт.
- В транзакции обмена ордера на покупку и продажу могут быть указаны в любом порядке.
- Изменена формула расчета price в ордерах. Ранее, при определении price для ассетов с разным количеством десятичных знаков, возникала проблема с величиной price. Её максимальное значение зависело от разности десятичных знаков ассетов. К примеру, price для NFT-ассета не мог превышать 1000 WAVES. Измененная формула исправляет эту проблему. Разность десятичных знаков больше не влияет на максимальный размер price.
- Минимальный интервал между блоками увеличен с 5 до 15 секунд. Среднее время генерации блока установлено в 60 секунд вместо ~59.
- Изменена схема подписания майнящей нодой транзакций блока. Ранее майнящей ноде требовалось подписывать блок вместе со всеми транзакциями. Теперь в заголовок блока добавлен корневой хеш транзакций, поэтому достаточно подписать только заголовок.
- В качестве идентификатора блока используется хеш BLAKE2b-256 заголовка блока.
- Теперь при валидации транзакции перед ее добавлением в пул неподтвержденных транзакций учитываются изменения состояния блокчейна, внесенные транзакциями, которые были ранее добавлены в блок, но затем возвращены в пул неподтвержденных транзакций из-за появления нового ключевого блока, ссылающегося на один из предшествующих микроблоков.
- dApp не может вызвать самого себя с помощью транзакции вызова скрипта с приложенными платежами. dApp также не может переводить средства самому себе с помощью действия скрипта
ScriptTransfer
.
# Обновления REST API
В релизе ноды 1.2 внесены семантические и ломающие изменения в API. Прочитайте внимательно описание изменений: они могут повлиять на работу приложений при миграции с версии 1.1.
# Семантические изменения
Транзакции вызова скрипта и транзакции обмена могут быть сохранены как неуспешные. Их присутствие на блокчейне не означает, что изменения применены: нужно проверить также поле
applicationStatus
. Его возвращают следующие методы:/blocks/{id}
/blocks/address/{address}/{from}/{to}
/blocks/at/{height}
/blocks/last
/blocks/seq/{from}/{to}
/debug/stateChanges/address/{address}/limit/{limit}
/debug/stateChanges/info/{id}
/transactions/address/{address}/limit/{limit}
/transactions/info/{id}
/transactions/status
Значения
applicationStatus
:succeeded
— транзакция успешна;script_execution_failed
— результат выполнения dApp-скрипта или скрипта ассета был неудачным.
Для неуспешных транзакций вызова скрипта причина ошибки указывается в структуре
error
в ответе методов:/debug/stateChanges/address/{address}/limit/{limit}
/debug/stateChanges/info/{id}
Формат:
"stateChanges": { "error": { "code": number, "text": string } }
Коды ошибок:
1 — ошибка выполнения dApp-скрипта
2 — недостаточно комиссии для оплаты действий скрипта
3 — скрипт ассета в действиях dApp-скрипта отклонил транзакцию
4 — скрипт ассета в приложенных платежах отклонил транзакцию
Для транзакции вызова скрипта результат новых действий скрипта отображается в ответе методов:
/debug/stateChanges/address/{address}/limit/{limit}
/debug/stateChanges/info/{id}
Формат:
"stateChanges": { "data": [], "transfers": [], "issues": [], "reissues": [], "burns": [], "sponsorFees": [] }
Для блока версии 5 поле
reference
ссылается наid
предыдущего блока, а не наsignature
, как в версии 4.
# Ломающие изменения
Получение блока по
id
вместоsignature
.Удалены методы:
/blocks/signature/{signature}
— вместо него используйте/blocks/{id}
/blocks/child/{signature}
Затронуты методы:
/blocks/delay/{id}/{blockNum}
/blocks/height/{id}
/debug/rollback-to/{id}
Удален метод
/consensus/generationsignature
.Изменена структура
meta
в ответе метода/addresses/scriptInfo/{address}/meta
. Список аргументов теперь представлен в виде массива объектов, а не map.Было:
"meta": { "callableFuncTypes": { "funcName": { "arg1": string, "arg2": string } } }
Стало:
"meta": { "callableFuncTypes": { "funcName": [ { "name": string, "type": string }, { "name": string, "type": string } ] } }
Добавлен новый тип транзакции: транзакция обновления информации ассета.
Транзакция вызова скрипта может содержать аргументы типа
List
.Пример:
{ "call": { "function": string, "args": [ ["arg1-item1", "arg1-item2", "arg1-item3"] ] } }
Записи в хранилище данных аккаунта могут быть удалены транзакциями данных и транзакциями вызова скрипта. Удаление записи выглядит как структура
{ "key": string, "value": null }
, гдеvalue
равно null, аtype
отсутствует. Затронуты методы:/blocks/{id}
/blocks/address/{address}/{from}/{to}
/blocks/at/{height}
/blocks/last
/blocks/seq/{from}/{to}
/debug/stateChanges/address/{address}/limit/{limit}
/debug/stateChanges/info/{id}
/transactions/address/{address}/limit/{limit}
/transactions/info/{id}
Транзакция обмена версии 3 может содержать ордера на покупку и продажу в любом порядке.
# Улучшения
Метод
/debug/validate
не требует указания API-key.Метод
/assets/details
позволяет получать информацию сразу по нескольким ассетам. В ответ добавлено полеoriginTransactionId
, содержащее ID транзакции, выпустившей ассет. Кроме того, поддерживаются POST-запросы.Метод
/addresses/balance
позволяет получать балансы сразу для нескольких адресов на заданной высоте, не далее 2000 от текущей.В ответ метода
/assets/nft/{address}/limit/{limit}
добавлен массивassetDetails
со списком NFT, принадлежащих адресу. Также поддерживаются POST-запросы.Следующие методы возвращают сложность каждой вызываемой функции и функции-верификатора:
/addresses/scriptInfo/{address}
/utils/script/compileCode
/utils/script/estimate
Формат:
{ "complexity": number, "callableComplexities": { "funcName1": number, "funcName2": number }, "verifierComplexity": number }
Новый метод
/transactions/merkleProof
принимает на вход ID транзакции или массив ID транзакций и возвращает массив доказательств для проверки присутствия транзакции в блоке.В следующие методы добавлены поля
id
иtransactionsRoot
:/blocks/{id}
/blocks/headers/last
/blocks/headers/seq/{from}/{to}
/blocks/headers/at/{height}
/blocks/at/{height}
/blocks/address/{address}/{from}/{to}
/blocks/last
/blocks/seq/{from}/{to}
# Изменения Ride
Выпущена версия 4 Стандартной библиотеки.
Добавлены действия скрипта, которые может выполнять вызываемая функция dApp-скрипта:
- Issue — выпуск токена.
- Reissue — довыпуск токена.
- Burn — сжигание токена.
- SponsorFee — настройка спонсирования.
- BooleanEntry, BinaryEntry, IntegerEntry, StringEntry — добавление или изменение записи соответствующего типа в хранилище данных аккаунта. Эти действия используются вместо DataEntry, которая не поддерживается в версии 4.
- DeleteEntry — удаление записи из хранилища данных аккаунта.
Изменен формат результата вызываемой функции: в версии 4 результат представляет собой список действий скрипта. Структуры
ScriptResult
,WriteSet
иTransferSet
не поддерживаются.Комиссия за выполнение транзакции вызова скрипта увеличивается на 1 WAVES за каждый ассет (кроме NFT), выпущенный при помощи структуры
Issue
.Реализована возможность обрабатывать в dApp до двух платежей, приложенных к транзакции вызова скрипта.
Реализована возможность использовать список в качестве аргумента вызываемой функции.
Добавлены встроенные функции:
- bn256Groth16Verify — семейство функций верификации доказательства с нулевым разглашением zk-SNARK по протоколу groth16 на кривой bn254. Сложность 800–1650 в зависимости от размера массива публичных входов.
- calculateAssetId — получает ID ассета, сформированного структурой Issue при выполнении транзакции вызова скрипта. Сложность равна 10.
- contains — проверяет, содержит ли строка заданную подстроку. Сложность 3.
- containsElement — проверяет наличие элемента в списке. Сложность 5.
- createMerkleRoot — вычисляет корневой хеш дерева Меркла транзакций блока. Сложность 30.
- ecrecover — возвращает открытый ключ, восстановленный из хеша сообщения и цифровой подписи ECDSA. Сложность 70.
- groth16Verify — семейство функций верификации доказательства с нулевым разглашением zk-SNARK по протоколу groth16 на кривой bls12-381. Сложность 1200–2700 в зависимости от размера массива публичных входов.
- indexOf — возвращает индекс первого вхождения элемента в списке. Сложность 5.
- lastIndexOf — возвращает индекс последнего вхождения элемента в списке. Сложность 5.
- makeString — объединяет строки из списка, используя разделитель. Сложность 30.
- max — возвращает наибольший элемент в списке. Сложность 3.
- median — вычисляет медиану списка целых чисел. Сложность 20.
- min — возвращает наименьший элемент в списке. Сложность 3.
- removeByIndex — удаляет элемент из списка по индексу. Сложность 7.
- transferTransactionFromProto — десериализует транзакцию перевода. Сложность 5.
- valueOrElse(t: T|Unit, t0 : T) — получение значения из параметра типа данных объединение. Сложность 2.
Встроенная функция wavesBalance возвращает структуру BalanceDetails, которая содержит все виды баланса WAVES.
В структуру Asset, возвращаемую встроенной функцией assetInfo, добавлены поля
name
иdescription
.Для встроенных функций хеширования
blakeb256
,keccak256
,sha256
и встроенных функций верификацииrsaVerify
,sigVerify
в версии 4 изменена сложность и добавлены семейства аналогичных функций с различной сложностью в зависимости от размера аргумента. Если размер данных известен заранее, можно использовать более «дешевую» функцию.Изменена сложность некоторых встроенных функций. Список приведен в разделе Встроенные функции.
Следующие функции не поддерживаются в версии 4:
- extract — вместо нее рекомендуется использовать value;
- checkMerkleProof — вместо нее рекомендуется использовать createMerkleRoot
Добавлены встроенные операторы работы со списками:
- Конкатенация при помощи оператора
++
. Пример: результатом выражения[1, 2] ++ [3, 4]
будет[1, 2, 3, 4]
. Сложность равна 4. - Добавление элемента в конец списка. Пример: результатом выражения
["foo","bar"] :+ "baz"
будет["foo", "bar", "baz"]
. Сложность равна 1.
- Конкатенация при помощи оператора
Добавлен тип данных Кортеж.
Максимальная сложность скрипта аккаунта и функции-верификатора скрипта dApp изменена на 2000 для новых скриптов, независимо от версии Стандартной библиотеки.
Максимальная сложность скрипта ассета и вызываемой функции скрипта dApp осталась прежней — 4000.
Изменен максимальный размер данных:
- String — 32 767 байт
- ByteVector — 32 767 байт (кроме поля
bodyBytes
структуры транзакции)
# Waves Explorer
- Добавлено отображение транзакций с неудачным результатом выполнения dApp-скрипта или скрипта ассета, сохраненных на блокчейне. В списке транзакций они отмечены значком .
- Для транзакции вызова скрипта поддерживается отображение нескольких платежей. Результат выполнения скрипта отображается в виде таблицы.
- Добавлено отображение нового типа транзакций — транзакций обновления информации ассета.
- На страницу с информацией об ассете добавлена ссылка на транзакцию выпуска ассета.
- На страницу с информацией о блоке добавлено поле Block ID.