Financial Information Platform

How to program/create your own ERC20 token

1 2

Programming and creating an ERC-20 token is relatively easy, thanks to the fact that the standard is designed to make life easier for developers. ERC-20 tokens are smart contracts programmed on the Solidity language that run on the Ethereum blockchain. Thus, although some notions of programming are necessary, the infrastructure is designed so that the maximum number of people possible can access and create tokens. In fact, there are currently about 5,00,000 different ERC-20 tokens.

How to program and create ERC-20 token step by step Remix

One of the advantages of the Solidity programming language is that it allows programming without installing any program on the computer. Thus, to write the code of our token we will use the Remix web interface . An Ethereum development environment that allows building and deploying smart contracts in a virtual machine. Once we have accessed Remix, we select the option to create a new folder and a new file. We put a name and we can start writing the contract.

 

Compiler Version

 

The first thing to do is select the compiler version. A kind of translator that converts high-level language into machine language. In Remix we can find the compiler information by clicking on the second symbol in the left column (Solidity Compiler).

 

 

The version of the compiler that we select does not matter so much. However, it is very important that we specify the version of the compiler that we have selected when writing the contract. Therefore, the first thing we must write in the creation of our token is the specification of the version or a range of versions. In my case, being using version 0.6.10, I will write:

pragma solidity >=0.5.5<0.8.0;

That is, followed by pragma solidity, we write a range where the selected version is found. Also, it is important that when we write each command we close it with a semicolon (;).

Next, we need to specify that we are going to use the ABI v2 version of the encoder, since this second version allows dynamic structs and variables to be passed to functions and returned by functions and emitted by events. This specification must be implemented if we are using a version of the compiler prior to 0.8.0, since from this version, version 2 of the ABI encoder is already included by default. Otherwise, we must write:

experimental pragma ABIEncoderV2;

Likewise, it is also important to indicate the license of use at the beginning of the whole. For this, in the first line of the code we will introduce the following:

// SPDX-License-Identifier: MIT

SafeMath

 

The next step will be to make sure you use safe math operations that throw exceptions in case the result of a calculation is not correct. For this, we define the “SafeMath” library by implementing three operations: addition, subtraction and multiplication. In this way, we avoid problems such as “overflow” or “underflow”, which could lead to possible hacks. These problems occur when arithmetic operations exceed the minimum or maximum sizes of declared variable types. To define the SafeMath library, we must write the following:

library SafeMath{
// The Subtraction
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a – b;
}

// The Sum
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
returnc;
}

// The Multiplication
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}

uint256 c = a * b;
require(c / a == b, “SafeMath: multiplication overflow”);

returnc;
}
}

The 6 key functions

Now we can start writing the functions defined by the ERC20 standard. A set of 6 mandatory functions for the creation of the token and its subsequent integration in marketplaces and crypto wallets. All ERC20 tokens have at least these 6 functions:

  1. totalSupply: This function specifies the total number of token supply. Once this limit is reached, the contract will refuse to create more tokens.
  2. balanceOf: This function is used for the contract to return the number of tokens that a portfolio has.
  3. allowance: Function that checks if a user has enough tokens to send them to another user.
  4. transfer: The function that allows to obtain a number of tokens from the initial supply and give them to a user.
  5. approve: Function that verifies if the contract can send a number of tokens to a user taking into account the total supply of tokens.
  6. transferFrom: This function enables the transfer of tokens between different users.

In addition to this, we will implement 2 additional events. A first event that notifies when a number of tokens passes from a source to a destination and a second event that notifies the approval of the allowance function. 

we start to write

Next, we write these functions in the interface of our token. Here, it should be noted that the text that goes after the two slashes (//) is only used to indicate that it is being done and that it is better understood.

// ERC token interface
interface IERC20{
// The total supply of tokens
function totalsupply() external view returns (uint256);
// Returns the number of tokens in an address
function balanceOf(address account) external view returns (uint256);
// If a user has enough tokens (and returns the number)
function allowance(address owner, address spender) external view returns (uint256);
// Initial supply tokens to a user
function transfer(address recipient, uint256 amount) external returns (bool);
// If the contract can send a number of tokens to a user
function approve(address spender, uint256 amount) external returns (bool);
// Enable token transfer between users
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
// Event number 1
event Transfer(address indexed from, address indexed to, uint256 value);
// Event number 2
event Approval(address indexed owner, address indexed spender, uint256 value);
}

Token Implementation

 

The next step is to implement the functions of the ERC20 token and give it whatever name we want. To start the implementation of the token, we will write the following: contract ERC20Basic is IERC20{

Once this bracket is open, we will start with the implementation. The first thing will be to give our token a name and an acronym with which it will be known, as well as establish the decimals with which we want to work. In this case I have decided to name the token “Blockchain Proof Observatory” , but any name can be entered between these quotes. The same goes for decimals and the acronym.
string public constant name = “Blockchain Test Observatory”;
string public constant symbol =”OBP”;
uint public constant decimals= 2;
Next, we implement the two events and indicate the use of the SafeMath library from the beginning to guarantee the consistency of the token.
event Transfer(address indexed from, address indexed to, uint256 tokens);
event Approval(address indexed owner, address indexed spender, uint256 tokens);
using SafeMath for uint256;

Mapping and constructor

 

The next step is to build two mappings. A first mapping that indicates that each address will correspond to a certain number of tokens, and a second mapping that indicates that each address corresponds to a set of addresses with a quantity in each of them. This second mapping serves to see that although the tokens may have been mined by a single person, they can be distributed among different users and so on.

mapping(address=>uint) balances;
mapping (address => mapping (address => uint)) allowed;
uint256 totalSupply_;
Next you need to define the constructor. The constructor will take the amount of tokens you want to create initially and give them to the original creator of these tokens (us). Furthermore, it defines that the constructor will be the only one that can determine the total number of tokens.
constructor (uint256 initialSupply) public{
    totalSupply_ = initialSupply;
    balances[msg.sender]=totalSupply_;
}

Implementation of the functions

 

The next step is to write the implementation of the 6 functions that we have previously introduced and the logic of each of them. By copying and pasting the following specifications into Remix, we would have finished writing the code for the token.

function totalsupply() public override view returns (uint256){
 return totalSupply_;
}
function increaseTotalSupply(uint newTokensAmount) public {
    totalSupply_+=newTokensAmount;
    balances[msg.sender]+= newTokensAmount;
}
function balanceOf(address tokenOwner) public override view returns (uint256){
    return balances[tokenOwner];
    }
    function allowance(address owner, address delegate) public override view returns (uint256){
        return allowed[owner][delegate];
    }
    function transfer(address recipient, uint256 numTokens) public override returns (bool){
        require(numTokens <=balances[msg.sender]);
        balances[msg.sender]=balances[msg.sender]. sub(numTokens);
        balances[recipient]=balances[recipient].add(numTokens);
        emit Transfer(msg.sender, recipient, numTokens);
        return true;
    }
    function approve(address delegate, uint256 numTokens) public override returns (bool){
        allowed[msg.sender][delegate]=numTokens;
        emit Approval(msg.sender, delegate, numTokens);
        return true;
    }
    function transferFrom(address owner, address buyer, uint256 numTokens) public override 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;
    }
}

Once we have written all the code in Remix, we must make sure that a green tick appears in the compiler part. This green tick is proof that all functions are written correctly. If, on the contrary, it shows us an error, Remix itself tells us where we have that error. The most common errors usually occur due to small mistakes when writing the code.

Deployment

To check that everything works well and try to deploy the token, we must go to the deployment part (deploy) in the left column. Here, under “Account” it will be the main account that receives all the initial tokens. Thus, to check that everything is fine, we must indicate the number of tokens that we want to deploy next to the section where it says “Deploy”, and click on the square to see if everything is fine. If everything is correct, a green tick will appear on the screen below followed by the address where the tokens have been deployed.

