Rust interactor snippet generator
Each contract has a meta crate, which is able to perform various tasks based on the contents of the contract.
Its primary role is coordinating the contract builds, but it can do anything that requires contract metadata, including code generation. In this very case, we are generating Rust boilerplate code for a contract interactor. The interactor functionality was developed in the previous release.
An interactor program is a small tool that can send transactions to the contract on the blockchain. It is great for Rust developers seeking an alternative to mxpy/bash or mx-sdk-js. Some example code:
The idea is that the interactor framework allows us to call a contract like in remote procedure call, using the actual contract endpoints. In the above example, the add method belongs to the contract.
It utilizes much of the Mandos v2 Rust infrastructure. Apart from working with the auto-generated contract proxies, it benefits from its equivalent encoding mechanism, by which the contract proxy accepts as arguments variables of types that are different from the contract types, but have equivalent encoding. An example of this might be using an u32 variable instead of a BigUint, since they are both numbers and have the same top-encoding (for more about encoding see MultiversX serialization format).
Now, even with this kind of syntax sugaring, there is still some boilerplate code to write for each contract. This is why we have decided to additionally provide an interactor boilerplate code generator. Calling cargo run snippets in the meta crate of the contract produces a starter interactor crate, called interact-rs, which contains methods for calling each of the public endpoints with some dummy arguments. The generated code looks like this (an excerpt):
PlaceholderOutput types, they should be replaced by the developer with actual types for them to use, either the ones from the contract or equivalent ones.
Added some missing substitution rules in the contract preprocessor
Before building the contracts, a preprocessor is in charge of de-sugaring the managed type expressions. For instance, instead of writing
BigUint<Self::Api> in full, the developers only writes BigUint, and the preprocessor converts it to
Some of the managed types were missing from the preprocessor, they were all added.
Allow single zero byte when top-decoding
The Option type is encoded as follows:
- None is encoded as empty bytes
- Some(value) is encoded as
0x01followed by the nested-encoded value.
Previously decoding None was only accepting an empty input. Now,
0x00 is also accepted.
Ongoing operations module
The module abstracts away the management of an expensive process that needs to be interrupted when it runs out of gas, so that it can be continued later.
Have a look at the provided example in the Rust docs:
Claim developer rewards module
The module provides contracts functionality to claim developer rewards from other contracts that they own.
FromIterator trait for
Implementation from the community.
With this, developers can use the more ergonomic collect fn instead of manually doing a for_each or for loop over the filtered/mapped iterator.
let mut collected_vec: ManagedVec<i32> = ManagedVec::new();
managed_vec.iter().filter(|x| x <= &5).for_each(|el| collected_vec.push(el));
let collected_vec = managed_vec.iter().filter(|x| x <= &5).collect::<ManagedVec<i32>>();
"id" accepted as synonym to
Transaction ids in Mandos were given under
“id” is now also accepted, in both mandos-go and mandos-rs.
Don’t forget to send us feedback. Full changelog can be found here.
Stay Hungry! Stay Foolish!