This is a simple IBC enabled CosmWasm smart contract with the feature of callback of ibc-send message on the ibc-ack method. It expects to be deployed on two chains and, when prompted, will send messages to its
counterpart. It then counts the number of times messages have been
received on both sides and also, when the source chain gets the ack-packet, some callback function (msgs) is executed on that chain if the callback
value in the SendPacket
is set true
.
The reason why this callback msg execution is valid is simply because ack process is the same as send process. In the process to produce ack-packet and passing back that packet to the source chain, there doesn't occur any illegal state-modification as ibc intends so. Hence, I believe it's effective way to realize ibc-send callback mechanism.
At a high level, to use this contract:
- Store and instantiate the contract on two IBC enabled chains. We will call these chains chain A and chain B.
- Configure and run a relayer to connect the two contracts.
- Execute the
Increment {}
method on one contract to increment the send a message and increment the count on the other one. - Use the
GetCount { connection }
query to check callback function worked as intended
Don't worry, I just wrote the test codes to check these features. Please see the How to test section.
To connect two CosmWasm contracts over IBC you must establish an IBC channel between them. The IBC channel establishment process uses a four way handshake. Here is a summary of the steps:
OpenInit
Hello chain B, here is information that you can use to verify I am chain A. Do you have information I can use?OpenTry
Hello chain A, I have verified that you are who you say you are. Here is my verification information.OpenAck
Hello chain B. Thank you for that information I have verified you are who you say you are. I am now ready to talk.OpenConfirm
Hello chain A. I am also now ready to talk.
Once the handshake has been completed a channel will be established
that the ibc messages may be sent over. In order to do a handshake and
receive IBC messages your contract must implement the following entry
points (see src/ibc.rs
):
ibc_channel_open
- Handles theOpenInit
andOpenTry
handshake steps.ibc_channel_connect
- Handles theOpenAck
andOpenConfirm
handshake steps.ibc_channel_close
- Handles the closing of an IBC channel by the counterparty.ibc_packet_receive
- Handles receiving IBC packets from the counterparty.ibc_packet_ack
- Handles ACK messages from the countarparty. This is effectively identical to the ACK message type in TCP.ibc_packet_timeout
- Handles packet timeouts.
Having implemented these methods, once you instantiate an instance of the contract it will be assigned a port. Ports identify a receiver on a blockchain in much the same way as ports identify applications on a computer.
# run the local-osmosis chain
# ./ci-scripts/osmosis/start.sh
# run the local-wasmd chain
# ./ci-scripts/wasmd/start.sh
# build the wasm file and optimize by run this shell
./compile_optimize.sh
cp ./artifacts/cw_ibc_callback_example.wasm ./tests/testdata/
# if you use apple silicon, cw_ibc_callback_example-aarch64.wasm
cd ./tests
npm run build
npm run test:unit
The well-written ibc-enabled contract for ICA - https://github.com/confio/osmo-oracle This repo also has unit tests in the contract code for ibc features.