A guide to Inter-Blockchain Communication (IBC)

Polymer Labs
8 min readOct 4, 2022

Overview of IBC

After covering the basics of IBC in our previous article, this piece will take a deeper dive into the protocol. The following images show a high-level representation of how the IBC core module forms the IBC-Go module.

Figure 4: IBC Module Overview
Figure 5: IBC Module Internal

Foundations of IBC

To understand the basic building blocks of IBC, there are several components that must be broken down:

  • Light Clients
  • Relayers
  • IBC Connections, Channels, and Packets

Light Client

Light clients get their name from having a “lighter” footprint than a full node. Its primary role is to track the consensus state of other blockchains and have the proof spec necessary to verify the proof against the client’s consensus state. Light clients use block headers to confirm the latest blockchain consensus state rather than executing and storing the block data & state. Light client protocols also consist of Merkle proofs that allow for trustless verification.

Figure 1: Merkle Proof (source)


Relayers are the carriers of IBC packets from one chain to another. They continuously check for new packets on an IBC connection from the sender chain and once found, relay them across to the other chain. Relayers have full access to the nodes on both the sender and the receiver chains, which enables them to transport a message from one chain to another successfully.

Before the relay of the IBC packets, the source chain will submit a commitment proof on its chain, which is then verified by the receiving chain; this is where light clients play their role. Relaying is trustless, meaning that by using relayers, there is no need to trust a third party to send packets across chains, such as bridges which are infamous for being exploited. With IBC, we only trust the source & destination chains.

Figure 2: IBC high-level architecture (source)


An IBC connection encapsulates two stateful objects. The connection ends on two separate blockchains. The connection is made by relayers between light clients on each chain, which facilitates the packet relays using channels. Connections are safely established by using a handshake protocol.

The state of the connection is tracked on a chain with the following interface.

interface ConnectionEnd {    state: ConnectionState    counterpartyConnectionIdentifier: Identifier    counterpartyPrefix: CommitmentPrefix    clientIdentifier: Identifier    counterpartyClientIdentifier: Identifier 

version: string
  • The state field describes the current state of the connection end.
  • The counterpartyConnectionIdentifier field identifies the connection end on the counterparty ledger associated with this connection.
  • The counterpartyPrefix field contains the prefix used for state verification on the counterparty ledger associated with this connection.
  • The clientIdentifier field identifies the client associated with this connection.
  • The counterpartyClientIdentifier field identifies the client on the counterparty ledger associated with this connection.
  • The version field is an opaque string which can be used to determine encodings or protocols for channels or packets utilizing this connection.


An IBC channel serves as a pipe for packets, ensuring that they are relayed from the module of one chain to another. It also ensures that the information is delivered only once, in the order it was sent, and to the corresponding module on the destination chain. Each IBC connection may have multiple IBC channels.

The state of the channel is tracked on a chain using the following structure:

enum ChannelState {    INIT,    TRYOPEN,    OPEN,    CLOSED,}
  • A channel end in INIT state has just started the opening handshake.
  • A channel end in TRYOPEN state has acknowledged the handshake step on the counterparty ledger.
  • A channel end in OPEN state has completed the handshake and is ready to send and receive packets.
  • A channel end in CLOSED state has been closed and can no longer be used to send or receive packets.


An IBC packet contains data that is transferred from one module to another over a channel using a particular interface:

interface Packet {    sequence: uint64    timeoutHeight: uint64    timeoutTimestamp: uint64    sourcePort: Identifier    sourceChannel: Identifier    destPort: Identifier     destChannel: Identifier    data: bytes}
  • The sequence number corresponds to the order of sends and receives, where a packet with an earlier sequence number must be sent and received before a packet with a later sequence number.
  • The timeoutHeight indicates a consensus height on the destination ledger after which the packet will no longer be processed, and will instead count as having timed-out.
  • The timeoutTimestamp indicates a timestamp on the destination ledger after which the packet will no longer be processed, and will instead count as having timed-out.
  • The sourcePort identifies the port on the sending ledger.
  • The sourceChannel identifies the channel end on the sending ledger.
  • The destPort identifies the port on the receiving ledger.
  • The destChannel identifies the channel end on the receiving ledger.
  • The data is an opaque value which can be defined by the application logic of the associated modules.

The IBC Flow

Now that we’ve got some of the basics covered, let’s dive deeper into the flow of IBC. In order for a packet to be sent from one chain to another, a connection must be established. Much like the TCP handshake in Web2, a connection handshake allows two separate chains to acknowledge each other. Before continuing, each chain must agree on the following:

