Skip to main content

Deploy-a-Smart-Contract

Deploy a Smart Contract

Clone cw-template

For this example, we will use the cw-template repository with the counter example.

cargo generate --git https://github.com/CosmWasm/cw-template.git --name my-first-contract

🔧   Destination: /home/alp/my-first-contract ...
🔧 project-name: my-first-contract ...
🔧 Generating template ...
? 🤷 The full template includes some example logic in case you're new to CosmWasm smart contracts.
✔ 🤷 The full template includes some example logic in case you're new to CosmWasm smart contracts.
The minimal template assumes you already know how to write your own logic, and doesn't get in your way.

select false

cd my-first-contract

Compile the wasm contract with stable toolchain

To deploy smart contracts, you must compile the code and make it an executable wasm binary file. We will compile the wasm contract with stable toolchain.

# Set 'stable' as the default release channel:
rustup default stable
cargo wasm

After this compiles, it should produce a file in target/wasm32-unknown-unknown/release/my_first_contract.wasm. If you check the size of the file by using the ls -lh command, it shows around 1.9M. This is a release build, but not stripped of all unneeded code. To produce a much smaller version, you can run this which tells the compiler to strip all unused code out:

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

This produces a file about 155K. To reduce gas costs, the binary size should be as small as possible. This will result in a less costly deployment, and lower fees on every interaction. Also, if you don’t use compilation optimization, CosmWasm smart contract will not be deployed well due to exceeds limit error.

The binary file which is created by cargo wasm is not deployable. Because cargo wasm doesn't actually generate a binary that's deployable. To creating a deployable binary file we would use rust-optimizer which is the industry standard for building your smart contracts for deployment.

CosmWasm Optimizing Compiler

rust-optimizer Is a Docker build with a locked set of dependencies to produce reproducible builds of cosmwasm smart contracts. It also does heavy optimization on the build size. You must set the local path to the smart contract you wish to compile and it will produce an artifacts directory with <contract_name>.wasm and contracts.txt containing the hashes. This is just one file.

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

Binary file will be at artifacts/my_first_contract.wasm folder and its size will be about 130K, which is more smaller than when only RUTFLAGS was used.

Verifying CosmWasm smart contracts

cosmwasm-check Is a CLI tool for verifying CosmWasm smart contracts. Used to verify a Wasm binary is a CosmWasm smart contract suitable for uploading to a blockchain with a given set of capabilities.After creating a binary file of smart contract, you can check and verify the binary of a smart contract by using this tool.

Installation

cargo install cosmwasm-check

Check some contracts:

cosmwasm-check artifacts/my_first_contract.wasm

After having a valid smart contract binary, it can be stored successfully in the chain.

Store the binary in Soarchain

We have the wasm binary executable ready. Now it is time to store the code to the Soarchain.

RES=$(soarchaind tx wasm store artifacts/my_first_contract.wasm --from mywallet --gas-prices 0.025umotus --chain-id soarchaintestnet --gas auto --gas-adjustment 1.5 -y --output json -b block)

If you require additional clarification regarding any of the command flags,

Check them
  • soarchaind tx wasm store : upload a wasm binary
  • --from : name or address of private key with which to sign the tx.
  • --gas-prices : gas prices in decimal format to determine the transaction fee.
  • --gas : gas limit to set per-transaction. set to “auto” to calculate sufficient gas automatically
  • the chain-id is whatever chain-id you are working with (in the soarchain testnet case it is soarchaintestnet)
  • --gas-adjustment : adjustment factor to be multiplied against the estimate returned by the tx simulation.
  • -y : to skip tx broadcasting prompt confirmation.
  • --output : output format.
  • -b : transaction broadcasting mode

Once that is complete, you can get the CODE_ID easily using jq.

jq is an open source that helps extract data from JSON. Install it according to your OS(linux in the example) using the following command:

sudo apt-get install jq

Run the following command to set the CODE_ID as a variable:

# get CODE_ID
CODE_ID=$(echo $RES | jq -r '.logs[0].events[-1].attributes[0].value')
echo $CODE_ID

Instantiate the contract

We can now create an instance of this wasm contract. First, set the initial state of the instance in the INIT variable and run the instantiate command

# set the initial state of the instance
INIT='{"count":100}'

# instantiate the contract
soarchaind tx wasm instantiate $CODE_ID "$INIT" \
--label "my first contract" --gas-prices 0.025umotus --gas auto --gas-adjustment 1.5 -b block -y --no-admin --chain-id soarchaintestnet --from mywallet

If you require additional clarification regarding any of the command flags,

Check them
  • soarchaind tx wasm instantiate : instantiate a wasm contract using CODE_ID of the uploaded binary.
  • --label : human-readable name for this contract in lists.
  • --no-admin : you must set this explicitly if you don’t want an admin.

Get the contract address using the command following:

CONTRACT_ADDR=$(soarchaind query wasm list-contract-by-code $CODE_ID --output json | jq -r '.contracts[0]')
echo $CONTRACT_ADDR

Query the contract

Now, let’s see if the contract we deployed works well.

Get contract's count

Send a get_count query to check the count value. The previously set INIT state is output as it is : {"data":{"count":100}}

QUERY='{"get_count":{}}'
soarchaind query wasm contract-state smart $CONTRACT_ADshDR "$QUERY" --output json

soarchaind query wasm contract-state smart : calls contract with given address with query data and prints the returned result

The output will be:

{"data":{"count":100}}

Execute the Contract

Increment contract’s count

Send an increment transaction this time, one that raises the count value by +1. You must pay gas fees since the transaction alters the internal condition of the contract.

After sending the increment transaction, you can observe that +1 has grown from the previous count value by running the get_count query once more.

TRY_INCREMENT='{"increment": {}}'
soarchaind tx wasm execute $CONTRACT_ADDR "$TRY_INCREMENT" --gas-prices 0.025umotus --gas auto --gas-adjustment 1.5 -y --chain-id soarchaintestnet --from mywallet

Reset contract’s count

Let's submit a reset transaction lastly. You must pay gas fees because reset transactions, like increments, also alter the internal state of contracts.

RESET='{"reset": {"count": 0}}'
soarchaind tx wasm execute $CONTRACT_ADDR "$RESET" --gas-prices 0.025umotus --gas auto --gas-adjustment 1.5 -y --chain-id soarchaintestnet --from mywallet