ERC20 Token Standard
Tags: blockchain, solidity, erc20, token
Published: 2022-01-14 22:00:16

**ERC** stands for Ethereum Request for Comment used to initiate improvement proposals to the Ethereum blockchain in the hope of making them a standard. The ERC20 standard is a common one that is implemented for the creation of fungible tokens on the Ethereum blockchain. Fungible tokens refer to what can be broken down into smaller sub units (like money).

Tokens represent a store of value. The value attached to a token makes it economic viable as a means of exchange or worthless with no value.

## Definition of Terminologies

### Coin
A coin is a native digital asset or cryptocurrency of a blockchain. The Ethereum blockchain has the Ether with a symbol of **ETH** that is used for executing transactions in the blockchain. A coin is different from a token because it is the currency of a blockchain.

### Token
A token is a digital asset or a cryptocurrency that is built on top of an existing blockchain. An example of a token is the DAO or Maker token which is built on the Ethereum blockchain with Solidity smart contract.

#ERC20 Methods 

```solidity

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)
```
##ERC20 Events

```solidity
event Transfer(address indexed _from, address indexed _to, uint256 _value)
event Approval(address indexed _owner, address indexed _spender, uint256 _value)
```
To create a token that is ERC20 standard compliant, your token must implement some core functions from the interface. The core functions that must be implemented from the above list of functions are:

```solidity
totalSupply()
balanceOf(account)
transfer(recipient, amount)
allowance(owner, spender)
approve(spender, amount)
transferFrom(sender, recipient, amount)
```
These are the functions which must be implemented by your token so as to become compliant with the standard.

The optional functions of `name()` , `symbol()` and `decimal()` belong to another standard referred to as **ERC20Detailed** which sets the values of this three functions in the constructor function of the smart contract that creates the token.

`constructor(name, symbol, decimals)`

> The ERC20Detailed standard provides some missing functionality from the ERC20 standard. When creating a token smart contract, it is not unusual to inherit from both two standards.

## State Variables in ERC20 Standard
The following are the state variables described by the standard and their uses.

### balances
This is a mapping that holds the amount of token credited to addresses.

```solidity
  mapping(address => uint256) internal balances;
```

The entry in the `balances` variable is updated when the 
`transferFrom()` or `transfer()`functions are called. The `balances` state variable acts as an account ledger, that details who owns what amount of token.
To retrieve a value from the `balances` mapping, the function `balanceOf()` is called with the address of the account we want to read their balance from. The use of the mapping data structures makes this retrieval to happen in O(1) time, that is constant time.

### allowed
The allowed state variable is defined in the contract as follows:

```solidity
mapping(address => mapping (address => uint256 )) internal allowed;
```

The `allowed` variable contains a mapping with an address as key to another mapping which contains an address mapped to a uint256. (nested mapping )

The allowed variable is used to store the amount of token that a token owner has approved to be spent on their behalf by another account. A token holder X can assign that a certain amount of token N, to another account Y, so that Y is allowed to take the approved N number of tokens from the token balance of X. 

#### totalSupply
The totalSupply variable is defined as follows in a smart contract:

```solidity
uint256 internal _totalSupply();
```

This variable stores the total amount of the token that exist in circulation. The value of this variable is read by the function `totalSupply()`.

## Functions and Methods in the Standard

### transfer
This function as the name specifies is used to transfer tokens from the owner to another address. The standards requires a Transfer event to be emitted on a successful transfer of token. When a transfer of token occurs, the balance of the token holder is reduced by the amount that was transferred while the receiver has it's balance in the balances variable increased by the transferred amount.

**Implementation of the transfer function**

```solidity
function transfer(address _to, uint256 _value) public returns (bool) {
  //check if the person making the transfer have token more or equal to the value being transferred 
  require(_value <= balances[msg.sender]);
 balances[msg.sender] = balances[msg.sender].sub(_value);
 balances[_to] = balances[_to].add(_value);
 emit Transfer (msg.sender, _to, _value );
 return true;
}
```
We are making use of the **Safe Math Library** methods of **add** and **sub** so as to prevent integer overflow or underflow since we are dealing with huge numbers.