  • Version of connection
  • Consensus state
  • Identifier

Forming a connection is a multi-step process:

  1. Chain A: “Hi! I would like to open a connection. Here’s my consensus state, what I think your consensus state is, the version I’d like to use, and some proofs that I’ve stored this information.” (ConnOpenInit)
  2. Chain B: “I acknowledge you’re trying to open a connection. Your record of my consensus state is correct. I can use the same version requested. I’ve verified your proofs and have included my own proofs for the connection object I’ve created.” (ConnOpenTry)
  3. Chain A: “I’ve verified your proofs, and the connection has been established on my end. Here’s a proof of that.” (ConnOpenAck)
  4. Chain B: “I will also establish a connection.” (ConnOpenConfirm)

Once a connection is created, the next step is creating a channel to relay the IBC packets between modules. For reference, the IBC connection is the phone line, and the IBC channels are the phone calls.

The process of setting up a channel is also a multi-step process:

  1. Chain A: “Hi! A module on my chain wants to open up a channel with a module on your chain. Here is some channel information and proof that I’ve stored it.” (ChanOpenInit)
  2. Chain B: “I’ve verified your proof, and the requested module has accepted the attempt to open a channel. Here’s proof of me storing channel information.” (ChanOpenTry)
  3. Chain A: “I’ve verified your proof and the channel is now live.” (ChanOpenAck)
  4. Chain B: “Since your channel is now live, so is mine.” (ChanOpenConfirm)

Now that the connection & channel are live, the last step is to send or relay the IBC packet. Going back to the phone line analogy, IBC packets are the signals sent through the phone line, which are interpreted on the receiving line.

The process of sending an IBC packet is also a multi-step process:

  1. Chain A: “Hi! Here is an IBC packet; all information about the connection, channel, message, and proof is stored. I have added the IBC message on my chain.” (sendPacket)
  2. Chain B: “I’ve verified the IBC message on your chain; the IBC packet is received and interpreted. Here is the acknowledgment.” (recvPacket)
  3. Chain A: “I’ve received your acknowledgment, have a good day!” (acknowledgePacket)
Figure 3: IBC packet flow (source)

IBC Applications

IBC fuels innovation by enabling dApps built on top of the protocol to do much more than what could be possible otherwise. Here are a couple examples.

Interchain Accounts

Using a real-world example, through IBC, someone with a US-based bank account can now access the transactions of a virtual bank account in France. IBC allows users to access accounts across chains through an interchain account. It helps share data cross-chain and write states on the other chain.

Figure 6: Interchain Accounts

Interchain Queries

Interchain queries allow chains to query information across chains. The interchain account was primarily made for cross-chain transactions, which means it has an added layer of authentication.

Figure 7: Interchain Queries

Cross Chain Validation

Cross-chain validation allows for running the proof logic on one chain and relaying the proof result with relevant information cross-chain using IBC. Suppose Chain A runs the proof logic to verify the blocks on Chain B and relays the proof result to Chain C. This concept will allow cross-chain validation, which plays a crucial role in achieving interchain security.

Polymer scales IBC to all chains

Polymer is working on a universal router chain that supports e2e IBC connectivity across all chains. In the absence of a native IBC integration (e.g. Cosmos SDK chain), we’re integrating IBC directly into the VM of the counterparty chain.

Polymer aims to be the most efficient e2e IBC protocol across heterogeneous networks. The team continues to work on optimizations in the core protocol as well as investing in R&D efforts on Zero Knowledge (more on this in future articles) and infrastructure.

As an IBC native protocol, Polymer will support efficient light client proof verification across all chains and will provide core IBC primitives such as connections and channels within the VMs of non-native IBC chains.

About Polymer:

Polymer is the first modular IBC-based networking protocol. The Polymer chain will enable ZK-IBC connectivity across all integrated chains with a trustless architecture based on light client state proof verification. Polymer believes in a multichain future connected primarily by one open-sourced, community-developed, and maintained industry standard, IBC x Polymer.

Follow our Twitter, visit our Website, and join our community on Discord! Sign up to become a validator here, and to take part in Polymer’s private testnet here.

Sources: https://arxiv.org/pdf/2006.15918.pdf



Polymer Labs

Polymer is building a universal IBC router to connect all chains.