Instantiating a CosmWasm Contract: A Step-by-Step Guide

945G...fRid
9 Jun 2024
50

In this guide, we will walk through the process of instantiating a CosmWasm smart contract. We'll cover the InstantiateMsg structure passed during contract creation and the instantiate function executed upon contract deployment.

What is InstantiateMsg?

InstantiateMsg is the initialization message used when a contract is instantiated. It includes variables provided during the contract creation. Here is a simple example of what InstantiateMsg looks like:

rust

复制代码
/// Variables for contract instantiation. /// Exclude variables susceptible to replay attacks or secret data. pub struct InstantiateMsg { pub sent_message: String, } 

This structure is defined in msg.rs. It's important to ensure that no sensitive data prone to replay attacks is included in this message.

The Instantiate Function

The instantiate function is executed when the contract is created. It sets the initial state of the smart contract, performs necessary checks, and can act similarly to an execute message. Below is an example of how this function is defined in contract.rs:

rust

复制代码
pub fn instantiate( deps: DepsMut, _env: Env, _info: MessageInfo, msg: InstantiateMsg, ) -> Result<Response, ContractError> { // Initialize contract's state.let state = State { global_var: msg.sent_message, }; // Save state to the blockchain. STATE.save(deps.storage, &state)?; Ok(Response::new().add_attribute("instantiated", "true")) } 

This function initializes the contract's state with the provided sent_message and saves this state to the blockchain.

Example: Setting Up the Contract Files

To instantiate a CosmWasm contract, you need to set up several files. Here is an example layout of the files and their content:

  • lib.rs
rust

复制代码
pub mod contract; mod error; pub mod helpers; pub mod msg; pub mod state; pub use crate::error::ContractError; 
  • contract.rs
rust

复制代码
#[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, to_binary}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{State, STATE}; #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( deps: DepsMut, _env: Env, _info: MessageInfo, msg: InstantiateMsg, ) -> Result<Response, ContractError> { let state = State { global_var: msg.sent_message, }; STATE.save(deps.storage, &state)?; Ok(Response::new().add_attribute("instantiated", "true")) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute( _deps: DepsMut, _env: Env, _info: MessageInfo, _msg: ExecuteMsg, ) -> Result<Response, ContractError> { unimplemented!() } #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> { match msg { QueryMsg::GetMessage {} => to_binary(&query::message(deps)?), } } pub mod query { use crate::msg::GetMessageResponse; use super::*; pub fn message(deps: Deps) -> StdResult<GetMessageResponse> { let state = STATE.load(deps.storage)?; Ok(GetMessageResponse { message: state.global_var }) } } #[cfg(test)] mod tests { use cosmwasm_std::{testing::{mock_dependencies, mock_env, mock_info}, Addr, from_binary}; use crate::msg::GetMessageResponse; use super::*; #[test]fn instantiate_test() { let mut deps = mock_dependencies(); let env = mock_env(); let msg = InstantiateMsg { sent_message: "Hey!".to_string()}; let info = mock_info("creator", &[]); instantiate(deps.as_mut(), env.clone(), info, msg).unwrap(); let res = query(deps.as_ref(), env, QueryMsg::GetMessage {}).unwrap(); let message: GetMessageResponse = from_binary(&res).unwrap(); assert_eq!("Hey!".to_string(), message.message); } } 
  • msg.rs
rust

复制代码
use cosmwasm_schema::{cw_serde, QueryResponses}; #[cw_serde] pub struct InstantiateMsg { pub sent_message: String, } #[cw_serde] pub enum ExecuteMsg {} #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { #[returns(GetMessageResponse)] GetMessage {}, } #[cw_serde] pub struct GetMessageResponse { pub message: String, } 
  • error.rs
rust

复制代码
use cosmwasm_std::StdError; use thiserror::Error; #[derive(Error, Debug)] pub enum ContractError { #[error("{0}")]Std(#[from] StdError), #[error("Unauthorized")] Unauthorized {}, } 
  • state.rs
rust

复制代码
use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use cw_storage_plus::Item; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct State { pub global_var: String, } pub const STATE: Item<State> = Item::new("state"); 
  • helpers.rs
rust

复制代码
use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg}; use crate::msg::ExecuteMsg; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct CwTemplateContract(pub Addr); impl CwTemplateContract { pub fn addr(&self) -> Addr { self.0.clone() } pub fn call<T: Into<ExecuteMsg>>(&self, msg: T) -> StdResult<CosmosMsg> { let msg = to_binary(&msg.into())?; Ok(WasmMsg::Execute { contract_addr: self.addr().into(), msg, funds: vec![], } .into()) } } 

By following these steps and organizing your files as shown, you can successfully instantiate and deploy a CosmWasm smart contract. This setup forms the foundation for more complex contract development and deployment on the blockchain.

Write & Read to Earn with BULB

Learn More

Enjoy this blog? Subscribe to 666

0 Comments

B
No comments yet.
Most relevant comments are displayed, so some may have been filtered out.