Crear una instancia de un contrato CosmWasm

Esta sección describe el proceso de creación de instancias de un contrato inteligente, mostrando la estructura InstantiateMsg pasada durante la creación del contrato y la función Instantiate que se ejecuta tras la ejecución del contrato.

Explicación

InstanciarMsg

InstantiateMsg es el mensaje de inicialización y trata con el variables proporcionadas cuando se crea una instancia del contrato.

Esta función se puede encontrar en msg.rs.

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

Info

Asegúrese de que no se incorporen datos confidenciales propensos a ataques de repetición.

Crear una instancia

Al crear el contrato, la función de creación de instancias establece el estado inicial del contrato inteligente, realiza las comprobaciones necesarias y puede funcionar de forma similar a un mensaje de ejecución.

Esta función se puede encontrar en contract.rs

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"))
}

Ejemplo

Para crear instancias de contratos con CosmWasm, puede crear los siguientes archivos: lib.rs contract.rs msg.rs error.rs state.rs helpers.rs

lib.rs

pub mod contract;
mod error;
pub mod helpers;
pub mod msg;
pub mod state;
pub use crate::error::ContractError;

contract.rs

#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, to_binary};
// use cw2::set_contract_version;
use crate::error::ContractError;
use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
use crate::state::{State, STATE};
/*
// version info for migration info
const CONTRACT_NAME: &str = "crates.io:instantiation";
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
*/
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
    deps: DepsMut,
    _env: Env,
    _info: MessageInfo,
    msg: InstantiateMsg,
) -> Result<Response, ContractError> {
    /* Code is executed at contract creation and accepts an `InstantiateMsg`
    Used to set initial (default) state variables of the smart contract
    Can perform checks and acts like an execute message.
     */
    let state = State {
        global_var: msg.sent_message,
    };
    // Pushes the data to blockchain storage
    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();
        // Query data from blockchain
        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

use cosmwasm_schema::{cw_serde, QueryResponses};
#[cw_serde]
/*
variables to be passed to contract at instantiation.
secret variables or any variable that is open to a replay attack should not be 
part of the InstantiateMsg 
*/
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

use cosmwasm_std::StdError;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum ContractError {
    #[error("{0}")]
    Std(#[from] StdError),
    #[error("Unauthorized")]
    Unauthorized {},
    // Add any other custom errors you like here.
    // Look at https://docs.rs/thiserror/1.0.21/thiserror/ for details.
}

state.rs

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

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg};
use crate::msg::ExecuteMsg;
/// CwTemplateContract is a wrapper around Addr that provides a lot of helpers
/// for working with this.
#[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())
    }
}

Last updated