Compiling a Contract

In this section, we will compile the rust written contract into a wasm binary executable. Before heading on to it, please ensure that the dev environment is setup and it's either configured with Node.js REPL or the wasmd Go CLI before you proceed.

In this example, we will be utilizing example smart contract code from InterWasm DAO. InterWasm DAO is the organization for CosmWasm ecosystem development.

Compiling and Testing the Contract Code

Let's clone the repository in which we keep cw-contracts and compile the existing code for a simple nameservice contract that mimics a name service marketplace.

First, clone the repo and try to build the wasm bundle:

# Download the repository
git clone <https://github.com/InterWasm/cw-contracts>
cd cw-contracts
git checkout main
cd contracts/nameservice

# compile the wasm contract with stable toolchain
rustup default stable
cargo wasm

The compilation should output the file as target/wasm32-unknown-unknown/release/cw_nameservice.wasm. With a quick ls -lh you can see that the file size is around 1.8 MB. This is a release build but still contains some unused code. To create a much smaller version, you can run the following command which tells the compiler to strip the unused parts of the code out:

RUSTFLAGS='-C link-arg=-s' cargo wasm

This generates a file approximately 165kB in size. We can either use the command above or apply a different Rust optimizer—details of which will be covered in the optimized compilation section below—to produce the smallest possible wasm binary before uploading it to the blockchain.

Unit Tests

Let's try running the unit tests:

RUST_BACKTRACE=1 cargo unit-test

After some compilation steps, you should see:

running 15 tests
test tests::tests::proper_init_no_fees ... ok
test tests::tests::fails_on_register_insufficient_fees ... ok
test coin_helpers::test::assert_sent_sufficient_coin_works ... ok
test tests::tests::fails_on_register_wrong_fee_denom ... ok
test tests::tests::fails_on_register_already_taken_name ... ok
test tests::tests::fails_on_transfer_from_nonowner ... ok
test tests::tests::fails_on_transfer_insufficient_fees ... ok
test tests::tests::fails_on_transfer_non_existent ... ok
test tests::tests::proper_init_with_fees ... ok
test tests::tests::register_available_name_and_query_works ... ok
test tests::tests::register_available_name_fails_with_invalid_name ... ok
test tests::tests::returns_empty_on_query_unregistered_name ... ok
test tests::tests::register_available_name_and_query_works_with_fees ... ok
test tests::tests::transfer_works ... ok
test tests::tests::transfer_works_with_fees ... ok

test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out;

RUST_BACKTRACE=1 will provide you with full stack traces on any error, which is super useful. This only works for unit tests (which test native rust code, not the compiled wasm). Additionally, if you're curious about where cargo wasm and cargo unit-test come from, they are just aliases defined in the file .cargo/config located in the project directory. Review the contents of this file to better understand the cargo flags used.

Optimized Compilation

To minimize gas fee, it's important to keep the binary size as small as possible. This leads to reduced deployment costs and lower fees for each interaction. Fortunately, tools are available to assist with this. By using the rust-optimizer, you can optimize production code effectively. rust-optimizer generates reproducible builds of CosmWasm smart contracts, ensuring that third parties can verify the contract matches the claimed code.

You will need Docker installed in order to run rust-optimizer.

Navigate to the project root and run the following command:

docker run --rm -v "$(pwd)":/code \\
  --mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \\
  --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \\
  cosmwasm/optimizer:0.16.0

On Windows, you can use the following command instead.

docker run --rm -v ${pwd}:/code `
  --mount type=volume,source="$("$(Split-Path -Path $pwd -Leaf)")_cache",target=/target `
  --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry `
  cosmwasm/optimizer:0.16.0

The binary will be under the folder artifacts and its size will be 138 kB.

Last updated