The following example will show you how to send an ERC20 Token on C-chain to an Avalanche L1 as an ERC20 token using Interchain Messaging and Foundry. This demo is conducted on a local network run by the CLI, but can be applied to Fuji Testnet and Avalanche Mainnet directly.
All Avalanche Interchain Token Transfer contracts and interfaces implemented in this example implementation are maintained in the avalanche-interchain-token-transfer repository.
If you prefer full end-to-end testing written in Golang for bridging ERC20s, native tokens, or any combination of the two, you can view the test workflows directly in the avalanche-interchain-token-transfer repository.
Deep dives on each template interface can be found here.
Disclaimer: The avalanche-interchain-token-transfer contracts used in this tutorial are under active development and are not yet intended for production deployments. Use at your own risk.
You can run them directly on Github by clicking Code, switching to the Codespaces tab and clicking Create codespace on main. A new window will open that loads the codespace. Afterwards you will see a browser version of VS code with all the dependencies installed. Codespace time out after some time of inactivity, but can be restarted.
For convenience the private key 56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027 of the default airdrop address is stored in the environment variable $PK in .devcontainer/devcontainer.json. Furthermore, the RPC url for the C-Chain local-c and Avalanche L1 created with the name myblockchain on the local network is set in the foundry.toml file.
To get started, create an Avalanche L1 configuration named "myblockchain":
avalanche blockchain create myblockchain
Your Avalanche L1 should have the following things:
Interchain Messaging enabled
CLI should run an AWM Relayer
Upon Avalanche L1 deployment, 100 tokens should be airdropped to the default ewoq address (0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC)
✔ Avalanche L1-EVM✔ Use latest release version✔ Yes✔ YesInstalling subnet-evm-v0.6.6...subnet-evm-v0.6.6 installation successfulcreating genesis for subnet myblockchainEnter your subnet's ChainId. It can be any positive integer.ChainId: 123Select a symbol for your subnet's native tokenToken symbol: NAT✔ Low disk use / Low Throughput 1.5 mil gas/s (C-Chain's setting)✔ Airdrop 1 million tokens to the default ewoq address (do not use in production)prefunding address 0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC with balance 1000000000000000000000000✔ No✓ Successfully created subnet configuration
Finally, deploy your Avalanche L1:
avalanche subnet deploy myblockchain
? Choose a network for the operation:✔ Local NetworkDeploying [myblockchain] to Local Network
The CLI will output addresses and information that will be important for the rest of the tutorial:
Deploying Blockchain. Wait until network acknowledges...Teleporter Messenger successfully deployed to c-chain (0x253b2784c75e510dD0fF1da844684a1aC0aa5fcf)Interchain Messaging Registry successfully deployed to c-chain (0x17aB05351fC94a1a67Bf3f56DdbB941aE6c63E25)Teleporter Messenger successfully deployed to myblockchain (0x253b2784c75e510dD0fF1da844684a1aC0aa5fcf)Interchain Messaging Registry successfully deployed to myblockchain (0x73b1dB7E9923c9d8fd643ff381e74dd9618EA1a5)using awm-relayer version (v1.3.3)Installing AWM-Relayer v1.3.3Executing AWM-Relayer...<lots of node information...>Browser Extension connection details (any node URL from above works):RPC URL: http://127.0.0.1:9650/ext/bc/2u9Hu7Noja3Z1kbZyrztTMZcDeqb6acwyPyqP4BbVDjoT8ZaYc/rpcCodespace RPC URL: https://organic-palm-tree-ppr5xxg7xvv2974r-9650.app.github.dev/ext/bc/2u9Hu7Noja3Z1kbZyrztTMZcDeqb6acwyPyqP4BbVDjoT8ZaYc/rpcFunded address: 0x69AD03393144008463beD1DcB3FD33eb9A7081ba with 600 (10^18)Funded address: 0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC with 1000000 (10^18) - private key: 56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027Network name: myblockchainChain ID: 123Currency Symbol: NAT
From this output, take note of the Funded Address (with 100 tokens) and set the parameter as environment variable so that we can manage them easily and also use them in the commands later.
First step is to deploy the ERC20 contract. We are using OZs example contract here and the contract is renamed to ERC20.sol for convenience. You can use any other pre deployed ERC20 contract or change the names according to your Avalanche L1 native token as well.
We will deploy two Interchain Token Transfer contracts. One of the source chain (which is C-chain in our case) and another on the destination chain (myblockchain in our case). This will be done by a single command with the Avalanche CLI
avalanche interchain tokenTransferrer deploy
Go
✔ Local Network✔ C-Chain✔ Deploy a new Home for the token✔ An ERC-20 tokenEnter the address of the ERC-20 Token: 0x5DB9A7629912EBF95876228C24A848de0bfB43A9✔ Avalanche L1 myblockchainDownloading Avalanche InterChain Token Transfer ContractsCompiling Avalanche InterChain Token TransferHome Deployed to http://127.0.0.1:9650/ext/bc/C/rpcHome Address: 0x4Ac1d98D9cEF99EC6546dEd4Bd550b0b287aaD6DRemote Deployed to http://127.0.0.1:9650/ext/bc/2u9Hu7Noja3Z1kbZyrztTMZcDeqb6acwyPyqP4BbVDjoT8ZaYc/rpcRemote Address: 0x0D189a705c1FFe77F1bF3ee834931b6b9B356c05
Save the Remote contract address in the environment variables.
Now that the Avalanche Interchain Token Transfer contracts have been deployed, transfer some ERC20 tokens TOK from C-Chain to myblockchain with the following command
avalanche key transfer
✔ Local Network✔ C-Chain✔ Avalanche L1 myblockchainEnter the address of the Token Transferrer on c-chain: 0x4Ac1d98D9cEF99EC6546dEd4Bd550b0b287aaD6DEnter the address of the Token Transferrer on myblockchain: 0x0D189a705c1FFe77F1bF3ee834931b6b9B356c05✔ ewoq✔ Key✔ ewoqAmount to send (TOKEN units): 100