HelloERC20
is an example ERC20
token implemented in Solidity, designed for cross-chain operations without relying on traditional bridge mechanisms. Utilizing the VIA Labs package and MessageClient extension, it demonstrates a bridgeless approach to native token minting and burning across different blockchain networks.
- ERC20 Token Implementation: A standard
ERC20
token with additional burnable functionality. - Cross-Chain Functionality: Native support for cross-chain interactions without using a bridge.
- VIA Labs Integration: Leverages the VIA Labs package for seamless cross-chain communication.
- Configurable on Multiple Networks: Can be deployed and configured across various blockchain networks.
Before you begin, ensure you have the following installed:
- Node.js and npm (Node Package Manager)
- A text editor such as VSCode for editing
.sol
and.ts
files - GIT installed
- Testnet Tokens (ethereum sepolia faucet and polygon testnet faucet)
Please visit node documentation link and the git install documentation for more information.
Please open a terminal to run the following commands. You can use any terminal of your choice, including the built in terminal in vscode (Terminal -> New Terminal)
- Clone the Repository:
git clone https://github.com/VIALabs-io/hello-erc20.git
- Open in IDE: After cloning the repository, if using vscode or a similar IDE, you can now open the hello-erc20 in your IDE of choice.
code hello-erc20
- Install Dependencies: In vscode (Terminal -> New Terminal)
npm install
- Set Up Environment Variables:
Create a new
.env
file to set your EVM private key for contract deployment or copy and edit the existing.env.example
to.env
PRIVATE_KEY=0000000000000000000000000000
- Gas tokens: Make sure you have enough gas to complete the contract deployments and a couple test transactions
Deploy the HelloERC20
contract to your desired networks. This must be done for each network you wish to operate on. You can see a list of our networks in the Package documentation
- Ethereum Sepolia:
npx hardhat --network ethereum-sepolia deploy
- Polygon Testnet:
npx hardhat --network polygon-amoy deploy
Edit the networks.ts
file and include all of the networks the contract is deployed on.
[
"ethereum-sepolia",
"polygon-amoy"
]
Once all contracts are deployed across the desired networks and listed in networks.ts
, configure them using the provided script. Remember, if a new network is added later, all contracts must be reconfigured.
- Ethereum Sepolia:
npx hardhat --network ethereum-sepolia configure
- Polygon Testnet:
npx hardhat --network polygon-amoy configure
To check the balance of tokens on a particular chain:
npx hardhat --network ethereum-sepolia get-token-balance
To send tokens to another chain it is required to set the --dest
parameter to the destination chain id. The example below uses the id for the Polygon Testnet. Chain IDs can be looked up in the Package documentation.
npx hardhat --network ethereum-sepolia bridge-token --dest 80002 --amount 50
You can now check the balance on the destination chain. Please give the transaction some time to process. You should see your balance increase on the destination chain:
npx hardhat --network polygon-amoy get-token-balance
This contract is an ERC20
token with additional functionalities for cross-chain operations. It inherits from ERC20Burnable
for standard ERC20
functionality with burn capabilities and from MessageClient
for handling cross-chain messages.
pragma solidity =0.8.17;
import "@vialabs-io/contracts/message/MessageClient.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
contract HelloERC20 is ERC20Burnable, MessageClient {
constructor() ERC20("HelloERC20", "HELLO") {
_mint(msg.sender, 1_000_000 ether);
}
function bridge(uint _destChainId, address _recipient, uint _amount) external onlyActiveChain(_destChainId) {
// burn tokens
_burn(msg.sender, _amount);
// send cross chain message
_sendMessage(_destChainId, abi.encode(_recipient, _amount));
}
function messageProcess(uint, uint _sourceChainId, address _sender, address, uint, bytes calldata _data) external override onlySelf(_sender, _sourceChainId) {
// decode message
(address _recipient, uint _amount) = abi.decode(_data, (address, uint));
// mint tokens
_mint(_recipient, _amount);
}
}
constructor() ERC20("HelloERC20", "HELLO") {
_mint(msg.sender, 1_000_000 ether);
}
- Initializes the token with the name "HelloERC20" and symbol "HELLO".
- Mints 1,000,000 tokens to the address deploying the contract.
function bridge(
uint _destChainId,
address _recipient,
uint _amount
) external onlyActiveChain(_destChainId) {
// burn tokens
_burn(msg.sender, _amount);
// send cross chain message
_sendMessage(_destChainId, abi.encode(_recipient, _amount));
}
- Allows a user to send tokens to another chain.
- Parameters:
_destChainId
: The ID of the destination chain._recipient
: The recipient's address on the destination chain._amount
: The amount of tokens to send.
- Process:
- Burns the specified
_amount
of tokens from the sender's balance. - Encodes the
_recipient
address and_amount
into bytes (_data
). - Calls
_sendMessage
, a function fromMessageClient
, to send this encoded data to the destination chain.
- Burns the specified
- Modifiers:
onlyActiveChain
: A modifier restricts this function to be called only if the destination chain is active.
function messageProcess(
uint,
uint _sourceChainId,
address _sender,
address,
uint,
bytes calldata _data
) external override onlySelf(_sender, _sourceChainId) {
// decode message
(address _recipient, uint _amount) = abi.decode(_data, (address, uint));
// mint tokens
_mint(_recipient, _amount);
}
- Handles incoming messages from other chains.
- Parameters:
_sourceChainId
: The ID of the source chain from where the message is sent._data
: Encoded data containing the recipient's address and the amount.
- Process:
- Decodes
_data
to extract_recipient
and_amount
. - Mints
_amount
of tokens to_recipient
's address on the current chain.
- Decodes
- Modifiers:
onlySelf
: A modifier restricts this function to be called only if the message was sent from the corresponding deployments of this contract on the source chain.