Using no_std#

At a glance

This guide shows how to enable no_std in your Concordium smart contract to reduce the size of the compiled Wasm module. You will need an existing Rust smart contract and the nightly Rust toolchain. After following this guide, your contract will compile without the Rust standard library, resulting in a smaller binary.

This guide shows how to enable no_std for your rust smart contract, potentially reducing the size of the resulting Wasm module by several kilobytes.

Preparation#

Compiling concordium-std without the std feature requires using the rust nightly toolchain, which can be installed using rustup:

$rustup toolchain install nightly

Then add the wasm32 target by using

$rustup +nightly target add wasm32-unknown-unknown

Setting up the module for no_std#

The concordium-std library exposes a std feature, which enables the use of the rust standard library. This feature is enabled by default.

To disable it, one must simply disable default features for the concordium-std in the dependencies of your module. You can update your Cargo.toml file by using:

[dependencies]
concordium-std = { version = "10.0", default-features = false }

Note

To compile your smart contracts, a memory allocator is used. concordium-std version <6.0.0 hard-coded the use of the wee_alloc allocator. In concordium-std version in the range of >=6.0.0 and <10.0.0, wee_alloc is a feature and needs to be explicitly enabled. In concordium-std version >=10.0.0, bump_alloc is a feature and needs to be explicitly enabled. When std feature is enabled, the allocator provided by the Rust standard library is used by default but when the wee_alloc/bump_alloc feature is enabled in addition, bump_alloc ( or wee_alloc) is used instead. Read Use a custom allocator for more information on custom allocators.

You can enable the std feature and the wee_alloc feature in concordium-std version in the range of >=6.0.0 and <10.0.0 by using:

[dependencies]
concordium-std = {version = "6.0", features = ["wee_alloc"]}

You can enable the std feature and the bump_alloc feature in concordium-std version >=10.0.0 by using:

[dependencies]
concordium-std = {version = "10.0", features = ["bump_alloc"]}

Alternatively, if you want to test with and without wee_alloc/bump_alloc enabled add a wee_alloc/bump_alloc feature to the smart contract crate as follows:

[features]
default = ["std", "bump_alloc"]
std = ["concordium-std/std"]
bump_alloc = ["concordium-std/bump_alloc"]

The above code blocks will use the bump_alloc allocator and not the allocator provided by the Rust standard library when compiled with the default features as follows:

$cargo concordium build

When no_std is used either wee_alloc/bump_alloc must be enabled, or another global allocator must be set in the smart contract. You can add the wee_alloc/bump_alloc feature by using e.g.:

[features]
bump_alloc = ["concordium-std/bump_alloc"]

To be able to toggle between with and without std, also add a std to your own module, which enables the std feature of concordium-std:

[features]
std = ["concordium-std/std"]

This is the setup of the smart contract examples, where std for each smart contract module is enabled by default.

Building the module#

In order to use the nightly toolchain, add +nightly right after cargo:

$cargo +nightly concordium build

If you want to disable the default features of your own smart contract module, you can pass extra arguments for cargo:

$cargo +nightly concordium build -- --no-default-features --features bump_alloc

Note

The above command works with concordium-std version >=10.0.0, because the bump_alloc feature needs to be explicitly enabled.

If you use concordium-std version in the range of >=6.0.0 and <10.0.0 use the following instead:

$cargo +nightly concordium build -- --no-default-features --features wee_alloc

If you use concordium-std version <6.0.0 use the following instead:

$cargo +nightly concordium build -- --no-default-features
Was this article helpful?