ERC20 Transfers
Fungibility Everywhere!
Step 1: Create a basic ERC20 contract using the OpenZeppelin library
The first step in creating a cross-chain ERC20 contract is to create a basic ERC20 contract using the OpenZeppelin library. This library provides a set of reusable smart contracts for the Ethereum blockchain that are secure and tested.
To create a new ERC20 contract, you will first need to install the OpenZeppelin library by adding it as a dependency in your project. You can do this using a package manager like npm by running the following command:
Once the library is installed, you can import the ERC20
contract from the OpenZeppelin library and use it as the base for your new contract. Here is an example of how you can create a new MyToken
contract that inherits from the ERC20
contract:
In this example, the MyToken
contract inherits from the ERC20
contract provided by the OpenZeppelin library. The constructor
function is used to initialize the contract with the name "My Token" and symbol "MT".
And this is the basic ERC20 contract ready to use
In the next step, I'll guide you on how to add cross-chain transfer functionalities.
Step 2: Add the cross-chain transfer functionality
Now that you have a basic ERC20 contract, you can add the necessary functions to perform cross-chain transfers.
The first thing you need to do is to set the bridgeAddress
variable to the address of the deployed bridge contract and define an interface with the outboundMessage
function of the bridge contract.
The next step is to add the bridgeTransfer
function that will be used to transfer tokens to a recipient address on another chain. This function will be payable and should call the outboundMessage
function in the bridge contract.
The bridgeTransfer
function has three parameters:
recepient
is the address of the recipientamount
is the amount of tokens to be transferredendChain
is the string that represent the end chain which the tokens should be transferred
It starts by checking that the msg.value passed is the same as the value of tokens to be transferred and that the contract has enough tokens to be able to transfer. Then it calls the outbound message function of the bridge contract passing the recipient address and the value of the tokens being transferred and the endChain. It burns the transferred tokens and emits a transfer event.
It is important to note that the _burn
function should be implemented in your contract to properly reduce the total supply of tokens and update the balance of the sender.
You'll also need to make sure that this function is protected and can only be called by the owner or an authorized address, in order to prevent malicious actors from making unauthorized transfers.
You can now test your contract by calling the bridgeTransfer
function and passing the correct parameters to transfer tokens to another chain. You should see the balance of the sender decrease and the Transfer
event being emitted after the successful transfer.
Step 3: Listen for incoming cross-chain messages
In order to handle incoming cross-chain transfers, you need to add a function that will listen for incoming messages from the bridge contract. This function is called portMessage
The portMessage
function will be called by the bridge contract and should handle the transfer of tokens from another chain to this contract by minting the recieved tokens.
Here's an example of how the portMessage
function can be implemented:
As you can see, I added a onlyBridge
modifier to the portMessage
function. This modifier will check that the contract calling the function is the same as the bridgeAddress
that you've set. The function then continues as before. It check that the arrays are not empty and it mints the tokens by calling the _mint
internal function. Finally it emits a Transfer
event to notify any other contract of the transfer and a fun event to let everyone know that the minting has happened.
It is important to note that the bridgeAddress
variable should be set in the constructor or in a separated function that can only be called by the owner.
Adding this security measure ensures that only verified and expected cross-chain messages are processed, so you don't have to worry about some shady characters trying to sneak in unwanted token transfers. So far, your ERC20 token contract should have the following features:
Implemented the OpenZeppelin ERC20 library
A
bridgeTransfer
function which is payable, takes in 3 parameters (recipient
address,amount
uint,endChain
string), it calls the outBound message function in the bridge contract.A
bridgeAddress
variable that is set by the contract's ownerA
portMessage
function that has the correct parameter (_addressData
address[],_numberData
uint256[],_stringData
string[],_boolData
bool[]), this function should be protected by a onlyBridge modifier which only allows the bridge contract to call it. This function mints the token being transferred, emits a Transfer event and a custom event.a
_mint
internal function that should be implemented by the developerA constructor that sets the bridgeAddress
Here's what the full contract could look like:
Last updated