Wednesday, September 21, 2022
API
Protocol
WASM
Tooling

Release: elrond-wasm - v0.35.0

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:


impl State {
async fn add(&mut self) {
let value = 123u32;

let result: elrond_interact_snippets::InteractorResult = self
        .interactor
        .sc_call_get_result(self.contract
          .add(value)
          .into_blockchain_call()
          .from(&self.wallet_address)
          .gas_limit(DEFAULT_GAS_LIMIT)
          .into(),
)
.await;
let result_value = result.value();

    println!("Result: {:?}", result_value);
  }
}

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):


impl State {
async fn add(&mut self) {
let value = PlaceholderInput;

let result: elrond_interact_snippets::InteractorResult = self.interactor.sc_call_get_result(self.contract
                                        .add(value)
                                        .into_blockchain_call()
                                        .from(&self.wallet_address)
                                        .gas_limit(DEFAULT_GAS_LIMIT)
                                        .into(),)
                                      .await;
let result_value = result.value();

  println!("Result: {:?}", result_value);
  }
}

Notice the PlaceholderInput and 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 BigUint<Self::Api>.

Some of the managed types were missing from the preprocessor, they were all added.

Allow single zero byte when top-decoding Option::None

The Option type is encoded as follows:

  • None is encoded as empty bytes (0x);
  • Some(value) is encoded as 0x01 followed 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: OngoingOperationModule in elrond_wasm_modules.

Claim developer rewards module

The module provides contracts functionality to claim developer rewards from other contracts that they own.

FromIterator trait for ManagedVec

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.

  • Before:

let mut collected_vec: ManagedVec<i32> = ManagedVec::new();
managed_vec.iter().filter(|x| x <= &5).for_each(|el| collected_vec.push(el));

  • After:

let collected_vec = managed_vec.iter().filter(|x| x <= &5).collect::<ManagedVec<i32>>();

Mandos "id" accepted as synonym to "txId"


Transaction ids in Mandos were given under “txId”. Just “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!

Do you need more information?

Explore projects, tokens, and integrations built on MultiversX