How to Create an ERC20 Token in Solidity
Tags: web3, blockchain, solidity, erc20
Published: 2021-10-29 10:00:23

Let’s start with the basics Understanding:
####What is a Token?
Tokens can represent virtually anything in Ethereum:

* reputation points in an online platform
* skills of a character in a game
* lottery tickets
* financial assets like a share in a company
* a fiat currency like USD
* an ounce of gold
* and many more...

####What is an ERC-20 Token?
ERC stands for Ethereum Request for Comment, and 20 is the proposal identifier number. ERC-20 was designed to improve the ETH network.
An ERC20 token is a blockchain-based asset with similar functionality to bitcoin, ether, and bitcoin cash: it can hold value and be sent and received.
The ERC-20 introduces a standard for Fungible Tokens. In short they have a property that makes each Token be exactly the same type and value of another Token.

#####What makes ERC20 tokens so attractive and successful?

1. ERC20 tokens are simple and easy to deploy, as you will see in this tutorial.
2. It was the first popular specification to offer Ethereum token standardization. It was not by any means the first, but thanks to its popularity, it quickly became the industry standard.

Just like other Ethereum tokens, ERC20 tokens are implemented as smart contracts and executed on the Ethereum Virtual Machine (EVM) in a decentralized manner.

###Creating your own ERC20 Token:
We will use [Solidity](https://github.com/ethereum/solidity)	to Create ERC-20 Token.
[Solidity](https://github.com/ethereum/solidity) is an contract-oriented and statically-typed programming language that was designed to allow developers to create smart contracts.
ERC20 token need to implement the following methods and events:
###Methods
![ERC20 Methods](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fl36rfyqlph8q0mv1z0n.png)
###Events
![ERC20 Events](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ay9q06kx3mui2lj2yjs.png)

#####In order to create an ERC20 token, you need the following:
* The Token’s Name
* The Token’s Symbol
* The Token’s Decimal Places
* The Number of Tokens in Circulation

Now Head over to the Ethereum [Remix](https://remix.ethereum.org/) IDE and make a new Solidity file, for example - token.sol
![Creating Contract File](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/krpymscdc1lptjhhxmix.png)
Paste the following code into your new Solidity script:
```
pragma solidity ^0.8.0;

interface IERC20 {

    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);

    function transfer(address recipient, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);


    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}


contract SampleToken is IERC20 {
    using SafeMath for uint256;

    string public constant name = "SampleToken";
    string public constant symbol = "SMT";
    uint8 public constant decimals = 18;

    mapping(address => uint256) balances;
    mapping(address => mapping (address => uint256)) allowed;

    uint256 totalSupply_;

    constructor(uint256 total) public {
        totalSupply_ = total;
        balances[msg.sender] = totalSupply_;
    }

    function totalSupply() public override view returns (uint256) {
        return totalSupply_;
    }

    function balanceOf(address tokenOwner) public override view returns (uint256) {
        return balances[tokenOwner];
    }

    function transfer(address receiver, uint256 numTokens) public override 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, uint256 numTokens) public override returns (bool) {
        allowed[msg.sender][delegate] = numTokens;
        emit Approval(msg.sender, delegate, numTokens);
        return true;
    }

    function allowance(address owner, address delegate) public override view returns (uint) {
        return allowed[owner][delegate];
    }

    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;
    }
}

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;
    }
}

```
We need to define two mapping objects. This is the Solidity notion for an associative or key/value array:
```
 mapping(address => uint256) balances;
 mapping(address => mapping (address => uint256)) allowed;
```
The expression `mapping(address => uint256)` defines an associative array whose keys are of type address. a number used to denote account addresses, and whose values are of type uint256. Balances mapping, will hold the token balance of each owner account.

The second mapping object, allowed, will include all of the accounts approved to withdraw from a given account together with the withdrawal sum allowed for each.

After that we set the total amount of tokens at constructor (which is a special function automatically called by Ethereum right after the contract is deployed) and assign all of them to the “contract owner” i.e. the account that deployed the smart contract:
```
uint256 totalSupply_;
constructor(uint256 total) public {
  totalSupply_ = total;
  balances[msg.sender] = totalSupply_;
}
```
###Get Total Token Supply
This function will return the number of all tokens allocated by this contract regardless of owner.
```
function totalSupply() public view returns (uint256) {
  return totalSupply_;
}
```
###Get Token Balance of Owner
balanceOf will return the current token balance of an account, identified by its owner’s address.
```
function balanceOf(address tokenOwner) public view returns (uint256) {
   return balances[tokenOwner];
}
```
###Transfer Tokens to Another Account
The transfer function is used to move `numTokens` amount of tokens from the owner’s balance to that of another user, or receiver. The transferring owner is [msg.sender](https://ethereum.stackexchange.com/questions/21029/difference-between-msg-owner-and-msg-sender/28042) i.e. the one executing the function.
```
function transfer(address receiver, uint256 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;
}
```
###Approve user to Withdraw Tokens
This function is most often used in a token marketplace scenario. What `approve` does is to allow an owner i.e. msg.sender to approve a delegate account to withdraw tokens from his account and to transfer them to other accounts.

```
function approve(address delegate, uint256 numTokens) public returns (bool) {
   allowed[msg.sender][delegate] = numTokens;
   emit Approval(msg.sender, delegate, numTokens);
   return true;
}
```
At the end of its execution, this function fires an Approval event.
###Get Number of Tokens Approved for Withdrawal
This function returns the current approved number of tokens by an owner to a specific delegate, as set in the approve function.
```
function allowance(address owner, address delegate) public view returns (uint) {
   return allowed[owner][delegate];
}
```
###Transfer Tokens by Delegate
The `transferFrom` function is the peer of the approve function. It allows a delegate approved for withdrawal to transfer owner funds to a third-party account.
```
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] — numTokens;
  allowed[owner][msg.sender] =
        allowed[from][msg.sender] — numTokens;
  balances[buyer] = balances[buyer] + numTokens;
  Transfer(owner, buyer, numTokens);
  return true;
}
```
###SafeMath
We also used [SafeMath](https://openzeppelin.org/api/docs/math_SafeMath.html) Library for `uint256` data type. SafeMath is a Solidity library aimed at dealing with one way hackers have been known to break contracts: integer overflow attack. In such an attack, the hacker forces the contract to use incorrect numeric values by passing parameters that will take the relevant integers past their maximal values.
##Contract Deployment
Now Let's deploy our ERC20 Token to Ethereum Network. To Deploy Contract to Ethereum Network you will need to install the [MetaMask](https://metamask.io/) plugin on your browser and a Ropsten (Ethereum test network) account with at least some [Ropsten](https://faucet.ropsten.be/) Ether in it.

Then, we will hop over to the second tab to the bottom called *Compiler* and click **Compile**.
![Compile Contract](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1fh7eyjwks4h09ftv01j.png)
After compiled successfully Then, we will hop over to the third tab to the bottom called *DEPLOY & RUN TRANSACTIONS*. Then change the environment to **Injected Web3**. Make sure to select the appropriate contract from options.
![Deploy Contract](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nvgy5eoe2sy8e46mgwyv.png)
And then enter total supply in highlighted box which you want for this token and click on deploy. A MetaMask popup will appear asking us to confirm the transaction. After approve your contract will be deployed which you can see in bottom section **Deployed Contracts**.
![Deoployed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a6cokm5yx4233b8xiwur.png)

That’s it! your token contract is now deployed on Ethereum’s Ropsten testnet! 

Congratulations on successfully creating your very own token/coin on the Ethereum network! Read more about the ERC-20 standard [here](https://eips.ethereum.org/EIPS/eip-20).