Since Satoshi Nakamoto released Bitcoin in 2009, Blockchain technology has been taking over the world. While Bitcoin is focused on cryptocurrencies, Ethereum - A byproduct of Blockchain, goes a step further by providing a virtual machine and smart contracts that enable users to deploy their tokens, similar to Bitcoin.

A token can represent a virtual currency, voting, a lottery ticket, or a character's skill in a game. There will be a suitable type of token on the Ethereum network, depending on business logic. Up to now, many types of token standards have been deployed. One of the most popular token standards is ERC-20. This document will explain what the ERC-20 standard is and focus on how to use it to deploy a token on the Ethereum network.

What is the ERC token standard?

Ethereum's network, launched in 2015, created a lot of attention in the developer community and sprouted a lot of tokens on the network. However, there weren't any templates or guidelines for token development initially. That resulted in a variety of tokens quite different from each other and has made it difficult to program, communicate and exchange tokens. For that reason, the community has set the world standard in token creation. These standards came to be known as Ethereum Request for Comment (ERC) standards. ERCs aim to establish conventions that make it easier for applications and contracts to interact with each other.

What is the ERC-20 standard?

“The ERC-20 introduces a standard for Fungible Tokens. In other words, they have a property that makes each Token be exactly the same (in type and value) of another Token.” [1]

ERC-20 token standard requires to include six mandatory functions:

  • totalSupply: A method that returns the total supply of your tokens that currently exist. When this limit is reached, the smart contract will refuse to create new tokens.
  • balanceOf: A method that returns the number of tokens a wallet address has.
  • transfer: A method that transfers the number of tokens from the total supply to a wallet.
  • transferFrom: A method that transfers the number of tokens between wallets.
  • approve: Given a recipient address and amount authorizes that address to execute several transfers up to that amount from the account that issued the approval.
  • allowance: Given an owner address and a spender address, returns the remaining amount that the spender is approved to withdraw from the owner.

And three optional ones:

  • name: Human-readable name of the Token.
  • symbol: Human-readable symbol of your Token.
  • decimals: How dividable your Token is. For example, if decimals are 2, then the token amount is divided by 100 to get its user representation.

Deploy an ERC-20 token on the Ethereum network

Preparation

  1. In this tutorial, we use:
  • Ubuntu 18.04 OS
  • NodeJS v16.14.0 and NPM v8.3.1
  • Truffle v5.3.11
  • MetaMask Extension on Chrome

2. Installation

If your computer does not have NodeJS installed, you can download them from this link or run the below commands from your Terminal.

$ curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash

The script will add the NodeSource signing key to your system, create an apt repository file, install all necessary packages, and refresh the apt - cache.

Once the NodeSource repository is enabled, install Node.js and npm:

$ sudo apt install nodejs

The nodes package contains both the Node and NPM binaries.

Verify that the Node.js and NPM were successfully installed by printing their versions:

$ node --version

Output
v16.14.0 

$ npm --version

Output
v8.3.1

To be able to compile native addons from npm, you’ll need to install the development tools:

 $ sudo apt install build-essential

After your computer has installed NPM, you can install Truffle. This is a development environment, testing framework, and asset pipeline for blockchains using the Ethereum Virtual Machine (EVM). We’ll use Truffle to compile and deploy smart contract scripts. Execute the below command to install Truffle:

 $ npm install -g [email protected]

 $ npm install @truffle/[email protected]

Verify that Truffle was successfully installed by printing their versions:

$ truffle --version

Output
Truffle v5.3.11 - a development framework for Ethereum

3. Script

  • Execute the below command from your Terminal to initialize your project
$ truffle init
  • Following directory structure and edit each file
ERC20/
+------ contracts
|	`------ Augenstern.sol
+------ migrations
|	`------ 1_initial_augenstern.js
+--------package.json
+--------package-lock.json
+--------truffle-config.js

ERC20/contracts/Augenstern.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.3;

