The "ERC20" Token

Github link to code

Hello, I just created an ERC20 token, and I will be explaining each line of the code snippets... (I will be creating a Factory pattern of/for this very soon ๐Ÿค—)

ERC20 is a widely adopted standard for creating and issuing tokens on the Ethereum blockchain. The name ERC20 stands for "Ethereum Request for Comments 20," and it defines a set of rules and functions that Ethereum-based tokens must follow to be considered ERC20 compliant.

contract ERC20 {
code...;
}
  • This line declares the start of a new contract named ERC20. Contracts in Solidity are similar to classes in object-oriented programming languages.
uint private totalTokenSupply;
mapping(address => uint256) private balances;
mapping(address => mapping(address => uint256)) public allowance;
string public name;
string public symbol;
uint8 public decimals;
address owner = msg.sender;

These lines declare state variables for the ERC20 contract.

  • totalTokenSupply: Stores the total supply of tokens.

  • balances: Maps address to their respective token balances in unsigned integers (uint256).

  • allowance: A 2D mapping. Maps address to a mapping of address to approved token spending amounts.

  • name, symbol, and decimals: Variables for the name, symbol, and decimal precision of the token.

  • owner: Stores the address of the contract deployer.

constructor() {
    name = "KUVAT";
    symbol = "KVA";
    decimals = 18;
    owner = msg.sender;
    mint(5000000);
}

At the point of deployment, we set fixed values into the state variables through the constructor. We can make this dynamic if we want to. It also calls the mint function to mint an initial supply of tokens upon deployment.

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

These lines declare two events: Transfer and Approval. Events are used to log specific occurrences within a contract, allowing external applications to listen for and react to these events. Transfer event will be emitted at transfer() and transferFrom(). Approval event emitted at approve().

The contract functions including the cores, burnable, and mint are as follows;

function totalSupply() external view returns (uint256) {
        return totalTokenSupply;
 }
  • totalSupply(): A read function which returns the total supply of tokens, and the amounts in existence at any given time.

      function balanceOf(address _account) external view returns (uint256) {
              return (balances[_account]);
          }
    
  • balanceOf(): Returns the token balance of a given address _account.

      function transfer(address _recipient, uint _amount) external returns (bool) {
              require(_recipient != address(0), "no zero address call");
              uint _charges = (_amount * 10) / 100;
              require((balances[msg.sender] + _charges) >= _amount,
                  "you don't have sufficient funds to send"
              );
              burn(_charges);
              balances[msg.sender] -= _amount;
              balances[_recipient] += _amount;
              emit Transfer(msg.sender, _recipient, _amount);
              return true;
          }
    
  • transfer(): Moves amount _amount tokens from the caller's address/account to a specified recipient _recipient. A burn() charging 10% on every transaction from the caller's balance, and burning it from the totalTokenSupply was invoked.

function approve(address _spender, uint _amount) external returns (bool) {
        require(_spender != address(0), "wrong EOA");
        uint _charges = (_amount * 10) / 100;
        require((balances[msg.sender] + _charges > 0),
            "You do not have enough token to approve to spender"
        );
        allowance[msg.sender][_spender] = _amount;
        emit Approval(msg.sender, _spender, _amount);
        return true;
    }
  • approve(): Sets _amount as the allowance of the _spender over the caller's msg.sender tokens. Returns a boolean value indicating whether the operation succeded. Emits an Approval event.
function transferFrom(address _sender,address _recipient, uint256 _amount
    ) external returns (bool) {
        uint _charge = (_amount * 10) / 100;
        require(allowance[msg.sender][_sender] > _amount,
            "you do not have sufficient allowance to send"
        );
        allowance[msg.sender][_sender] -= _amount;
        burn(_charge);
        balances[msg.sender] -= _amount;
        balances[_recipient] += _amount;
        emit Transfer(_sender, _recipient, _amount);
        return true;
    }
  • transferFrom(): Transfers tokens from one address to another, with approval using the allowance mechanism. _amount is deducted from the caller's allowance. Emits an Transfer event.

  • mint(): Mints new tokens, to set the total supply.

  • burn(): Burns (destroys) tokens, decreasing the total supply.

ย