This guide provides a step-by-step process to write and deploy a CW20 token contract on the MANTRA Chain using Rust and CosmWasm. CW20 contracts are similar to ERC20 contracts on Ethereum and are widely used for token creation and management on Cosmos-based blockchains.
In the previous sections, we have understood the dev environment setup, wallet setup and collect testnet OM tokens for the development purposes. Therefore, ensure your Keplr wallet is set up and contains OM testnet tokens for the deployment process.
Prerequisites
If you encounter any issues with your development environment setup or need to refresh your setup, follow these steps:
Install Rust
First, you need to install Rust, a programming language used for developing smart contracts. You can do this by running the following command in your terminal:
Download and extract the pre-built mantrachaind binary:
On Linux:
# Download the CLIcurl-LO<https://github.com/MANTRA-Finance/public/raw/main/mantrachain-testnet/mantrachaind-linux-amd64.zip># Unzip the CLIunzipmantrachaind-linux-amd64.zip
On MacOS:
# Download the CLI for Intel chipscurl -LO <https://github.com/MANTRA-Finance/public/raw/main/mantrachain-hongbai/mantrachaind-static-darwin-amd64.tar.gz>
# Download the CLI for Silicon chips (M1, M2...)curl -LO <https://github.com/MANTRA-Finance/public/raw/main/mantrachain-hongbai/mantrachaind-static-darwin-arm64.tar.gz>
# Extract the CLItar-xzvfmantrachaind-static-darwin-*.tar.gz
If you encounter a missing libwasmvm.x86_64.so error, download the library:
After cloning the repository, open the project in your preferred code editor, such as Visual Studio Code.
Step 2: Update Dependencies
Navigate to the Cargo.toml file in the root directory of your project. This file manages the dependencies for your Rust project. Add the following dependency to include the cw20-base package:
Cargo.toml
[dependencies]cw20-base = { version ="2.0.0", features = ["library"] }cw20 ="2.0.0"cw-utils ="2.0.0"cosmwasm-std ="2.1.3"cosmwasm-storage ="1.1.1"cw-storage-plus ="2.0.0"cw2 ="2.0.0"schemars ="0.8.21"serde = { version ="1.0.207", default-features =false, features = ["derive"] }thiserror = { version ="1.0.63" }cosmwasm-schema ="2.1.3"prost ="0.13.1"
This ensures that you have the necessary libraries to work with CW20 tokens, providing essential functionalities like token transfer, allowance, and minting.
Now that we have completed the setup , let's modify the boilerplate code and get our token ready .
We will be changing or creating the logic inside the following files :
scr/msg.rs
src/contract.rs
src/lib.rs
Step 3: Modify Contract Files
Update msg.rs
use cosmwasm_schema::cw_serde;#[cw_serde]pubenumMigrateMsg {}
Update contract.rs
In the contract.rs file, define the core contract logic. This includes handling instantiation, execution, and query messages:
These functions define the contract's entry points (instantiate,execute,query,migrate) and handle token operations such as transfers, burns, minting, allowances, and querying balances.It uses helper functions from the cw20-base package to handle common CW20 operations.
Error Handling Logic
The error handling on this contract happens at the cw20-base library level, so you don’t need to implement specific errors unless you want to.
Step 4: Build Artifacts and Wasm file
To build the artifact, we need to run the rust-optimizer with docker:
Once deployed, you will receive the wallet address and confirmation of contract instantiation. Verify your deployment on the MANTRA Chain Explorer athttp://explorer.hongbai.mantrachain.io.
Using typescript:
Create a new folder named “deployer” to manage the deployment scripts:
mkdir deployer
Navigate to the “deployer” folder and initialize it with npm:
cd deployer
npm init -y
npm i
This sets up a new Node.js project in the deployer folder.
Install TypeScript and initialize a TypeScript configuration file:
npm install typescript --save-dev
npx tsc --init
Install the necessary dependencies for the deployment script:
Now, manually copy the wasm file to the deployer folder, which was created under the artifacts file.
Now create an index.ts file in the deployer folder with the following code for deployment script.
const { DirectSecp256k1HdWallet } =require("@cosmjs/proto-signing");const {assertIsBroadcastTxSuccess,SigningCosmWasmClient,CosmWasmClient,} =require("@cosmjs/cosmwasm-stargate");const { coins,GasPrice } =require("@cosmjs/stargate");constfs=require("fs");require("dotenv").config();constmnemonic=process.env.MNEMONIC;// Replace with your mnemonicconstrpcEndpoint="<https://rpc.hongbai.mantrachain.io>";constcontractWasmPath="./first_token_cw20contract.wasm"; // Path to your compiled contract (wasm file)asyncfunctiondeploy() {// Step 1: Set up wallet and clientconstwallet=awaitDirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix:"mantra",// Replace with the correct prefix for your chain });const [account] =awaitwallet.getAccounts();console.log(`Wallet address: ${account.address}`);// Step 2: Connect to the blockchainconstclient=awaitSigningCosmWasmClient.connectWithSigner( rpcEndpoint, wallet, { gasPrice:GasPrice.fromString("0.0025uom") } );console.log("Connected to blockchain");// Step 3: Upload contractconstwasmCode=fs.readFileSync("./first_token_cw20contract.wasm"); // wasm fileconstuploadReceipt=awaitclient.upload(account.address, wasmCode,"auto","Upload CosmWasm contract" );constcodeId=uploadReceipt.codeId;console.log(`Contract uploaded with Code ID: ${codeId}`);// Step 4: Instantiate contractconstinitMsg= { name:"MANTRAcw20", symbol:"MNTRA", decimal:6, initial_balances: [ { address:" ",// add your wallet address amount:10000000, }, ], }; // Replace with your contract's init messageconstinstantiateReceipt=awaitclient.instantiate(account.address, codeId, initMsg,"My CW20 contract","auto" );constcontractAddress=instantiateReceipt.contractAddress;console.log(`Contract instantiated at reciept: ${instantiateReceipt}`);console.log(`Contract instantiated at address: ${contractAddress}`);}deploy().catch(console.error);
Remember to add your mnemonic and MANTRA Chain's RPC endpoint “https://rpc.hongbai.mantrachain.io” wherever mentioned. Additionally, include your wallet address in the initMsg structure. Modify contract.rs, index.ts, and msg.rs as per your contract requirements.
Compile TypeScript: Execute the following command to compile index.ts It will automatically create an index.js file upon successful compilation:
tsc index.ts
Deploy Contract: Run the final command to deploy your CW20 contract on the MANTRA Chain. Ensure your wallet contains sufficient OM test tokens:
npx ts-node index.ts
Once deployed, you will receive the wallet address and confirmation of contract instantiation. Verify your deployment on the MANTRA Chain Explorer at http://explorer.hongbai.mantrachain.io.