Waves 1.3 Stagenet Release
Following 4.5 months of development, the Waves protocol’s version 1.3 is now available on the stagenet.
The update contains unique functionality for operating decentralized apps, which you won’t find in any other protocol.
Detailed information on all the improvements is available on the release page here.
One of the protocol improvements is continuations, a concept originally described by Ilya Smagin in late 2019.
Thanks to continuations, you can write scripts with a maximum complexity exceeding 4,000 (which is a limit for scripts on the mainnet now).
Previously, for complex computations, an app’s logic had to be split into several methods and invoke them, one by one, in separate transactions. Thanks to continuations, execution of a script with a complexity exceeding 4,000 is split into several stages: the first stage is executed within an invoke script transaction, and the remaining ones are generated without the user’s involvement in continuation transactions.
Calling a dApp from another one
A dApp script’s callable function can execute attached calls. From a dApp, another or the same dApp’s
@Callable function can be invoked. The callable function can also invoke itself. All invoked functions are executed within the same invoke script transaction. The complexity of executable scripts is limited.
Thanks to this improvement, two dApps can communicate not only through account storage but also directly by calling each other.
Changes for developers
To support the improvements described above, changes for developers were added to the protocol. Primarily, a new transaction type has been added, which is a continuation transaction. A continuation transaction is created by a block generator automatically, in case of an incomplete computation chain. A continuation transaction can’t be sent by a user.
Also, version 3 invoke script transaction has been added, enabling invocation of scripts with a complexity exceeding 4,000.
Changes to the Ride language
Version 5 of the standard library has been released, to which the Invoke function for calling a dApp from another one has been added. Calling one dApp from another one could look like this:
Eager variables called with the keyword
strict have been added. They are different from regular ‘lazy’ variables, called with the
let keyword, and are computed until the next expression, to guarantee the order of execution and application of callable functions’ scripts.
The format of a
@Callable function’s result has been changed: a returned value as the final part of a tuple has been added:
In version 1.2, new script actions were added, including
LeaseCancel, which a callable function could execute, were lacking. In the new version, those functions have been added, and, thanks to this, a smart contract can lease out WAVES or cancel leasing.
LeaseCancel, a leasing amount can be changed or part of the total leased amount can be withdrawn. If in one script invocation, the leasing of a larger amount is canceled and a smaller amount is leased out to the same recipient, the generating balance will decrease by one. However, if two separate transactions are sent — a lease cancel transaction and a lease transaction, — and they are added to different blocks, the generating balance will immediately decrease by the canceled leasing amount, and the new leasing amount will be added to it only after 1,000 blocks.
In other words, thanks to support for
LeaseCancel, partial leasing cancellation has been made possible.
For the convenience of leasing operations, the in-built function calculateLeaseId has been added to receive a leasing ID, formed by the Lease structure. The principle of using calculateLeaseId is identical to that of
In Ride’s new version, account data storage functions have been added, enabling a dApp script to read data from its own storage at any computation stage:
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
Another major improvement is the addition of another data type — Any. This is a supertype for all types: a value of any type can be a line, a number, a unit, a structure, a list, a tuple, etc.
Please, pay attention to changes in REST API, which break backward compatibility. A detailed description is available on the release page on Github.
How to test?
The new functionalities of calling a dApp from another one and, specifically, continuations have led to substantial changes in app development experience on Waves. You can already start testing your dApps on the stagenet.
If you have questions or issues, discuss them in the developer chat at https://t.me/waves_ride_dapps_dev
If you have ideas for improving the functionalities of continuations or calling one dApp from another one, welcome to the discussion forum for Waves Enhancement Proposals: