DEV Community

Abel Osaretin
Abel Osaretin

Posted on

EIP ERC20 IMPLEMENTATION

November 19th, 2015 an Ethereum Improvement Proposal (EIP) was published to standardize the structure to create tokens on the Ethereum blockchain. The authors were Fabian Vogelsteller and Vitalik Buterin, it was the 20th Ethereum Request For Comment (ERC) so it was given the name ERC-20: Token Standard.

The aim for creating this token standard was to provide basic functionality to transfer tokens, as well as allow tokens to be approved so they can be spent by another on-chain third party. It will also allow any tokens on Ethereum to be re-used by other applications: from wallets to decentralized exchanges.

First we need to create our constructor and state variables to set Name, Symbol, Decimal, and total supply on deployment.

State Variables


string private TokenName;

string private TokenSymbol;

uint8 private TokenDecimals;

uint256 private TokenSupply;

address public owner;

Enter fullscreen mode Exit fullscreen mode

Constructor


constructor(

string memory _tokenName,

string memory _tokenSymbol,

 uint8 _tokenDecimals,

uint256 _tokenSupply

) {

 owner = msg.sender;

 TokenName = _tokenName;

TokenSymbol = _tokenSymbol;

TokenDecimals = _tokenDecimals;

TokenSupply = _tokenSupply;

balance[owner] = TokenSupply;

}

Enter fullscreen mode Exit fullscreen mode

There are 9 functions and 2 events specifications. I will list out the specifications and show you how I implemented it in my code.

Events


event Transfer(address indexed _from, address indexed _to, uint256 _value);

event Approval(address indexed _owner, address indexed _spender, uint256 _value)

Enter fullscreen mode Exit fullscreen mode

Functions

1. Name:

Specification:

Returns the name of the token - e.g. “My Token”

function name() public view returns (string)
Enter fullscreen mode Exit fullscreen mode

Implementation:

function name() public view returns (string memory) {
return TokenName;
}
Enter fullscreen mode Exit fullscreen mode

2. Symbol:

Specification:

Returns the symbol of the token - e.g. “MTK”

function symbol() public view returns (string)
Enter fullscreen mode Exit fullscreen mode

Implementation:

function symbol() public view returns (string memory) {
return TokenSymbol;
}
Enter fullscreen mode Exit fullscreen mode

3. Decimals:

Specification:

Returns the number of decimals the token uses - e.g. 8 means to divide the token amount by, 100000000 to get its user representation.

function decimals() public view returns (uint8)
Enter fullscreen mode Exit fullscreen mode

Implementation:

function decimals() public view returns (uint8) {
return TokenDecimals;
}
Enter fullscreen mode Exit fullscreen mode

4. Total Supply:

Specification:

Returns the token total supply.

function totalSupply() public view returns (uint256)
Enter fullscreen mode Exit fullscreen mode

Implementation:

function totalSupply() public view returns (uint256) {
return TokenSupply;
}
Enter fullscreen mode Exit fullscreen mode

5. Balance Of:

Specification:

Returns the account balance of another account with address “_owner”.

function balanceOf(address _owner) public view returns (uint256 balance)
Enter fullscreen mode Exit fullscreen mode

Implementation:

function balanceOf(address _owner) public view returns (uint256) {
return balance[_owner];
}
Enter fullscreen mode Exit fullscreen mode

6. Transfer:

Specification:

Transfers “_value” amount of tokens to address “_to”, and MUST fire the “Transfer event”. The function SHOULD “throw” if the message caller’s account balance does not have enough tokens to spend.

function transfer(address _to, uint256 _value) public returns (bool success)
Enter fullscreen mode Exit fullscreen mode

Implementation:

function transfer(
address payable _to,
uint256 _value
) public returns (bool) {

require(_to != address(0x0), "Wrong EOA");

require(_value <= balance[msg.sender], "You Don't have enough Token");

balance[msg.sender] = balance[msg.sender] - _value;

balance[_to] = balance[_to] + _value;

return true;

}

Enter fullscreen mode Exit fullscreen mode

7. Transfer From:

Specification:

Transfers "_value" amount of tokens from address "_from" to address "_to", and MUST fire the "Transfer" event. The "transferFrom" method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf.

function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
Enter fullscreen mode Exit fullscreen mode

Implementation:

function transferFrom(
address _from,
address _to,
uint256 _value
) public returns (bool) {

require(_to != address(0x0), "Wrong EOA");

require(_value <= approval[_from][msg.sender]);

uint256 _burnAmount = _value / 10;

approval[_from][msg.sender] -= _value;

balance[_from] -= _value;

balance[_to] += _value;

burn(_from, _burnAmount); // You will see this function bellow

return true;
    }

Enter fullscreen mode Exit fullscreen mode

8. Approve:

Specification:

Allows "_spender" to withdraw from your account multiple times, up to the "_value" amount. If this function is called again it overwrites the current allowance with "_value".

function approve(address _spender, uint256 _value) public returns (bool success)
Enter fullscreen mode Exit fullscreen mode

Implementation:

function approve(address _spender, uint256 _value) public returns (bool) {

approval[msg.sender][_spender] = _value;

return true;

    }

Enter fullscreen mode Exit fullscreen mode

9. Allowance:

Specification:

Returns the amount which "_spender" is still allowed to withdraw from "_owner".

function allowance(address _owner, address _spender) public view returns (uint256 remaining)
Enter fullscreen mode Exit fullscreen mode

Implementation:

function allowance(
address _owner,
address _spender
) public view returns (uint256 approved) {

return approval[_owner][_spender];

}

Enter fullscreen mode Exit fullscreen mode

Burn Feature.

I added a burn feature to the contract which was called in transferFrom function.

10. Burn

It burns 10% of the total supply.

Implementation:


function burn(address _from, uint256 _value) internal {

require(balance[_from] >= _value, "Insufficient balance to burn");

balance[_from] = balance[_from] - _value;

TokenSupply = TokenSupply - _value;

emit Transfer(_from, address(0), _value);

}

Enter fullscreen mode Exit fullscreen mode

Top comments (0)