An example CosmWasm contract for connecting contracts over IBC.

Overview

CosmWasm IBC Example

This is a simple IBC enabled CosmWasm smart contract. 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.

At a high level, to use this contract:

  1. Store and instantiate the contract on two IBC enabled chains. We will call these chains chain A and chain B.
  2. Configure and run a relayer to connect the two contracts.
  3. Execute the Increment {} method on one contract to increment the send a message and increment the count on the other one.
  4. Use the GetCount { connection } query to determine the message count for a given connection.

This repo also contains a demo contract which makes an infinite loop of contract calls over IBC. See the README on the zeke/ibc-replay branch for more information and an integration test that demonstrates this.

Background

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:

  1. OpenInit Hello chain B, here is information that you can use to verify I am chain A. Do you have information I can use?
  2. OpenTry Hello chain A, I have verified that you are who you say you are. Here is my verification information.
  3. 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.
  4. 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):

  1. ibc_channel_open - Handles the OpenInit and OpenTry handshake steps.
  2. ibc_channel_connect - Handles the OpenAck and OpenConfirm handshake steps.
  3. ibc_channel_close - Handles the closing of an IBC channel by the counterparty.
  4. ibc_packet_receive - Handles receiving IBC packets from the counterparty.
  5. ibc_packet_ack - Handles ACK messages from the countarparty. This is effectively identical to the ACK message type in TCP.
  6. 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.

You can find the port that has been assigned to your contract by running junod query wasm contract <ADDRESS> and inspecting the ibc_port_id field. For example:

$ junod query wasm contract juno1r8k4hf7umksu9w53u4sz0jsla5478am6yxr0mhkuvp00yvtmxexsj8wazt
address: juno1r8k4hf7umksu9w53u4sz0jsla5478am6yxr0mhkuvp00yvtmxexsj8wazt
contract_info:
  admin: ""
  code_id: "1377"
  created: null
  creator: juno1m7a7nva00p82xr0tssye052r8sxsxvcy2v5qz6
  extension: null
  ibc_port_id: wasm.juno1r8k4hf7umksu9w53u4sz0jsla5478am6yxr0mhkuvp00yvtmxexsj8wazt
  label: ekez-cw-ibc-example

To establish a connecton between two contracts you will need to set up a relayer. If you chose to use hermes, after configuration the command to establish a connection is:

hermes create channel --a-chain uni-3 --b-chain juno-1 --a-port wasm.juno1r8k4hf7umksu9w53u4sz0jsla5478am6yxr0mhkuvp00yvtmxexsj8wazt --b-port wasm.juno1fsay0zux2vkyrsqpepd08q2vlytrfu7gsqnapsfl9ge8mp6fvx3qf062q9 --channel-version counter-1

Then, to start the relayer:

hermes start

Note that you will need to configure hermes for the chains you are relaying between before these commands may be run.

Once the relayer is running, make note of the channel ID that has been established. You will use this when telling the contract to send packets. This is needed because one contract may be connected to multiple channels. You can not assume that your channel is the only one connected at a given time.

For example, to increment the count on the counterparty chain over a connection between local channel-72 and remote channel-90:

junod tx wasm execute juno1r8k4hf7umksu9w53u4sz0jsla5478am6yxr0mhkuvp00yvtmxexsj8wazt '{"increment": { "channel": "channel-72" }}' --from ekez --gas auto --gas-adjustment 2 --fees 12000ujunox

Then, switching to the other chain, we can query that count by running:

junod query wasm contract-state smart juno1fsay0zux2vkyrsqpepd08q2vlytrfu7gsqnapsfl9ge8mp6fvx3qf062q9 '{"get_count": {"channel": "channel-90"}}'

Troubleshooting

  1. Packets may take over a minute to be relayed. If your packet is not sent instantly it is probably OK. Feel free to take a break and come back.
  2. Hermes will not pick up packets that were sent while it was not running. Start your relayer and wait for the log line Hermes has started before sending packets.

Testing

To run IBC tests (you will need just installed):

just simtest

This contract uses the Cosmos SDK's simulator to test IBC interactions between chains. Testing code and information about its setup can be found in the tests subdirectory.

You might also like...
Minimal Substrate node configured for smart contracts via pallet-contracts.

substrate-contracts-node This repository contains Substrate's node-template configured to include Substrate's pallet-contracts ‒ a smart contract modu

evm2near compiles Solidity contracts into NEAR WebAssembly contracts.

EVM → NEAR evm2near is a project for compiling EVM bytecode into wasm bytecode, with the particular goal of having that wasm artifact be executable on

Ticketed Discreet Log Contracts (DLCs) to enable instant buy-in for wager-like contracts on Bitcoin.
Ticketed Discreet Log Contracts (DLCs) to enable instant buy-in for wager-like contracts on Bitcoin.

dlctix Ticketed Discreet Log Contracts (DLCs) to enable instant buy-in for wager-like contracts on Bitcoin. This project is part of the Backdrop Build

IBC modules and relayer - Formal specifications and Rust implementation

ibc-rs Rust implementation of the Inter-Blockchain Communication (IBC) protocol. This project comprises primarily four crates: The ibc crate defines t

Rust implementation of the Inter-Blockchain Communication (IBC) protocol.

ibc-rs Rust implementation of the Inter-Blockchain Communication (IBC) protocol. This project hosts the ibc rust crate which defines the main data str

An all-in-one IBC protocol providing fungible token transfer, interchain account, and async query functionalities

