IBC, Smart Contracts, and You!

Provenance Blockchain Foundation
Provenance Blockchain
6 min readDec 15, 2022

So…you read the excellent article by Jacob Schwartz introducing smart contracts on the Provenance Blockchain, then tried it out yourself by following the tutorial, and now you’re an expert at creating smart contracts (or even dApps)! The next step in your smart contract training is Inter-Blockchain Communication (IBC).

What is Inter-Blockchain Communication?

One of the differentiating features of the Cosmos Ecosystem from other blockchains is IBC. IBC is the protocol which provides cross-chain communication. In other words, allowing many different blockchains to interact with each other. There are a few goals in the implementation, but the primary ones are reliable, ordered, and authenticated communication in a minimal-trust environment.

The best part? It is a general-purpose messaging protocol that allows any type of data to be communicated across chains, not just predefined messages like token transfers or Interchain Accounts

I highly recommend reading more about the protocol in the documentation from the Cosmos team.

How does IBC work?

It’s important to keep in mind that trust between the networks is to be as minimal as possible. We don’t want to introduce new trust requirements, this is decentralization after all! So, if we can trust that each blockchain performs their respective functions correctly, then we can trust the communications between them given the design of IBC.

https://tutorials.cosmos.network/academy/3-ibc/1-what-is-ibc.html

There are two layers in IBC: the Transport layer and the Application layer. If you are familiar with computer networks, these terms will be familiar to you and the separation of concerns is similar.

The Transport layer concerned only with delivering the messages between the chains. It is not aware of the semantics of the messages as from its perspective they are all just bytes of data. In order to transfer messages, the transport layer utilizes four components: light clients, relayers, connections, and channels.

Light clients
Instead of running full nodes that track the full history of the blockchain, light clients are just a small representation of the counterparty chain. E.g. — if we are connecting chain A and chain B, chain A would have a light client (state representation) of chain B, and vice-versa. Essentially, if one wants to send a message to another chain, it is committed to its own chain first, and that block header is transmitted to the receiving chain as well as a commitment proof. This can be verified by the receiving chain that the message was indeed committed. By committing IBC messages to the contracts chain, we can guarantee message integrity and authenticity without requiring an increase in trust between the chains.

Relayers
Relayers are a separate process/service which anyone can run. Their sole-purpose is to detect the aforementioned message on the origin chain and “relay” that to the remote chain. The major concept is that IBC messages are not directly sent to the destination chain. Rather, the message is committed to its own chain, the relayer reads this message and forwards it to the destination chain. So, any time data is to move across chains, it must be committed to its own state. There are two implementations of the relayer: one in Go and the other in Rust. The Rust relayer, Hermes, is recommended as it is feature complete. https://github.com/informalsystems/hermes

Connections and Channels
Connections provide light clients the means to communicate by creating a four-way handshake. It provides the initialization, version negotiation, and establishment of communication states. These connections are per chain, whereas channels are per module. This is a key difference and will become clearer later.

IBC sounds awesome! But, how do smart contracts come into play?

This is the exciting part. Sure, Interchain Accounts provide the means for executing transactions on behalf of your local account, as if you performed the transaction yourself directly on the remote chain. But, we are still limited to the functionality provided by modules. Smart contracts, however, allow programmable functionality that does not require a chain upgrade and is not limited to the logic of the modules. The same benefits smart contracts provide to a single chain are magnified when creating IBC-enabled smart contracts.

To get started writing an IBC smart contract you first need to be familiar with regular smart contracts and that will be assumed for the remainder of this article.

In order to enable IBC for a smart contract you will need to add the following Entrypoints: ibc_channel_open, ibc_channel_connect, ibc_channel_close, ibc_packet_receive, ibc_packet_ack, and ibc_packet_timeout. By implementing these entrypoints, the chain is made aware of the smart contracts IBC capability and reserves a channel using the contracts address. This is how messages can be addressed to specific contracts.

ibc_channel_open
This entrypoint is called when a channel is opened. You may accept the channel or reject it based on criteria such as version or message ordering.

ibc_channel_connect
This entrypoint is invoked after ibc_channel_open. You can write initialization logic for state and return messages here.

ibc_channel_close
This entrypoint is invoked upon closing of the channel. It is intended for any cleanup actions you may want to take.

ibc_packet_receive
The packet receive entrypoint is the primary callback and is invoked any time a message is sent via IBC to your contract. The payload will contain any messages you design as part of your smart contract API. It is similar in functionality to the Execute entrypoint. This entrypoint will return a message that includes an acknowledgement to be returned to the origin chain smart contract that made the original call.

ibc_packet_ack
This entrypoint is called when an acknowledgement is received after sending a packet to a remote chain contract.

ibc_packet_timeout
Finally, this optional entrypoint is called if a sent IBC packet timed out. This could occur if a relayer fails to transfer the message, any other network failures, or remote chain failures.

For more details regarding the IBC Smart Contract Entrypoints, see the CosmWasm developer readme.

Once the origin and destination contracts have been created, you are ready to start:

  1. You will need to store and instantiate the contracts on their respective chains.
  2. Use the hermes relayer cli to create a connection and open a channel to establish communication between the two contracts. An example:
hermes create channel \
- a-chain $LOCAL_CHAIN_ID \
- b-chain $REMOTE_CHAIN_ID \
- a-port wasm.$IBC_REFLECT_SEND_ADDRESS \
- b-port wasm.$IBC_REFLECT_ADDRESS \
- order ordered \
- channel-version $CHANNEL_VERSION \
- new-client-connection \
- yes

3. Start the relayer

If everything was successful, you will see the relayer waiting for IBC messages. If you invoke the origin chain contract to send an IBC packet, the relayer will detect it and correctly relay that packet to the destination chain contract. When that contract responds, the relayer will forward the acknowledgment back to the origin chain contract.

To see a working example, check out the sample IBC project in ProvWasm

Be sure to check out the documentation via the links in this article for more information and we look forward to seeing all your contracts in action on the Provenance Blockchain!

Links:

KEN TALLEY

Ken is a Software Engineer who has lived in Texas and Colorado. Before joining the Provenance Blockchain team, he has worked in the Identity and Access Management space for startups and large enterprises. When he’s not programming, you can find him turning wrenches or planning his next camping adventure.

--

--

Provenance Blockchain Foundation
Provenance Blockchain

The public open-source blockchain used by over 60 financial institutions. Billions of dollars of financial transactions have been executed on Provenance.