waves_logo Docs
  • Будьте в курсе
    Будьте в курсе
  • Release notes
    Release notes
  • Release notes (Node Go)
    Release notes (Node Go)
  • MetaMask
    MetaMask
  • Сохранение транзакций с неудачным результатом выполнения скрипта
    Сохранение транзакций с неудачным результатом выполнения скрипта
  • Обновления в документации
    Обновления в документации
      • English
      • Русский
      On this page
        • Версия 1.5 Daytona
        • Версия 1.4 Zegema
        • Версия 1.3 Jumeirah
        • Версия 1.2 Malibu
      waves_logo Docs

          # 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.

          • Добавлены встроенные функции:

            • sqrt(Int,Int,Int,Union)
            • sqrt(BigInt,Int,Int,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:

            • invoke
            • reentrantInvoke
          • Добавлены нетерпеливые переменные, которые вычисляются до следующего выражения, чтобы гарантировать порядок выполнения и применения действий скрипта вызываемых функций.

          • Изменен формат результата вызываемой функции: добавлено возвращаемое значение.

          • Изменена структура 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.
          Будьте в курсе
          Release notes (Node Go)
          Будьте в курсе
          Release notes (Node Go)