Deploy a WASM contract
Overview
The x/wasm
Warden module allows executing WebAssembly smart contracts developed with CosmWasm and Rust.
This guide explains how to create and deploy a simple "Hello World" WASM contract on the Warden chain. Since it's intended for testing purposes, you'll be running a local chain.
Prerequisites
Before you start, complete the following prerequisites:
-
Install Rust by running the following:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
-
Set up the CosmWasm development environment:
-
CosmWasm: The CosmWasm binary and its dependencies.
-
cargo-generate: A tool to help you get up and running quickly with a new Rust project by leveraging a pre-existing git repository as a template.
-
wasm-opt: A tool for optimizing the compiled WebAssembly (Wasm) code.
To install these tools, run the following commands:
rustup target add wasm32-unknown-unknown
cargo install cargo-generate --features vendored-openssl
brew install binaryen -
-
Run a local chain and make sure you have
wardend
correctly installed.The next steps require your local account name, or key name, which is referenced as
my-key-name
in the provided command-line examples. You can check the list of available keys by executing this command:wardend keys list
tipIf you used a
just
script or a devnet snapshot to run your node, the local account name isshulgin
.
1. Create a CosmWasm project
Create a new CosmWasm project by running the following:
cargo generate --git https://github.com/CosmWasm/cw-template.git --name hello-world
cd hello-world
2. Modify the contract code
-
Open
src/contract.rs
and replace its contents with this code:use cosmwasm_std::{
entry_point, to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult,
};
use cw2::set_contract_version;
use crate::error::ContractError;
use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
const CONTRACT_NAME: &str = "crates.io:hello-world";
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
#[entry_point]
pub fn instantiate(
deps: DepsMut,
_env: Env,
info: MessageInfo,
_msg: InstantiateMsg,
) -> Result<Response, ContractError> {
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
Ok(Response::new().add_attribute("method", "instantiate")
.add_attribute("owner", info.sender))
}
#[entry_point]
pub fn execute(
_deps: DepsMut,
_env: Env,
info: MessageInfo,
msg: ExecuteMsg,
) -> Result<Response, ContractError> {
match msg {
ExecuteMsg::SayHello {} => Ok(Response::new()
.add_attribute("method", "say_hello")
.add_attribute("sender", info.sender)),
}
}
#[entry_point]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::GetGreeting {} => to_binary(&"Hello, World!"),
}
} -
Open
src/msg.rs
and replace its contents with this code:use cosmwasm_schema::{cw_serde, QueryResponses};
#[cw_serde]
pub struct InstantiateMsg {}
#[cw_serde]
pub enum ExecuteMsg {
SayHello {},
}
#[cw_serde]
#[derive(QueryResponses)]
pub enum QueryMsg {
#[returns(String)]
GetGreeting {},
}
3. Compile the contract
To compile the contract, run the following:
cargo wasm
The contract should be compiled without any errors.
4. Optimize the code
Now you need to optimize your compiled Wasm code:
wasm-opt -Os -o target/wasm32-unknown-unknown/release/hello_world.wasm /
target/wasm32-unknown-unknown/release/hello_world.wasm
5. Run the chain
If your local chain isn't running, start it:
wardend start
6. Store the contract on-chain
To store your contract on the Warden chain, run the command below. Replace my-key-name
with your key name from Prerequisites (typically shulgin
).
wardend tx wasm store target/wasm32-unknown-unknown/release/hello_world.wasm /
--from my-key-name --gas auto --gas-adjustment 1.3 --gas-prices 100000000000award -y
The transaction should be successful without any errors.
7. Get the code ID
Get the code ID that indentifies your Wasm code:
wardend query wasm list-code
Note down code_id
from the output.
8. Instantiate the contract
You can instantiate the contract by using the command below.
Before you proceed, replace 1
with the actual code ID you retrieved in previous step and replace my-key-name
with your key name. Also note that you can either define an admin or pass --no-admin
to make it immutable, like in this example.
wardend tx wasm instantiate 1 '{}' /
--from my-key-name --label "Hello World" /
--gas auto --gas-adjustment 1.3 --gas-prices 100000000000award /
--no-admin -y
9. Get the contract address
To get the contract address, run the following command. Replace 1
with the actual code ID:
wardend query wasm list-contract-by-code 1
Note down the contract address.
10. Execute the contract
Use the command below to exectute your contract. Replace my-contract-address
with your contract address and my-key-name
with your key name.
wardend tx wasm execute my-contract-address '{"say_hello":{}}' /
--from my-key-name --gas auto --gas-adjustment 1.3 --gas-prices 100000000000award -y
11. Query the contract
You can query your contract with the following command. Replace my-contract-address
with your contract address.
wardend query wasm contract-state smart my-contract-address '{"get_greeting":{}}'
In the output, you should see this: data: Hello, World!
If you encounter any issues, please reach out to us in Discord or Twitter.
Happy coding! 🚀