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