Once deployed, in «Deployed Contracts» we can see our token and if we click on the arrow on the left, a drop-down will appear to prove that the functions of our token are correct. For example, if we click on name, the name of our token should appear and in Total Supply the supply of tokens should appear. In addition, in balanceOf we can check how many tokens each of the accounts has. For example, if we copy and paste the starting address, your balance should be the full supply of tokens since we have not made any transactions.

checks

To verify that the transfers work, in transferFrom we include the main address (the first in the Account section) and we try to transfer it by placing in the transfer section the account that is going to receive those tokens (another of the accounts in the “accounts” dropdown) followed by of the number of tokens we want to transfer. If we click on transfer, a green tick should appear in the lower left part indicating that it has been transferred correctly, and in balanceOf, the number of tokens of each of the accounts must have been modified.

Once we have verified that everything works correctly, the token would be programmed and ready to be launched on a public blockchain, such as the BSC or the Polygon network (MATIC). To implement the token in one of these two networks, gas would have to be paid. However, in a future article I will explain how to implement the tokens for free in a test network.

Entire code to copy and paste:

// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0 <0.8.0;
experimental pragma ABIEncoderV2;
library SafeMath{
// The substraction
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a – b;
}
// The sum
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
returnc;
}
// The multiplication
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, “SafeMath: multiplication overflow”);
returnc;
}
}
//Interface ERC token
interface IERC20{
//The total supply of tokens
function totalsupply() external view returns (uint256);
//Returns the number of tokens in an address
function balanceOf(address account) external view returns (uint256);
//A user has enough tokens (and returns the number)
function allowance(address owner, address spender) external view returns (uint256);
//Initial supply tokens to a user
function transfer(address recipient, uint256 amount) external returns (bool);
//If the contract can send a number of tokens to a user
function approve(address spender, uint256 amount) external returns (bool);
//Enables the transfer of tokens between users
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
//Event number 1
event Transfer(address indexed from, address indexed to, uint256 value);
//Event number 2
event Approval(address indexed owner, address indexed spender, uint256 value);
}
//Implementation of ERC20 token functions
contract ERC20Basic is IERC20{
string public constant name = “Blockchain Test Observatory”;
string public constant symbol =”OBP”;
uint public constant decimals= 2;
event Transfer(address indexed from, address indexed to, uint256 tokens);
event Approval(address indexed owner, address indexed spender, uint256 tokens);
using SafeMath for uint256;
mapping(address=>uint) balances;
mapping (address => mapping (address => uint)) allowed;
uint256 totalSupply_;
constructor (uint256 initialSupply) public{
    totalSupply_ = initialSupply;
    balances[msg.sender]=totalSupply_;
}
function totalsupply() public override view returns (uint256){
 return totalSupply_;
}
function increaseTotalSupply(uint newTokensAmount) public {
    totalSupply_+=newTokensAmount;
    balances[msg.sender]+= newTokensAmount;
}
function balanceOf(address tokenOwner) public override view returns (uint256){
    return balances[tokenOwner];
    }
    function allowance(address owner, address delegate) public override view returns (uint256){
        return allowed[owner][delegate];
    }
    function transfer(address recipient, uint256 numTokens) public override returns (bool){
        require(numTokens <=balances[msg.sender]);
        balances[msg.sender]=balances[msg.sender]. sub(numTokens);
        balances[recipient]=balances[recipient].add(numTokens);
        emit Transfer(msg.sender, recipient, numTokens);
        return true;
    }
    function approve(address delegate, uint256 numTokens) public override returns (bool){
        allowed[msg.sender][delegate]=numTokens;
        emit Approval(msg.sender, delegate, numTokens);
        return true;
    }
    function transferFrom(address owner, address buyer, uint256 numTokens) public override 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;
    }
}

 

 

Equation and Calculation from the Ethereum Blockchain Network.

1 Comment
  1. […] is much lower than on the Ethereum blockchain and the process is very similar. In a previous article we saw how to develop your own token in Remix. Now, it is time to bring it to life and that this […]

Leave A Reply

Your email address will not be published.