> The ERC20 standard **transfer** function should not be confused with the one (transfer function) used by smart contracts to transfer ether to an address.

sample code:

```solidity
    address payable internal toAddress;
    address(toAddress).transfer(msg.value);
```

### approve
This function allows an address (owner) to approve another address (spender) to be able to spend tokens on behalf of the (owner) account. The owner approves a particular ** token amount** that the spender can withdraw on their behalf. This function is necessary to enable a third party to be able to withdraw approved token from an owner's address.

The ERC20 API specifies that the following signature for the approve function

```solidity
 function approve(address _spender, uint256 _amount) external returns (bool success);
```
The `approve` function returns a bool if the approval was successfully executed. An `Approval` event is also emitted on a successful execution.

**Implementation of the approve function**

```solidity
 function approve(address _spender, uint256 _amountApproved) public returns (bool) {
  //remember the allowed state variable is used to store the approvals
 allowed[msg.sender][_spender] = _amountApproved;
 //broadcast to the blockchain about the approval
 emit Approval(msg.sender, _spender, _amountAllowed);
 return true;
}
``` 
### transferFrom 

This function is used by an address to transfer funds from another address with prior approval. The transferFrom function accepts three parameters which are:

* from : account the token is to be transferred from.
* to : account the token will be transferred into.
* amount : amount of token to transfer

Before an address can transfer token from another address, an approval must be given prior to the transfer. This means that the address which the token is transferred from must call the approve function to authorised the transfer of tokens.

**Implementation of transferFrom function**

```solidity
function transferFrom(address _from, address _to, uint256 _amount )  public returns (bool ){
 //first check if the address to transfer from has that much token

require( amount <= balances[_from] );
//check if the address making the transfer has the allowance to do that
required(_amouunt <= allowed[_fromr][msg.sender]);
//prevent the transfer of this token to the grave yard which is the address(0) where nothing is recovered from
require(_to != address(0);
balances[_from] = balances[_from].sub(_amount);
balances[_to] = balances[_to].add(_amount);
//subtract the transfer value from the allowed variable
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_amount);
emit Transfer(_from, _to, _amount);
return true
}
```
> msg.sender here refers to the address making the transfer

### allowance

This function returns the amount of token that an address is allowed to spend on behalf of another address.

```solidity
function allowance(address _owner, address _spender ) public view returns (uint256) {
  returns allowed[_owner][_spender];
}
```

### balanceOf function

This function returns the token balance of the given address. It retrieves the value from the **balances** state variable.

```solidity
 function balanceOf(address _owner) public view returns (uint256) {
   return balances[_owner];
}
```

### totalSupply function

The totalSupply function reads the value of the _totalSupply state variable which holds the total number of token available in circulation. This value is updated when tokens are minted (created) or burn (destroyed)

```solidity
 function totalSupply() public view returns (uint256) {
   return _totalSupply;
}
```
## Events

Two events are defined by the standards which are the Transfer event and the Approval event. These events can be listened to by a client who subscribes to them. Events are used to tell about happenings on the blockchain.

**Signature of the Transfer event**

```solidity
event Transfer(address indexed from, address indexed to, uint256 value);
```

**Signature of the Approval event**

```solidity
event Approval(address indexed owner, address indexed spender, uint256 value);
```
## Summary

The **ERC20** standard provides a way for fungible token to be uniform in their implementation so that they can be easily swapped with one another because if all token implements the same standard, it becomes easy and consistent to interact with them.

The examples given are for the reader to know what is happening underneath the hood. Instead of coding your token from scratch you can use the implementation of OpenZepplin and decide to overide any of the functions for your own implementationor. Their code has been tested, audited and it is being used by many.

```solidity
pragma solidity ^0.5.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Detailed.sol";

contract GLDToken is ERC20, ERC20Detailed {
    constructor(uint256 initialSupply) ERC20Detailed("Gold", "GLD", 18) public {
        _mint(msg.sender, initialSupply);
    }
}

```

The above code does just that by creating a token called `GLDToken`.

I hope I was able to improve your understanding of the ERC20 token standard. Thanks for reading..

Happy coding!