Learn how to use submessages on Secret Network
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
.
You can learn more about submessages here!
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 😊
git clone
the submessages example repository:
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
This tutorial follows the same design patterns of the Cross Contract Communication tutorial, but uses submessages in place of Wasm messages
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:
Increment
contains one parameter, the string contract.
This is the contract address of the counter contract, which we will increment.
Where is the code hash?
Unlike other Cosmos chains, Secret Network requires the hash of the smart contract in addition to the address when executing calls to smart contracts.
Contract hashes are what binds a transaction to the specific contract code being called. Otherwise, it would be possible to perform a replay attack in a forked chain with a modified contract that decrypts and prints the input message.
However, there is no need to pass a code_hash
when doing cross contract or sub message calls because we have designed the helper functionget_contract_code_hash
which we call internally when executing the Increment
function.
Notice that we implement HandleCallBack for our ExecuteMsg
enum, which is what allows our submessages to be converted into a CosmosMsg
and executed:
Submessages offer different options for the other contract to provide a reply. There are four reply options you can choose:
In order to handle the reply from the other contract, the calling contract must implement a new entry point, called reply
:
Here is an example of how to handle the reply:
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.
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:
Or deploy your own counter contract here :)
cd
into manager/node:
Install the dependencies:
Run node execute to execute the counter contract:
Upon successful execution, you will see a tx
returned in your terminal:
Now, let's query the counter contract to make sure it was executed correctly!
cd
into counter/node:
Install the dependencies:
And run node query
:
You will see that the counter contract has been incremented by 1 :)
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 🤓
get_contract_code_hash helper function
To retrieve a Secret Network smart contract's code hash from within a Secret contract call, you can use Stargate queries to directly query the on-chain data from inside the contract.
This helper function is particularly interesting if you desire to make complicated contract structures that involve submessages or just cross-contract messages to different Secret Network contracts. With this code snippet, you do not need to supply the code_hash
of each contract that you are going to call in submessage or normal messages. It is sufficient to know the contract address of the other contract, the code snipped will fetch the latest on chain code_hash
for you.
Be aware that contracts can be upgraded on Secret Network! Since this code snippet always fetch the code_hash
directly from the chain without any extra check (which was implictly done by manually supplying the code_hash
), you need to be careful about silently (perhaps maliciously) upgraded contracts which potentially releveal confidential information.
The Secret Network team has designed a helper function, get_contract_code_hash
, exactly for this purpose.
See an example usage of get_contract_code_hash here.
Simply add the Anybuf package and the "stargate"
feature for cosmwasm-std to your cargo.toml
:
And then add the function to your contract: