ICS20: Fungible Token Transfer
The ICS20 (opens in a new tab) protocol defines a standard for transferring fungible tokens between two chains using IBC. It is one of the most widely used IBC protocols and is supported by pretty much all chains in the Cosmos.
To initiate an ICS20 transfer from inside a contract, you need to attach an IbcMsg::Transfer
message to your contract response like this:
// construct the transfer message
let msg = IbcMsg::Transfer {
channel_id: "channel-0".to_string(),
to_address: "cosmos1exampleaddress".to_string(),
amount: Coin::new(123u128, "ucoin"),
timeout: env.block.time.plus_seconds(60).into(),
memo: None,
};
// attach the message and return the response
Ok(Response::new().add_message(msg))
Sending this message causes an IBC transfer of the given amount
from your contract to the
destination chain at the other end of the given channel.
The channel_id
is the identifier of the channel you want to use for the transfer. Which channel
that should be depends on the source and destination chain. You can find out the correct channel ID
using a block explorer (opens in a new tab).
The to_address
is the address on the destination chain that should receive the tokens.
The amount
is the number and denomination of tokens to send. On the destination chain, the same
amount will be received, but the denomination will be of the form ibc/HASH
, where HASH
is a
SHA256 hash uniquely identifying the channel and the source chain denomination. To learn more about
this, take a look at the Cosmos Developer Portal (opens in a new tab).
The timeout
can either be a timestamp or a block height, as measured on the destination chain. It
is used to prevent the transfer from being stuck in limbo if the destination chain does not receive
the packet.
The memo
is an optional field that can be used to attach a message to the transfer. It is often
used for additional functionality like packet-forward-middleware (opens in a new tab) or
IBC Callbacks.