ICS-999 An all-in-one IBC protocol providing fungible token transfer, interchain account (ICA), and query (ICQ) functionalities, implemented in CosmWa

An EVM low-level language that gives full control over the control flow of the smart contract.

Meplang - An EVM low-level language Meplang is a low-level programming language that produces EVM bytecode. It is designed for developers who need ful

An example smart contract that builds on top of xyz

xyz Guestbook Tutorial Contract This repository contains an example smart contract that illustrates how to build on top of the xyz NFT contract. This

Example NFT marketplace project using ink! smart contract.

NFT Marketplace project This contract is an example for the NFT marketplace implementation. License Apache 2.0 🏗️ How to use - Contracts 💫 Build Use

Comments
  • Test light client `Expired` state

    Test light client `Expired` state

    what i'm currently trying to figure out is how to simulate light client expiry. basically, for two chains to connect and make a connection, they need to run light clients of eachother. light clients are small versions of the other blockchain's state machine. using light clients the two chains can prove things about each other. for example, a relayer might prove attempted delivery when returning a timeout.

    light clients (for reasons i think are related to them being "light") have an expiration. in the trusting period. if a light client expires, it enters this strange state of "expired". we need to learn more about this state.

    the code can be found on the zeke/strangelove branch and is based on this test from the ibc-go team:

    https://github.com/cosmos/ibc-go/blob/main/e2e/tests/core/client_test.go

    if you read through the test you can see how they make a client expire and then use x/gov prop to bring it back to life. the expired state is different from closed. my current understanding is that in the expired state it won't accept packets, what i want to learn is if, in that state it will allow timeouts to be returned to the sending chain?

    opened by 0xekez 1
  • Test light client missbehavior

    Test light client missbehavior

    The IBC spec discusses misbehavior here. This test is the same as #5, but for a light client that is frozen due to misbehavior. We need to be able to answer two questions:

    1. What is the recovery process if missbehavior is discovered?
    2. Will timeouts be delivered on the sending chain if a light client is frozen due to missbehavior?
    opened by 0xekez 1
  • Explore using Apalache to verify contract

    Explore using Apalache to verify contract

    Informal has a CosmWasm Apalache example here: https://github.com/informalsystems/atomkraft/blob/dev/examples/cosmwasm/counter/models/counter.tla

    We should explore what we can formally verify about this contract using Apalache. This learning will be very useful for our other IBC work. Some ideas for invariants for this contract:

    1. Counterparty count should be the same as the number of times Increment {} has been called.
    2. Closing a channel should reset the count to zero.

    It might be good to keep things simple like this for our first try.

    opened by 0xekez 0
  • Use cosmwasm std mocking in tests

    Use cosmwasm std mocking in tests

    We could use mocking IBC functions below to demonstrate IBC working example that comes with some cool example tests. mock_ibc_channel, mock_ibc_packet_recv mock_ibc_channel_connect_ack, mock_ibc_channel_connect_confirm etc.

    opened by deveusss 1
Owner
ekez
ekez
CosmWasm-Examples is a collection of example contracts and applications built using the CosmWasm framework

CosmWasm-Examples is a collection of example contracts and applications built using the CosmWasm framework. CosmWasm is a secure and efficient smart contract platform designed specifically for the Cosmos ecosystem.

Vitalii Tsyhulov 20 Jun 9, 2023
A simple example demonstrating cross-contract calls in CosmWasm smart contracts

Cross-contract calls This tutorial demonstrates cross-contract calls with CosmWasm v1. Overview An end user calls the reservation contract to register

csli Tools 3 Sep 12, 2022
Cosmwasm in Cosmwasm through ComposableFi/cosmwasm-vm

Cosmwasmception Running Fastest way to run this contract would be through our vm. But note that our vm runs an already built version this contract, so

Abdullah Eryuzlu 3 Oct 5, 2022
CosmWasm multi-contract testing framework

Multi Test: Test helpers for multi-contract interactions Warning: Alpha Software Designed for internal use only. This is used for testing cw-plus cont

CosmWasm 7 Dec 6, 2022
Template for multi-contract CosmWasm projects

CosmWasm Template Template for multi-contract CosmWasm projects How to Use Install cargo-make: cargo install --force cargo-make Run formatter: cargo m

null 11 Jan 28, 2023
Examples and helpers to build NFT contracts on CosmWasm

CosmWasm NFTS This repo is the official repository to work on all NFT standard and examples in the CosmWasm ecosystem. cw721 and cw721-base were moved

CosmWasm 147 Jan 4, 2023
My code for the terra.academy course on CosmWasm smart contracts

CosmWasm Starter Pack This is a template to build smart contracts in Rust to run inside a Cosmos SDK module on all chains that enable it. To understan

Alex Incerti 0 Nov 7, 2021
A gRPC-based scripting library for interacting with CosmWasm smart-contracts.

Cosmos Rust Script Smart contract scripting library to ease CosmWasm smart contract development and deployment. cosm-script is inspired by terra-rust-

null 11 Nov 3, 2022
A blazingly fast compiling & optimization tool for CosmWasm smart contracts.

cw-optimizoor A blazingly fast alternative to CosmWasm/rust-optimizer for compiling & optimizing CW smart contracts. It's primarily meant to speed up

Sebastian Mandrean 37 Apr 15, 2023
Reference application for connecting to the TAPLE DLT network.

⚠️ TAPLE is in early development and should not be used in production ⚠️ TAPLE Client TAPLE (pronounced T+ ?? ['tapəl]) stands for Tracking (Autonomou

Open Canarias 8 Feb 15, 2023