***IBC Token Transfer for dummies*** Transferring tokens between chains is a common requirement and a challenge when dealing with two incompatible chains. So let's take a look at a solution to this problem: fungible token transfer with IBC. ICS-20 is an IBC protocol by which we will achieve this. We are going to have two chains and a channel that connects them. ![](https://hackmd.io/_uploads/rJ0bzmJea.png) First we have to determine what the source chain is. ![](https://hackmd.io/_uploads/rJlEMXkgp.png) Then the application logic can be summarized: ![](https://hackmd.io/_uploads/rkAPGQklT.png) Shortly you will see the corresponding code. Now again have a look at a transfer from source to sink: ![](https://hackmd.io/_uploads/SkMqM71gp.png) Above the source is chain A. The source channel is channel-2 and the destination channel is channel-40. The ICS 20 token denominations are represented by the form {ics20Port}/{ics20Channel}/{denom}, where ics20Port and ics20Channel are an ICS 20 port and channel on the current chain for which the funds exist. As tokens are sent across chains using the ICS 20 protocol, they begin to accrue a record of channels for which they have been transferred across. This information is encoded into the denom field. The way the reference ICS 20 implementation in ibc-go handles this is by taking advantage of the fact that it automatically generates channel identifiers with the format channel-{n}, where n is a integer greater or equal than 0. It can then correctly parse out the IBC trace information from the base denom which may have slashes, but will not have a substring of the form {transfer-port-name}/channel-{n}. If this assumption is broken, the trace information will be parsed incorrectly (i.e. part of the base denom will be misinterpreted as trace information). Thus chains must make sure that base denominations do not have the ability to create arbitrary prefixes that can mock the ICS 20 logic. You see transfer/channel-... because the transfer module will bind to a port, which is named transfer. Both machines A and B accept new channels from any module on another machine, if and only if: The channel being created is unordered. The version string is ics20-1. When source/port is equal, reverse direction transfer. When source/port are not equal, forward direction transfer. ***Sending a transfer packet*** After a channel is established, the module can start sending and receiving packets. A sending chain may be acting as a source or sink zone. When a chain is sending tokens across a port and channel which are not equal to the last prefixed port and channel pair, it is acting as a source zone. When tokens are sent from a source zone, the destination port and channel will be prefixed onto the denomination (once the tokens are received) adding another hop to a tokens record. When a chain is sending tokens across a port and channel which are equal to the last prefixed port and channel pair, it is acting as a sink zone. When tokens are sent from a sink zone, the last prefixed port and channel pair on the denomination is removed (once the tokens are received), undoing the last hop in the tokens record. In plain English, between chains A and B: When acting as the source zone, the bridge module escrows an existing local asset denomination on the sending chain and mints vouchers on the receiving chain. When acting as the sink zone, the bridge module burns local vouchers on the sending chains and unescrows the local asset denomination on the receiving chain. When a packet times-out, local assets are unescrowed back to the sender or vouchers minted back to the sender appropriately. Acknowledgement data is used to handle failures, such as invalid denominations or invalid destination accounts. Returning an acknowledgement of failure is preferable to aborting the transaction since it more easily enables the sending chain to take appropriate action based on the nature of the failure. ***How can we improve the signing process?*** *What is the memo field and how does it work?* The recent improvements made to ICS-20 token transfers introduces an optional memofield in the FungibleTokenPacketData struct. This allows for arbitrary data to be passed in as a string along with token transfers. For instance, information such as user action/call-data, number of decimal places, denomination (denom), ticker symbol, and logo can be indicated within the memo field. If a user today wants to send ATOM from the Cosmos Hub to Osmosis, and then provide liquidity to a pool (or execute other actions such as swap/stake/post tokens as collateral), they have to sign and approve two different transactions — one to send ATOM to Osmosis and then another to add liquidity. This UX can be considerably improved if the user can send tokens and specify what to do with them on the destination, all in one action. The newly introduced memo field provides the infrastructure to make this possible. A user will soon be able to send tokens and take some action programmatically (swap, stake, provide liquidity, etc.), effectively allowing multiple transactions to be bundled into one. ***Conclusion:*** We could use a merkle tree or polynomial commitments to send several transactions in a single packet using ics-20, and therefore we would carry out a single transaction, in turn with memo field we could save processes that are carried out after the transactions, so we would not only save the signatures of all the transactions, but also the signatures of the following processes. If we have n transactions, using memo we would save 2n signatures. An example package is a circuit of a merkle tree, so that it is easy to test using gnark, and each leaf is a transaction, or perhaps even another merkle tree. We can also use polynomial commitments and Semacaulk. Our input will be the channels and the tokens that we want to send, and we should combine all those tokens in a single operation. ***Sources:*** https://tutorials.cosmos.network/academy/3-ibc/7-token-transfer.html https://github.com/cosmos/ibc/tree/main/spec/app/ics-020-fungible-token-transfer https://medium.com/the-interchain-foundation/moving-beyond-simple-token-transfers-d42b2b1dc29b