# IBC Token Transfer
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.
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.
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:
Then the application logic can be summarized:
Shortly you will see the corresponding code. Now again have a look at a transfer from source to sink:
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}
. 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 transfer/channel-40/atoms. The channel-id will be increased sequentially per channel on a given connection.
If the tokens are sent back from the same channel as they were received:
Chain A will "un-escrow" 100 ATOM tokens, thus, the prefix will be removed. Chain B will burn transfer/channel-40/atoms.
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.
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
:
OnChanOpenAck
, OnChanOpenConfirm
, OnChanCloseInit
, and OnChanCloseConfirm
will do (almost) no checks.
After a channel is established, the module can start sending and receiving packets. OnRecvPacket
will decode a packet and apply the transfer token application logic:
Take a look at the type definition of a token packet (opens new window) before diving further into the code:
So where does the module send a token? Take a look at the msg_serve.go (opens new window) of the token transfer module:
There you see SendTransfer
, which implements the application logic after checking if the sender is a source or sink chain (opens new window):
# Next up
In the next section, discover how you can control an account on a host chain from a controller chain using interchain accounts (ICAs).