- Docs
- Smart Contracts
- Message
Messages
In CosmWasm, interactions with smart contracts are facilitated through messages. These messages define the operations that can be executed on a contract, playing a crucial role in tasks such as instantiating, querying, migrating, and executing other transactions on the blockchain.
Message definitions
Within most CosmWasm contracts, you'll find a msg.rs file that outlines the key messages used to interact with the contract. Below are the common types of messages you'll encounter:
- InstantiateMsg: This message is used to create a new instance of a CosmWasm smart contract on the blockchain. It is passed to the instantiate function in the main contract.rs file. The InstantiateMsg usually includes parameters that initialize the contract's state, such as initial balances, configurations, or other settings required for the contract to function properly.
- ExecuteMsg: This message is used to execute specific actions or operations defined by the contract after it has been instantiated. The ExecuteMsg typically contains different variants representing various functions or commands the contract can perform. For example, it might include actions like transferring tokens, updating configurations, or invoking specific business logic. The contract processes this message in the execute function, where each variant of the ExecuteMsg is matched to its corresponding handler function.
- QueryMsg: This message is used to query the state of the contract without making any changes to it. The QueryMsg allows users or other contracts to retrieve data from the contract, such as balances, configurations, or other relevant information. Unlike ExecuteMsg, queries do not require gas fees as they are read-only operations. The QueryMsg is processed by the query function in contract.rs, which interprets the query type and returns the appropriate response.
- MigrateMsg: This message is used to upgrade or modify the code of an existing contract instance while preserving its state. The MigrateMsg is involved when a contract needs to be updated to a new version of its code. This process is handled by the migrate function in contract.rs. This function can adjust the state if necessary to make it compatible with the new code version. Migrations are essential for maintaining contract functionality and security over time as improvements or fixes are applied.
Summary of message roles
- InstantiateMsg initializes the contract with necessary parameters.
- ExecuteMsg handles the various actions or commands the contract can perform.
- QueryMsg allows for the retrieval of contract data without modifying the state.
- MigrateMsg enables the safe and controlled upgrade of the contract code.
Schema files
If you're unsure about the arguments that can be passed to these messages, you can refer to the contract's schema folder. This folder contains JSON files that define the expected shape and types for the contract's messages. These schemas are automatically generated when building the contract using the cargo schema command or the archway contracts build command if you are using the Archway Developer CLI.
Common schema files include:
- instantiate_msg.json: Defines the structure and types expected for the InstantiateMsg.
- execute_msg.json: Defines the structure and types for each of the messages that the contract can use to execute an action.
For contracts with extensive APIs, the schema folder may contain many more files, each corresponding to different messages or queries. Exploring these files can help you understand the contract's API and find the exact message or command you're looking for.
Example: name service contract
In the nameservice example contract, once the contract has been instantiated, there are only two valid ExecuteMsg messages:
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]#[serde(rename_all = "snake_case")]pub enum ExecuteMsg { Register { name: String }, Transfer { name: String, to: String },}- Register: Registers a name with the service.
- Transfer: Transfers ownership of a registered name to another address.
The context of this code can be found here.
Processing messages
The ExecuteMsg messages are processed within the contract.rs file. Each variant of the enum is handled in the execute function. Here’s how the execute function handles the Register and Transfer messages:
#[cfg_attr(not(feature = "library"), entry_point)]pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg,) -> Result<Response, ContractError> { match msg { ExecuteMsg::Register { name } => execute_register(deps, env, info, name), ExecuteMsg::Transfer { name, to } => execute_transfer(deps, env, info, name, to), }}This function matches the incoming ExecuteMsg and dispatches it to the appropriate handler function—execute_register for registering a name and execute_transfer for transferring a name. This design allows the contract to handle different types of messages cleanly and efficiently.
You can find the source code for the execute function here.