IBC Token Transfer | Developer Portal (2024)

IBC Token Transfer | Developer Portal (1)

Transferring tokens between chains is both a common requirement and a significant technical challenge when two chains are incompatible. A convenient solution for moving tokens between chains is essential.

In this section, you will explore how a fungible token transfer can be done with IBC.

Having looked at IBC's transport, authentication, and ordering layer (IBC/TAO), you can now take a look at ICS-20 (opens new window). ICS-20 describes fungible token transfers.

IBC Token Transfer | Developer Portal (2)

Fungibility refers to an instance in which a token is interchangeable with other instances of that token or not. Fungible tokens can be exchanged and replaced.

There are many use cases involving token transfers on blockchains, like the tokenization of assets holding value or initial coin offerings (ICOs) to finance blockchain projects. IBC makes it possible to transfer tokens and other digital assets between (sovereign) chains, both fungible and non-fungible tokens. For example, fungible token transfers allow you to build applications relying on cross-chain payments and token exchanges. Therefore, IBC frees up great potential for cross-chain Decentralized Finance (DeFi) applications by offering a technically reliable cross-chain interoperability protocol that is compatible with digital assets on multiple networks.

The corresponding implementation (opens new window) is a module on the application level.

IBC Token Transfer | Developer Portal (3)

Look at the picture above. You can see two chains, A and B. You also see there is a channel connecting both chains.

How can tokens be transferred between chains and channels?

To understand the application logic for a token transfer, first, you have to determine the source chain:

IBC Token Transfer | Developer Portal (4)

Then the application logic can be summarized:

IBC Token Transfer | Developer Portal (5)

Shortly you will see the corresponding code. Now again have a look at a transfer from source to sink:

IBC Token Transfer | Developer Portal (6)

Above the source is chain A. The source channel is channel-2 and the destination channel is channel-40. The token denominations are represented as {Port}/{Channel}/{denom} (or rather their IBC denom representation on chain). The prefixed port and channel pair indicate which channel the funds were previously sent through. You see transfer/channel-... because the transfer module will bind to a port, which is named transfer. If chain A sends 100 ATOM tokens, chain B will receive 100 ATOM tokens and append the destination prefix port/channel-id. So chain B will mint those 100 ATOM tokens as ibc/<hash of transfer/channel-40/uatom>. The channel-id will be increased sequentially per channel on a given connection.

IBC Token Transfer | Developer Portal (7)

We can send assets (or their IBC voucher representation) in multiple hops across multiple chains. Every single time the path will be prepended with the port/channel-id/... prefix.

When sending this IBC denom (having had multiple hops) back to its source chain, for every hop back one port/channel-id/... prefix will be taken off. This results in a return to the original denom if all the hops are reversed.

If the tokens are sent back from the same channel as they were received:

IBC Token Transfer | Developer Portal (8)

Chain A will "un-escrow" 100 ATOM tokens, thus, the prefix will be removed. Chain B will burn transfer/channel-40/atoms.

IBC Token Transfer | Developer Portal (9)

The prefix determines the source chain. If the module sends the token from another channel, chain B is the source chain and chain A mints new tokens with a prefix instead of un-escrowing ATOM tokens. You can have different channels between two chains, but you cannot transfer the same token across different channels back and forth. If {denom} contains /, then it must also follow the ICS-20 form, which indicates that this token has a multi-hop record. This requires that the character / is prohibited in non-IBC token denomination names.

IBC Token Transfer | Developer Portal (10)

You already know that an application needs to implement the IBC Module Interface (opens new window), so have a look at the implementation for the token transfer (opens new window), e.g. for OnChanOpenInit:

Copy // OnChanOpenInit implements the IBCModule interfacefunc (im IBCModule) OnChanOpenInit( ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID string, channelID string, chanCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, version string,) error { if err := ValidateTransferChannelParams(ctx, im.keeper, order, portID, channelID); err != nil { return err } if version != types.Version { return sdkerrors.Wrapf(types.ErrInvalidVersion, "got %s, expected %s", version, types.Version) } // Claim channel capability passed back by IBC module if err := im.keeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { return err } return nil}

OnChanOpenAck, OnChanOpenConfirm, OnChanCloseInit, and OnChanCloseConfirm will do (almost) no checks.

# Transfer packet flow

You have seen an introduction to the application packet flow in the section on channels. This section will analyze this packet flow for the specific case of the transfer module.

# Sending a transfer packet

After a channel is established, the module can start sending and receiving packets.

So where does the module send a token? Take a look at the msg_server.go (opens new window) of the token transfer module:

Copy // Transfer defines an rpc handler method for MsgTransfer.func (k Keeper) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types.MsgTransferResponse, error) { ... if err := k.SendTransfer( ctx, msg.SourcePort, msg.SourceChannel, msg.Token, sender, msg.Receiver, msg.TimeoutHeight, msg.TimeoutTimestamp, ); err != nil { return nil, err } ...}

