Submessages
Learn how to use submessages on Secret Network
Introduction
In the CosmWasm SDK, submessages are a powerful feature that allows a contract to execute additional messages within the context of its own execution. SubMsg
just wraps the CosmosMsg
, adding some info to it: the id
field, and reply_on
. reply_on
describes if the reply
message should be sent on processing success, on failure, or both. To create submessages, instead of setting all the fields separately, you would typically use helper constructors: SubMsg::reply_on_success
, SubMsg::reply_on_error
and SubMsg::reply_always
.
In this tutorial, you will learn how to use submessages to execute a counter smart contract on Secret Network from another Secret Network smart contract 😊
Getting Started
git clone
the submessages example repository:
git clone https://github.com/writersblockchain/secret-submessages
Our Multi Contract System
In this tutorial, we will use submessages to execute a counter smart contract that is already deployed to the Secret Network Testnet. Thus, we are working with two smart contracts:
Manager Contract - which executes the Counter Contract using submessages
Counter Contract - which is executed by the Manager Contract
Designing the Manager Contract
We will be designing a Manager Smart Contract which can execute a Counter Contract that is deployed to the Secret testnet. Let's start by examining the message that we want to execute on the counter smart contract. In the src
directory, open msg.rs and review the Increment
msg:
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ExecuteMsg {
Increment { contract: String },
}
Increment
contains one parameter, the string contract.
This is the contract address of the counter contract, which we will increment.
Notice that we implement HandleCallBack for our ExecuteMsg
enum, which is what allows our submessages to be converted into a CosmosMsg
and executed:
use secret_toolkit::utils::HandleCallback;
impl HandleCallback for ExecuteMsg {
const BLOCK_SIZE: usize = BLOCK_SIZE;
}
Reply entry point
Submessages offer different options for the other contract to provide a reply. There are four reply options you can choose:
pub enum ReplyOn {
/// Always perform a callback after SubMsg is processed
Always,
/// Only callback if SubMsg returned an error, no callback on success case
Error,
/// Only callback if SubMsg was successful, no callback on error case
Success,
/// Never make a callback - this is like the original CosmosMsg semantics
Never,
}
In order to handle the reply from the other contract, the calling contract must implement a new entry point, called reply
:
#[entry_point]
pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result<Response, ContractError> {
match msg.id {
EXECUTE_INCREMENT_REPLY_ID => handle_increment_reply(deps, msg),
id => Err(ContractError::UnexpectedReplyId { id }),
}
}
Here is an example of how to handle the reply:
fn handle_increment_reply(_deps: DepsMut, msg: Reply) -> Result<Response, ContractError> {
match msg.result {
SubMsgResult::Ok(_) => Ok(Response::new().add_attribute("action", "increment")),
SubMsgResult::Err(e) => Err(ContractError::CustomError { val: e }),
}
}
The submessage returns a Result
containing:
Ok(Response)
if the submessage executed successfully, with an action attribute set to "increment".Err(ContractError)
if the submessage execution failed, with the error encapsulated in a custom contract error.
Executing the Manager contract
Now let's use this manager smart contract to increment a counter smart contract with submessages!
The counter contract we will be executing is deployed here:
const contractAddress = "secret1cldglt6wvueva2akly4x3wvzzlevk2hxzv0cvq";
cd
into manager/node:
cd manager/node
Install the dependencies:
npm i
Run node execute to execute the counter contract:
node execute
Upon successful execution, you will see a tx
returned in your terminal:
{
height: 5867847,
timestamp: '',
transactionHash: '046C97A2E2404FBF2AB75AFA0850BCD3CC7693BE270FA9DB86D2CE85EEDA5094',
code: 0,
codespace: '',
info: '',
tx: {
'@type': '/cosmos.tx.v1beta1.Tx',
body: {
messages: [Array],
memo: '',
timeout_height: '0',
extension_options: [],
non_critical_extension_options: []
}
Querying the counter contract
Now, let's query the counter contract to make sure it was executed correctly!
cd
into counter/node:
cd counter/node
Install the dependencies:
npm i
And run node query
:
node query
You will see that the counter contract has been incremented by 1 :)
{ count: 1 }
Summary
In this tutorial, you learned how to utilize submessages in the CosmWasm SDK to perform complex, atomic operations within smart contracts on the Secret Network. This guide walked you through executing a counter smart contract from another contract, detailing the setup of a Manager Contract that triggered the Counter Contract using submessages, managing replies, and verifying the execution results 🤓
Last updated
Was this helpful?