contract Arrebol {
   string public constant name = "Augenstern";
   string public constant symbol = "AUG";
   uint8 public constant decimals = 2; 
   event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
   event Transfer(address indexed from, address indexed to, uint tokens);
   mapping(address => uint256) balances;
   mapping(address => mapping (address => uint256)) allowed;
   uint256 totalSupply_;

   using SafeMath for uint256;
   constructor(uint256 total) { 
       totalSupply_ = total;
       balances[msg.sender] = totalSupply_;
   } 
   function totalSupply() public view returns (uint256) {
   	return totalSupply_;
   }
   function balanceOf(address tokenOwner) public view returns (uint){
       return balances[tokenOwner];
   }
   function transfer(address receiver, uint numTokens) public returns    (bool) {
       require(numTokens <= balances[msg.sender]);
       balances[msg.sender] = balances[msg.sender].sub(numTokens);
       balances[receiver] = balances[receiver].add(numTokens);
       emit Transfer(msg.sender, receiver, numTokens);
       return true;
   }
   function approve(address delegate, uint numTokens) public returns (bool) {
       allowed[msg.sender][delegate] = numTokens;
       emit Approval(msg.sender, delegate, numTokens);
       return true;
   }
   function allowance(address owner, address delegate) public view returns (uint) {
       return allowed[owner][delegate];
   }
   function transferFrom(address owner, address buyer, uint numTokens) public returns (bool) {
       require(numTokens <= balances[owner]);   
       require(numTokens <= allowed[owner][msg.sender]);
       balances[owner] = balances[owner].sub(numTokens);
       allowed[owner][msg.sender] = allowed[owner][msg.sender].sub(numTokens);
       balances[buyer] = balances[buyer].add(numTokens);
       emit Transfer(owner, buyer, numTokens);
       return true;
   }
}
library SafeMath {
   function sub(uint256 a, uint256 b) internal pure returns (uint256) {
     assert(b <= a);
     return a - b;
   }
   function add(uint256 a, uint256 b) internal pure returns (uint256) {
     uint256 c = a + b;
     assert(c >= a);
     return c;
   }
}


ERC20/migrations/1_initial_augenstern.sol

const Augenstern = artifacts.require("Augenstern")
module.exports = function (deployer) {
 deployer.deploy(Augenstern);
};


ERC20/truffle-config.js

const HDWalletProvider = require('@truffle/hdwallet-provider');
const mnemonic = 'your-mnemonic'

module.exports = {
 networks: {
   rinkeby: {
     provider: () => new HDWalletProvider(
       mnemonic, 'https://rinkeby.infura.io/v3/7f36cec5929045f89cd70f17e5995c7f'),
     network_id: 4,
     confirmations: 0,
     timeoutBlocks: 200,
     skipDryRun: true
   }
 },
 mocha: {},
 compilers: {
   solc: {
     version: "0.8.3"
   }
 },
 db: {
   enabled: false
 }
};

4. Deploy to network

To deploy the smart contract to the Ethereum network, we execute the below command

$ truffle migrate --network rinkeby

If everything goes right, you’ll get a contract address like this

0xa58e2E3492d160EC200306E98a8C455709953dBe

Check out the Rinkeby network’s explorer to ensure your contract is created successfully. In my case, accessing this link will show information like this:

Etherscan interface of creating the contract
Creating contract. Source: etherscan.io
Ehterscan interface of creating the contract
Creating Contract. Source: etherscan.io

5. Test

Select Import Tokens from MetaMask Extension on Chrome and paste your contract address into the Token Contract Address’s input field. Then, click Add Custom Token to import your ERC-20 token.

Metamask interface when inporting tokens

Your token has been added to the wallet; it will be available under the assets section in Metamask.

Metamask interface

My wallet owns 100 AUG because my smart contract has a constructor that initializes my address's balance to equal the total supply of my token.

Conclusion

The ERC-20 is a standard for Fungible Tokens. With this standard, you can deploy your own token, which can be exchanged with others. In addition to the ERC-20 standard, there are many other types of tokens standard like ERC-721, ERC-1155,... Subscribe to our TechFi for more articles and guilds on Ethereum.

References

[1] ERC-20 Token Standard, ethereum.org, accessed April 12th, 2022.

[2] How does Ethereum work, preethikasireddy.com, accessed April 12th, 2022.