Allocator
The allocator example demonstrates how to utilize the allocator feature when writing a contract.
The soroban-sdk
crate provides a lightweight bump-pointer allocator which can be used to emulate heap memory allocation in a Wasm smart contract.
Run the Example
First go through the Setup process to get your development environment configured, then clone the v21.6.0
tag of soroban-examples
repository:
git clone -b v21.6.0 https://github.com/stellar/soroban-examples
Or, skip the development environment setup and open this example in Gitpod.
To run the tests for the example, navigate to the alloc
directory, and use cargo test
.
cd alloc
cargo test
You should see the output:
running 1 test
test test::test ... ok
Dependencies
This example depends on the alloc
feature in soroban-sdk
. To include it, add "alloc" to the "features" list of soroban-sdk
in the Cargo.toml
file:
[dependencies]
soroban-sdk = { version = "20.0.0", features = ["alloc"] }
[dev_dependencies]
soroban-sdk = { version = "20.0.0", features = ["testutils", "alloc"] }
Code
#![no_std]
use soroban_sdk::{contractimpl, Env};
extern crate alloc;
#[contract]
pub struct AllocContract;
#[contractimpl]
impl AllocContract {
/// Allocates a temporary vector holding values (0..count), then computes and returns their sum.
pub fn sum(_env: Env, count: u32) -> u32 {
let mut v1 = alloc::vec![];
(0..count).for_each(|i| v1.push(i));
let mut sum = 0;
for i in v1 {
sum += i;
}
sum
}
}
Ref: https://github.com/stellar/soroban-examples/tree/v21.6.0/alloc
How it Works
extern crate alloc;
Imports the alloc
crate, which is required in order to support allocation under no_std
. See Contract Rust dialect for more info about no_std
.
let mut v1 = alloc::vec![];
Creates a contiguous growable array v1
with contents allocated on the heap memory.
The heap memory in the context of a smart contract actually refers to the Wasm linear memory. The alloc
will use the global allocator provided by the soroban sdk to interact with the linear memory.
Using heap allocated array is typically slow and computationally expensive. Try to avoid it and instead use a fixed-sized array or soroban_sdk::vec!
whenever possible.
This is especially the case for a large-size array. Whenever the array size grows beyond the current linear memory size, which is multiple of the page size (64KB), the wasm32::memory_grow
is invoked to grow the linear memory by more pages as necessary, which is very computationally expensive.
The remaining code pushes values (0..count)
to v1
, then computes and returns their sum. This is the simplest example to illustrate how to use the allocator.