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.
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.
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