There you see SendTransfer, which implements the application logic after checking if the sender is a source or sink chain (opens new window):

Copy func (k Keeper) SendTransfer( ctx sdk.Context, sourcePort, sourceChannel string, token sdk.Coin, sender sdk.AccAddress, receiver string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64,) { ... // deconstruct the token denomination into the denomination trace info // to determine if the sender is the source chain if strings.HasPrefix(token.Denom, "ibc/") { fullDenomPath, err = k.DenomPathFromHash(ctx, token.Denom) if err != nil { return err } } ... // NOTE: SendTransfer simply sends the denomination as it exists on its own // chain inside the packet data. The receiving chain will perform denom // prefixing as necessary. if types.SenderChainIsSource(sourcePort, sourceChannel, fullDenomPath) { ... // create the escrow address for the tokens escrowAddress := types.GetEscrowAddress(sourcePort, sourceChannel) // escrow source tokens. It fails if balance insufficient. if err := k.bankKeeper.SendCoins(...) { } else { ... if err := k.bankKeeper.SendCoinsFromAccountToModule(...); ... if err := k.bankKeeper.BurnCoins(...); ... } packetData := types.NewFungibleTokenPacketData( fullDenomPath, token.Amount.String(), sender.String(), receiver, ) ... }}

Take a look at the type definition of a token packet (opens new window) before diving further into the code:

Copy syntax = "proto3";package ibc.applications.transfer.v2;option go_package = "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types";// FungibleTokenPacketData defines a struct for the packet payload// See FungibleTokenPacketData spec:// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structuresmessage FungibleTokenPacketData { // the token denomination to be transferred string denom = 1; // the token amount to be transferred string amount = 2; // the sender address string sender = 3; // the recipient address on the destination chain string receiver = 4; // optional memo string memo = 5;}

IBC Token Transfer | Developer Portal (11)

An optional memo field was recently added to the packet definition. More details on the motivation, use cases, and consequences can be found in the accompanying blog post (opens new window).

# Receiving a transfer packet

A relayer will then pick up the SendPacket event and submit a MsgRecvPacket on the destination chain.

This will trigger an OnRecvPacket callback that will decode a packet and apply the transfer token application logic:

Copy // OnRecvPacket implements the IBCModule interface. A successful acknowledgement// is returned if the packet data is successfully decoded and the receive application// logic returns without error.func (im IBCModule) OnRecvPacket( ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress,) ibcexported.Acknowledgement { ack := channeltypes.NewResultAcknowledgement([]byte{byte(1)}) var data types.FungibleTokenPacketData var ackErr error if err := types.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { ackErr = sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "cannot unmarshal ICS-20 transfer packet data") ack = channeltypes.NewErrorAcknowledgement(ackErr) } // only attempt the application logic if the packet data // was successfully decoded if ack.Success() { err := im.keeper.OnRecvPacket(ctx, packet, data) if err != nil { ack = channeltypes.NewErrorAcknowledgement(err) ackErr = err } } eventAttributes := []sdk.Attribute{ sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), sdk.NewAttribute(sdk.AttributeKeySender, data.Sender), sdk.NewAttribute(types.AttributeKeyReceiver, data.Receiver), sdk.NewAttribute(types.AttributeKeyDenom, data.Denom), sdk.NewAttribute(types.AttributeKeyAmount, data.Amount), sdk.NewAttribute(types.AttributeKeyMemo, data.Memo), sdk.NewAttribute(types.AttributeKeyAckSuccess, fmt.Sprintf("%t", ack.Success())), } if ackErr != nil { eventAttributes = append(eventAttributes, sdk.NewAttribute(types.AttributeKeyAckError, ackErr.Error())) } ctx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypePacket, eventAttributes..., ), ) // NOTE: acknowledgement will be written synchronously during IBC handler execution. return ack}

IBC Token Transfer | Developer Portal (12)

Observe in the previous example how we redirect to the module keeper's OnRecvPacket method and are constructing the acknowledgement to be sent back.

# Acknowledging or timing out packets

A useful exercise is to try to find and analyze the code corresponding to this. The place to start is the packet callbacks, usually defined in a file like module_ibc.go or ibc_module.go.

IBC Token Transfer | Developer Portal (13)

When a packet times out, the submission of a MsgTimeout is essential to get the locked funds unlocked again. As an exercise, try to find the code where this is executed.

synopsis

To summarize, this section has explored:

  • How IBC provides a reliable solution to the technical challenge of transferring fungible and non-fungible tokens between two different blockchains, freeing up great potential for cross-chain Decentralized Finance (DeFi) applications.
  • How the process for transferring value differs based on whether or not the IBC tokens are native to the source chain, or whether or not they are being sent on a channel they were previously received on.
IBC Token Transfer | Developer Portal (2024)

FAQs

What is token denom? ›

Denoms are essentially identifiers for tokens on a blockchain, synonymous with terms like 'coin' or 'token'. For an in-depth understanding, refer to the Cosmos SDK's ADR 024: Coin Metadata. A denom in this module always has an owner.

What is IBC transfer crypto? ›

The Inter-Blockchain Communication Protocol (IBC) is a protocol to handle authentication and transport of data between two blockchains. IBC requires a minimal set of functions, specified in the interchain standards (ICS) .

What is the IBC protocol for blockchain? ›

The IBC protocol revolutionizes how different blockchains communicate, offering a seamless transfer of data between them. The IBC protocol works in two layers: the TAO layer, which stands for transport, authentication and ordering; and the APP layer, an abbreviation of application.

How to IBC transfer KEPLr? ›

Within your Keplr wallet extension, select [Cosmos] in the top drop-down menu. With the Cosmos network selected, scroll down to IBC Transfer and click on [Transfer]. In the Destination Chain field, click on [Select Chain] and then [New IBC Transfer Channel].

What is the difference between token and tokenization? ›

A token is a collection of characters that has semantic meaning for a model. Tokenization is the process of converting the words in your prompt into tokens. You can monitor foundation model token usage in a project on the Environments page on the Resource usage tab.

How do token transactions work? ›

Payment tokenization is the process by which sensitive personal information is replaced with a surrogate value — a token. That replaced value is stored in a PCI-compliant token vault owned by the token creator, which can be an entity such as an acquirer, issuer, network or payment processor.

How do I make a transfer with IBC? ›

Learn how to transfer funds using your IBC Bank mobile app.

First, go to the home screen and click "Transfers." Select the account you'll be transferring "from" and the account you'll be transferring "to." Then, enter the total amount and click "Save." After that, click "Transfer Funds" and you are all set!

How long do IBC transfers take? ›

Wire transfers provide same or next day availability of funds domestically and internationally.

Is IBC a bridge? ›

IBC requires that the start and destination chains achieve settlement finality; therefore, it connects to POW chains by creating Peg-Zones - this bridges the gap and enables POW blockchains like Bitcoin, which lack settlement finality ( not probabilistic finality), to interoperate with the cosmos blockchain.

What does IBC allow you to do in crypto? ›

The Inter-Blockchain Communication Protocol (IBC) is an open-source protocol to handle authentication and transport of data between blockchains. IBC allows heterogeneous chains to trustlessly communicate with each other to exchange data, messages, and tokens.

Does polkadot use IBC? ›

For example, when chains A and B want to talk to one another, chain A uses its light client of B to verify messages sent from chain B, and vice versa. IBC is currently live on Polkadot and Kusama.

What does IBC transfer mean? ›

The Inter-Blockchain Communication (IBC) open in new window protocol is enabled on Regen Mainnet meaning token holders can transfer tokens between Regen Mainnet and other IBC enabled blockchains.

What does IBC mean on Keplr wallet? ›

Connect to Multiple Blockchains: Keplr's support for the Inter-Blockchain Communication (IBC) protocol means users can connect to and interact with a variety of blockchains that are part of the Cosmos network, broadening their reach in the crypto market.

How to send atom ibc? ›

  1. Connect your Ledger device, unlock it, and open the Cosmos app.
  2. Open the Keplr extension and click on Send.
  3. Choose which crypto asset you'd like to send.
  4. Select IBC Send.
  5. Choose which blockchain you want to send the cryptocurrency to. ...
  6. Enter the amount you'd like to send. ...
  7. Choose your transaction fee and click on Next.
Feb 1, 2024

What is a token in my bank account? ›

Banking tokens are easy-to-use devices that help authenticate digital banking users. Connected or unconnected, these security tokens meet the multi-factor authentication security requirements for "something you know" and "something you have" very effectively.

What is denom in cosmos? ›

In Cosmos SDK, coins are represented as an object with 2 fields: amount and denom . amount is the number of coins, while denom is the identifier of the coins.

What do you mean by a token? ›

In general, a token is an object that represents something else, such as another object (either physical or virtual), or an abstract concept as, for example, a gift is sometimes referred to as a token of the giver's esteem for the recipient.

What does token payment mean? ›

: a very small payment made upon a debt and intended by the payer merely to acknowledge the existence of the obligation.

Top Articles
Latest Posts
Article information

Author: Arielle Torp

Last Updated:

Views: 6495

Rating: 4 / 5 (41 voted)

Reviews: 80% of readers found this page helpful

Author information

Name: Arielle Torp

Birthday: 1997-09-20

Address: 87313 Erdman Vista, North Dustinborough, WA 37563

Phone: +97216742823598

Job: Central Technology Officer

Hobby: Taekwondo, Macrame, Foreign language learning, Kite flying, Cooking, Skiing, Computer programming

Introduction: My name is Arielle Torp, I am a comfortable, kind, zealous, lovely, jolly, colorful, adventurous person who loves writing and wants to share my knowledge and understanding with you.