# Release Notes
# Version 1.3 (Stagenet)
# Protocol Enhancements
- dApp-to-dApp invocation. A dApp callable function can invoke a callable function of another dApp, or another callable function of the same dApp, or even itself. All invoked functions are executed within a single Invoke Script transaction. The total complexity is limited. More about dApp-to-dApp invocation
- Continued computations. Added support for dApp scripts with complexity over 4000. The execution of such a script is split into several stages. The first stage of computations is performed within the Invoke Script transaction. The further stages are performed within Continuation transactions. More about continued computations
- Implemented the new transaction type: Continuation. A block generator creates the Continuation transaction if there is an incomplete computation sequence. A user cannot send a Continuation transaction.
- Added version 3 for the Invoke Script transaction that can invoke a script with complexity over 4000.
# Ride
Issued version 5 of the Ride Standard library.
Added the Invoke function for dApp-to-dApp invocation.
Added strict variables that are evaluated before the next expression to ensure executing callable functions and applying their actions in the right order.
Modified the callable function result by adding a return value.
Added script actions that the callable function can perform:
- Lease — leases WAVES.
- LeaseCancel — cancels a specified lease.
Using these actions, you can change the amount of the lease, in particular, withdraw a part of the leased funds. If you cancel a lease for a larger amount and create a new lease for a smaller amount with the same recipient in the same script invocation, the recipient's generating balance decreases by the difference. Otherwise, if you send two separate transactions: a Lease Cancel transaction and a Lease transaction, they can be added to a different blocks and therefore generating balance decreases by the amount of the canceled lease immediately and increases by the amount of the new lease after 1000 blocks.
Added the function calculateLeaseId that calculates ID of the lease formed by the
Lease
structure.Added the following account data storage functions that allow the dApp script to read entries of its own data storage at any stage of the computations:
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
Added an arbitrary data type — Any.
# Node REST API
# Breaking Changes
Added the new transaction type: Continuation.
A lease can be created both as a result of a Lease transaction and as a result of an Invoke Script transaction via a
Lease
script action. Therefore, the response of the following endpoints has been changed:- In the response of
/transactions/address/{address}/limit/{limit}
and/transactions/info/{id}
endpoints for Lease Cancel transaction, thelease
structure now contains lease parameters instead of Lease transaction fields. /leasing/active/{address}
returns an array of structures containing lease parameters instead of array of Lease transactions.
Format
"lease": { "leaseId": "4AZU8XPATw3QTX3BLyyc1iAZeftSxs7MUcZaXgprnzjk", "originTransactionId": "4AZU8XPATw3QTX3BLyyc1iAZeftSxs7MUcZaXgprnzjk", "sender": "3PC9BfRwJWWiw9AREE2B3eWzCks3CYtg4yo", "recipient": "3PMj3yGPBEa1Sx9X4TSBFeJCMMaE3wvKR4N", "amount": 1000000000000, "height": 2253315 }
The
originTransactionId
field can contain an ID of a Lease Transaction or an Invoke Script transaction.- In the response of
# Semantic Changes
For Invoke Script transaction version 3 the fields
extraFeePerStep
andcontinuationtransactionIds
and thescript_execution_in_progress
value for theapplicationStatus
field added to the output of the endpoints providing transaction info.dApp-to-dApp invocation results are added as the
invokes
array to thestateChanges
structure returned by the following endpoints:/transactions/info/{id}
/transactions/address/{address}/limit/{limit}
Each element of
invokes
array, in turn, also containsstateChanges
.Format
"stateChanges": { "data": [], "transfers": [], "issues": [], "reissues": [], "burns": [], "invokes": [ { "dApp": "3PC9BfRwJWWiw9AREE2B3eWzCks3CYtg4yo", "payment": [ { "amount": 50000000, "assetId": "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p" } ], "call": { "function": "swapNeutrinoToWaves", "args": [ { "type": "string", "value": "EUR" }, { "type": "integer", "value": 843699 }, { "type": "binary", "value": "base64:OK+armP11YmAyoQOwl8jLDLi2dK2sRc1Ue2QzZX1wgRmwGASLhllv1iKg2fRKS8cAlSDrfMYPb6374WMC9gFgA==" } ] }, "stateChanges": { "data": [], "transfers": [], "issues": [], "reissues": [], "burns": [], "sponsorFees": [], "invokes": [] } } ] }
Results of the
Lease
andLeaseCancel
script actions are added to the ThestateChanges
structure.Format
"stateChanges": { "leases": [ { "leaseId": "5fmWxmtrqiMp7pQjkCZG96KhctFHm9rJkMbq2QbveAHR", "recipient": "3PLosK1gb6GpN5vV7ZyiCdwRWizpy2H31KR", "amount": 500000 } ], "leaseCancels": [ { "leaseId": "4iWxWZK9VMZMh98MqrkE8SQLm6K9sgxZdL4STW8CZBbX" } ] }
Results of
Lease
andLeaseCancel
script actions are also added to thetrace
structure returned by the following endpoints:/transactions/broadcast
/debug/validate
Format
"trace": [ { "id": "3MosFNQAFGskNDnYzRBgMbfod6xXPdG96ME", "type": "dApp", "vars": [ { "name": "amount", "type": "integer", "value": 12345 } ], "result": { "leases": [ { "leaseId": "5fmWxmtrqiMp7pQjkCZG96KhctFHm9rJkMbq2QbveAHR", "recipient": "3PLosK1gb6GpN5vV7ZyiCdwRWizpy2H31KR", "amount": 500000 } ], "leaseCancels": [ { "leaseId": "4iWxWZK9VMZMh98MqrkE8SQLm6K9sgxZdL4STW8CZBbX" } ] } } ]
# Activation
To activate the improvements listed above, vote for feature #16 “Ride V5, dApp-to-dApp invocations, Continuations”.
# Version 1.2
# Protocol Enhancements
- Improved the mechanism for generating blocks using VRF (opens new window) (Verifiable random function). This improvement allows withstanding stake grinding attacks, which are used by the attackers to try to increase the probability of generating a block for themselves.
- Implemented saving failed transactions. Invoke script transactions and exchange transactions are saved on the blockchain and a fee is charged for them even if the dApp script or the asset script failed, provided that the sender's signature or account script verification passed and the complexity of computations performed during script invocation exceeded the threshold for saving failed transactions. More details
- Implemented the feature of changing the asset name and description. For this means, the update asset info transaction is used. Change is possible after 10 or more blocks on Stagenet and after 100,000 or more blocks on Mainnet and Testnet.
- Implemented the feature of deletion of entries from the account data storage. This action can be performed by the data transaction or DeleteEntry structure of the Ride language.
- Reduced the minimum fee from 1 to 0.001 WAVES for the reissue transaction and sponsor fee transaction.
- Implemented transaction binary formats based on protobuf (opens new window).
- Issue transaction's
name
anddescription
fields type changed from bytes to string. - The maximum data size in data transaction increased to 165,890 bytes.
- Exchange transaction may contain buy and sell orders in any order.
- Changed the orders' price calculation formula. Earlier, when determining the price for assets with different numbers of decimal places, there was a price value size issue. The maximum value depended on the difference of decimal digits of assets. For example, the price for an NFT asset could not exceed 1000 WAVES. The modified formula corrects this problem. Decimal places no longer affect the maximum price.
- The minimum interval between blocks is increased from 5 to 15 seconds. Average block time is targeted 60 seconds instead of ~59 seconds.
- Changed the scheme for signing the block transactions by the generating node. Previously, the generating node needed to sign the block header along with all transactions. For now, the transactions root hash is added to the header, so it is enough to sign only the header.
- The BLAKE2b-256 hash of the block header is used as the block unique identifier.
- When a transaction is validated before adding to the UTX pool, the blockchain state changes made by the transactions that were previously added to the block but then returned to the UTX pool due to the appearance of a new key block that refers to one of the previous microblocks, are taken into account.
- dApp can't call itself with InvokeScript transaction with attached payments. Also dApp can't transfer funds to itself by
ScriptTransfer
script action.
# REST API Updates
In the Node 1.2 release, we have some semantic and breaking changes in the API. Please read the following changes very attentively as it can affect your working application when migrating from Node 1.1 API to the Node 1.2 API.
# Semantic Changes
Invoke script transactions and exchange transaction can be failed, so their presence on the blockchain does not mean they are successful. Check the new field
applicationStatus
which is added to the output of the following endpoints:/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
values:succeeded
— the transaction is successfulscript_execution_failed
— the dApp script or the asset script failed.
For failed invoke script transactions, the reason of failure is indicated in the
error
structure in the following endpoints:/debug/stateChanges/address/{address}/limit/{limit}
/debug/stateChanges/info/{id}
Format:
"stateChanges": { "error": { "code": number, "text": string } }
Error codes are as follows:
1: dApp script error
2: insufficient fee for script actions
3: asset script in dApp script actions denied the transaction
4: asset script in attached payments denied the transaction
For invoke script transactions, the results of new script actions are represented in the
stateChanges
structure in the following endpoints:/debug/stateChanges/address/{address}/limit/{limit}
/debug/stateChanges/info/{id}
Format:
"stateChanges": { "data": [], "transfers": [], "issues": [], "reissues": [], "burns": [], "sponsorFees": [] }
For block version 5, the
reference
field corresponds toid
of the previous block instead ofsignature
for block version 4.
# Breaking Changes
Retrieve blocks by
id
instead ofsignature
.Deleted endpoints:
/blocks/signature/{signature}
— use/blocks/{id}
instead/blocks/child/{signature}
Affected endpoints:
/blocks/delay/{id}/{blockNum}
/blocks/height/{id}
/debug/rollback-to/{id}
Deleted the
/consensus/generationsignature
endpoint.Changed the
meta
structure format in the/addresses/scriptInfo/{address}/meta
endpoint. The argument list is represented as an object array, not the map.Before:
"meta": { "callableFuncTypes": { "funcName": { "arg1": string, "arg2": string } } }
Now:
"meta": { "callableFuncTypes": { "funcName": [ { "name": string, "type": string }, { "name": string, "type": string } ] } }
Added the new transaction type: Update Asset Info.
Invoke script transaction now can have arguments of
List
type.Example:
{ "call": { "function": string, "args": [ ["arg1-item1", "arg1-item2", "arg1-item3"] ] } }
Account data storage entries can be deleted by data transactions and invoke script transactions. Entry deletion is represented as follows:
{ "key": string, "value": null }
,value
is null, notype
field. Can be found in:/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}
Exchange transaction version 3 can include buy and sell orders in any order: buy/sell or sell/buy.
# Improvements
/debug/validate
endpoint does not require API-key./assets/details
endpoint can provide multiple assets info at once. TheoriginTransactionId
field containing the ID of the transaction that issued the asset is added to the response. Also, the endpoint supports POST requests./addresses/balance
endpoint can provide balances for several addresses for specific height not more than 2000 from current./assets/nft/{address}/limit/{limit}
endpoint returns theassetDetails
array containing the list of NFTs belonging to the address is added to the response. Also, the endpoint supports POST requests.Complexity of each annotated function is returned by the following endpoints:
/addresses/scriptInfo/{address}
/utils/script/compileCode
/utils/script/estimate
Format:
{ "complexity": number, "callableComplexities": { "funcName1": number, "funcName2": number }, "verifierComplexity": number }
Added the
/transactions/merkleProof
endpoint that accepts the transaction ID or the array of transactions IDs and returns the array of proofs for checking that the transaction is in a block.Added the
id
andtransactionsRoot
fields to the following endpoints:/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 Improvements
- Issued version 4 of the Ride Standard library.
- Added script actions that the callable function of dApp can perform:
- Issue
- Reissue
- Burn
- SponsorFee
- BooleanEntry, BinaryEntry, IntegerEntry, StringEntry that add or update the account data storage entries of the corresponding type. These actions replace DataEntry that is not supported in version 4.
- DeleteEntry that deletes the account data storage entry.
- The callable function result format is modified. Since version 4 the result is the list of script actions. The
ScriptResult
,WriteSet
andTransferSet
structures are not supported. - Invoke script transaction's fee increased by 1 WAVES for each non-NFT asset issued by the transaction's Issue structure.
- Enabled processing up to two payments attached to the invoke script transaction.
- Added support of list of primitives as a callable function argument.
- Added the following built-in functions:
- bn256groth16Verify range of functions that verify the zero-knowledge proof zk-SNARK (opens new window) by groth16 protocol on the bn254 curve. Complexity is 800–1650 depending on the argument size limit.
- calculateAssetId that calculates ID of asset generated by the Issue structure when executing a dApp script. Complexity is 10.
- contains that checks whether the second argument (substring) is contained in the first string argument. Complexity is 3.
- containsElement that check if the element is in the list. Complexity is 5.
- createMerkleRoot that calculates transactions root hash. Complexity is 30.
- ecrecover that recovers public key from the message hash and the ECDSA (opens new window) digital signature. Complexity is 70.
- makeString that concatenates list strings adding a separator. Complexity is 10.
- groth16Verify range of functions that verify the zero-knowledge proof zk-SNARK (opens new window) by groth16 protocol on the bls12-381 curve. Complexity is 1200–2700 depending on the argument size limit.
- indexOf that returns the index of the first occurrence of the element in the list. Complexity is 5.
- lastIndexOf that returns the index of the last occurrence of the element in the list. Complexity is 5.
- max that returns the largest element in the list. Complexity is 3.
- median that calculates a median of the list of integers. Complexity is 20.
- min that returns the smallest element in the list. Complexity is 3.
- removeByIndex that removes an element from the list by index. Complexity is 7.
- transferTransactionFromProto that deserializes a transfer transaction. Complexity is 5.
- valueOrElse(t: T|Unit, t0 : T) that returns a value from the union type if it's not unit. Complexity is 2.
- The wavesBalance built-in function returns the BalanceDetails structure that contains all types of WAVES balances.
- Added
name
anddescription
fields to the Asset structure which is returned by the assetInfo built-in function. - For the built-in hashing functions
blakeb256
,keccak256
,sha256
and the built-in verification functionsrsaVerify
,sigVerify
the complexity is changed in version 4 along with adding the range of similar functions with different complexity depending on the argument size limit. When data size is known in advance, the “cheaper” function can be used. - Changed the complexity of certain built-in functions and operators. Changes are listed in the Built-in Functions article.
- The following features are no longer supported in version 4:
- extract — use value instead;
- checkMerkleProof — use createMerkleRoot instead.
- Added the following list operators:
- ++ for the concatenation of lists. Example: the result of
[1, 2] ++ [3, 4]
is[1, 2, 3, 4]
. Complexity is 4. :+
for adding an element to the end of the list. Example: the result of["foo","bar"] :+ "baz"
is["foo", "bar", "baz"]
. Complexity is 1.
- ++ for the concatenation of lists. Example: the result of
- Added the Tuple data type.
- The maximum complexity of an account script and verifier function of dApp script is changed to 2000 for new scripts, regardless of the Standard library version. The maximum complexity of an asset script and callable function of dApp script remains 4000.
- The maximum data size is changed:
- String: 32,767 bytes
- ByteVector: 32,767 bytes (except the
bodyBytes
field of the transaction structure)
# Waves Explorer
- Failed transactions are now displayed. They are marked with
icon in lists of transactions.
- Added support of two payments for invoke script transactions. The dApp script result is displayed as a table.
- Added display of the new transaction type: update asset info transaction.
- Added the link to the issue transaction on the asset information page.
- Added Block ID field to the block information page.