IBC integration

IBC transaction

An IBC transaction tx_ibc.wasm is provided. We have to set an IBC message to the transaction data corresponding to execute an IBC operation.

The transaction decodes the data to an IBC message and handles IBC-related data, e.g. it makes a new connection ID and writes a new connection end for MsgConnectionOpenTry. The operations are implemented in IbcActions.The transaction doesn't check the validity for the state changes. IBC validity predicate is in charge of the validity.

IBC validity predicate

IBC validity predicate checks if an IBC-related transaction satisfies IBC protocol. When an IBC-related transaction is executed, i.e. a transaction changes the state of the key that contains InternalAddress::Ibc, IBC validity predicate (one of the native validity predicates) is executed. For example, if an IBC connection end is created in the transaction, IBC validity predicate validates the creation. If the creation with MsgConnectionOpenTry is invalid, e.g. the counterpart connection end doesn't exist, the validity predicate makes the transaction fail.

Fungible Token Transfer

The transfer of fungible tokens over an IBC channel on separate chains is defined in ICS20.

In Namada, the sending tokens is triggered by a transaction having MsgTransfer as transaction data. A packet including FungibleTokenPacketData is made from the message in the transaction execution.

Namada chain receives the tokens by a transaction having MsgRecvPacket which has the packet including FungibleTokenPacketData.

The sending and receiving tokens in a transaction are validated by not only IBC validity predicate but also IBC token validity predicate. IBC validity predicate validates if sending and receiving the packet is proper. IBC token validity predicate is also one of the native validity predicates and checks if the token transfer is valid. If the transfer is not valid, e.g. an unexpected amount is minted, the validity predicate makes the transaction fail.

A transaction escrowing/unescrowing a token changes the escrow account's balance of the token. The key is {token_addr}/balance/{escrow_addr}. A transaction burning a token changes the burn account's balance of the token. The key is {token_addr}/balance/BURN_ADDR. A transaction minting a token changes the mint account's balance of the token. The key is {token_addr} /balance/MINT_ADDR. {escrow_addr}, {BURN_ADDR}, and {MINT_ADDR} are addresses of InternalAddress. When these addresses are included in the changed keys after transaction execution, IBC token validity predicate is executed.

IBC message

IBC messages are defined in ibc-rs. The message should be encoded with Protobuf (NOT with Borsh) as the following code to set it as a transaction data.

fn main() {
use ibc::tx_msg::Msg;

pub fn make_ibc_data(message: impl Msg) -> Vec<u8> {
    let msg = message.to_any();
    let mut tx_data = vec![];
    prost::Message::encode(&msg, &mut tx_data).expect("encoding IBC message shouldn't fail");