Cross-chain Token Transfer
This article will guide you through a demo on how to achieve a quick cross-chain token transfer using Tusima zkBridge. This demo will involve three contracts: TokenMock.sol
, TokenSender.sol
, and TokenReceiver.sol
. These contracts will utilize the cross-chain communication capabilities provided by Tusima zkBridge's Messaging component to transfer a token from one blockchain to another in a short amount of time.
ℹ️ Notice:
The code presented in this article is intended for illustrating the use of Tusima zkBridge and has not undergone a security audit. Please do not use it in real projects without proper security review.
ℹ️ Notice:
While this demo employs the Foundry framework, you have the flexibility to use any Solidity-compatible framework, such as Hardhat or Truffle, in your real-world development. To learn more about using the Foundry framework, please refer to this link.
Add dependencies
Before we begin, we need to import the interface files provided by Tusima zkBridge:
Additionally, you may need to include the auxiliary code from OpenZeppelin.
Mock Token
In this demo, we will use a simulated Token that includes mint
and burn
functions. Here is the interface part of it, ITokenMock.sol
:TokenMock.sol
is an implementation contract that builds upon ERC20.sol
provided by OpenZeppelin and adds mint
and burn
functions:
The TokenMock.sol
contract will be deployed on both the source and destination chains. On the source chain, the token will be burned, and on the destination chain, it will be minted. Since both functions have Admin
permissions, please remember to set these permissions after deploying all the contracts.
TokenSender
Let’s now implement the TokenSender
contract, which will be deployed on the source chain to provide users with the ability to send tokens.
To achieve this, we must send a message from the source chain to the target chain’s contract. To do this, we need to call the Tusima zkBridge’s Messaging
contract deployed on the corresponding source chain. The address of this contract can be provided as a parameter in the constructor during deployment.
First, let’s import the ISender
interface:
The constructor will include two parameters: the address of the Messaging
contract and the address of the token contract.
Next, we’ll write the sendToken
function, which is defined with four parameters:
_destinationChainId
: The ID of the destination chain._msgReceiver
: The receiving contract on the destination chain._tokenAmount
: The quantity of tokens to be sent._receiver
: The address of the token receiver.
There are three steps using this function:
1.Burn the caller’s Token
2.Package the message
3.Send the message
Here is the full function:
TokenReceiver
The TokenReceiver
will be deployed on the destination chain to receive messages from the source chain, mint tokens, and send them to the recipient's address.
To realize the function of receiving messages, we just need to implement the abstract contract Receiver
provided by Tusima zkBridge.
Let’s start by introducing Receiver.sol
:
Creating a TokenReceiver
contract and inherits the abstract contract Receiver
:
The constructor also takes two parameters, _tusimaMessaging
and _tokenMock
:
The abstract contract Receiver
contains an abstract function handleMsgImpl
which we need to implement and which will be triggered when a message is received.
There are two things we need to do when implementing the handleMsgImpl
function.
- Parsing the message,
- Mint Tokens.
The complete function is as follows:
At this point, all contracts are complete. You can deploy the contracts to any of our supported chains, but please don’t forget to assign the Admin
rights of the TokenMock
contract to the TokenSender
and TokenReceiver
contracts after deployment.