Deploying an ERC20 on Testnet
Linea is a network that scales the experience of Ethereum. Its out-of-the-box compatibility with the Ethereum Virtual Machine enables the deployment of already-existing applications, as well as the creation of new ones that would be too costly on Mainnet. It also enables the community to use those dapps, at a fraction of the cost, and at multiples the speed of Mainnet.
Introduction to ERC20 Tokens
ERC20 stands for Ethereum Request for Comment 20 and represents a standard interface for token contracts on the Ethereum blockchain. It has become the de facto standard for Ethereum tokens, allowing for interoperability between various applications and contracts. These tokens can represent anything from loyalty points to assets and even other cryptocurrencies.
Gateway into Blockchain
If you are completely new to blockchain, then we'll first need some tools to let us in the door. MetaMask is a swiss-army knife designed for the digital ecosystem.
-
Creating a Wallet
Download MetaMask
ORIf you already have a wallet, then we'll need to connect to the Linea testnet.
ChainList is an open-source tool created by the Founder of DeFi Lama. Think of this as a Web3 directory for you to look up EVM networks.
-
Funding your Wallet
Because we will be interacting with a blockchain, we will need some ETH in order to pay for our transactions. There are a couple of different ways to fund a wallet, but I will be touching on 2 of the simpliest.
Infura is a Web3 infrastructure provider and they have built a platform to give users ETH, otherwise known as a faucet
Additionally, Consensys has built a canonical bridge for existing Web3 users to transfer their ERC20s into Linea.
-
Setting Up the Environment
Because I'm on a Windows machine, I will be using VS Code and Truffle. Truffle is a world class development environment, testing framework and asset pipeline for blockchains using the EVM to make life easier as a developer.
Here is a quick startup guide on how to install Truffle on your device.
Creating an ERC20 Smart Contract
For a Smart Contract to be considered an ERC-20 Token Contract, then it is required to implement the following methods and events. Once deployed, it will be responsible to keep track of the created tokens on Ethereum or any EVM chain.
-
Methods:
function name() public view returns (string) function symbol() public view returns (string) function decimals() public view returns (uint8) function totalSupply() public view returns (uint256) function balanceOf(address _owner) public view returns (uint256 balance) function transfer(address _to, uint256 _value) public returns (bool success) function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) function approve(address _spender, uint256 _value) public returns (bool success) function allowance(address _owner, address _spender) public view returns (uint256 remaining)
-
Events:
event Transfer(address indexed _from, address indexed _to, uint256 _value) event Approval(address indexed _owner, address indexed _spender, uint256 _value)
-
Example Contract
For simplicity's sake, I will not be showing the entire contract but rather a skeleton so you can see the structure of an ERC20 Smart Contract. Below you can see the exact code I wrote for my Token.
contract JulianCoin { string public name = "Julian Coin"; string public symbol = "Juju"; uint8 public decimals = 18; uint256 public totalSupply = 8888 * (10 ** uint256(decimals)); mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); constructor() public { balanceOf[msg.sender] = totalSupply; emit Transfer(address(0), msg.sender, totalSupply); } function transfer(address _to, uint256 _value) public returns (bool success) { require(_to != address(0), "Invalid address"); require(balanceOf[msg.sender] >= _value, "Insufficient balance"); balanceOf[msg.sender] -= _value; balanceOf[_to] += _value; emit Transfer(msg.sender, _to, _value); return true; } function approve(address _spender, uint256 _value) public returns (bool success) { allowance[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; } function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { require(_to != address(0), "Invalid address"); require(balanceOf[_from] >= _value, "Insufficient balance"); require(allowance[_from][msg.sender] >= _value, "Allowance exceeded"); balanceOf[_from] -= _value; balanceOf[_to] += _value; allowance[_from][msg.sender] -= _value; emit Transfer(_from, _to, _value); return true; } }
-
Migration Script
Migrations are ways for developers to automate the deployment of data and its supporting structures. THey are very useful for managing the deployment for new software version. Truffle migrations enable us to push the smart contract to the Ethereum blockchain and to set up necessary steps for linking contracts with other contracts as well as populate contracts with initial data.
You will need to create a1_deploy_token.js
in themigrations
directory and add the following code:const JulianCoin = artifacts.require("JulianCoin"); module.exports = function(deployer) { deployer.deploy(JulianCoin); };
Deploy Your Smart Contract
With Truffle, they have front-end dashboard where we can deploy our Smart Contract using our MetaMask wallet right through our browser!
-
Configure our
truffle-config.js
file like so:require("dotenv").config(); const { MNEMONIC } = process.env; const HDWalletProvider = require("@truffle/hdwallet-provider"); module.exports = { networks: { linea_testnet: { provider: () => { return new HDWalletProvider( MNEMONIC, `https://rpc.goerli.linea.build/`, ); }, network_id: "59140", }, linea_mainnet: { provider: () => { return new HDWalletProvider( MNEMONIC, `https://rpc.linea.build/`, ); }, network_id: "59140", }, }, // ... rest of truffle-config.js };
-
Call
truffle migrate --network linea_testnet
Your output should look similar to the following:
Compiling your contracts... =========================== > Everything is up to date, there is nothing to compile. Starting migrations... ====================== > Network name: 'linea' > Network id: 59140 > Block gas limit: 30000000 (0x1c9c380) 1_deploy_token.js ================= Deploying 'Token' ----------------- > transaction hash: 0x412d58eaf4cc387fe1efa52b105f6fadac36db934b1617d04eaefc1947197525 > Blocks: 0 Seconds: 0 > contract address: 0x33b4D321Fc300E4f402820052EFA0958272D2AE5 > block number: 143419 > block timestamp: 1677366505 > account: YOUR_ACCOUNT_NUMBER > balance: 0.088400819995522296 > gas used: 639672 (0x9c2b8) > gas price: 2.500000007 gwei > value sent: 0 ETH > total cost: 0.001599180004477704 ETH > Saving artifacts ------------------------------------- > Total cost: 0.001599180004477704 ETH Summary ======= > Total deployments: 1 > Final cost: 0.001599180004477704 ETH ``` -->
Wrapping Up
Successfully creating an ERC20 token is a testament to the versatility and innovation within the Ethereum ecosystem. This foundational skill opens doors to numerous applications, from crowdfunding campaigns to decentralized applications and beyond. As the blockchain landscape continues to evolve, the knowledge and expertise in crafting such tokens will undoubtedly remain a prized asset.