Loading...
It bascially is a smart contract that follows some sort standard which is recognized by the ethereum virtual machine(EVM).
Some commonly known erc20 tokens are Link token, Omisego(OMG), Thether(USDT), Compound(Comp) and plenty other that lie on ethereum blockchain. You can find more on etherscan.io.
Now before hopping into the smart contract we should know how these erc20 standard look like. You can also find them on ethereum.org.
These are some of the manditory functions that you need include into smart contract to be recognized as erc20 token. All These funciton are wrapped as interface. Using interface keyword instead of contract makes it abstract it simple means that all your functons visibility is suppose to be external or else the compiler will throw an error.
interface IERC20{
function balanceOf(address _owner) external view returns (uint256 balance);
function transfer(address _to, uint256 _value) external returns (bool success);
function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);
function approve(address _spender, uint256 _value) external returns (bool success);
function allowance(address _owner, address _spender) external view returns (uint256 remaining);
}
event Transfer(address indexed _from, address indexed _to, uint256 _value)
event Approval(address indexed _owner, address indexed _spender, uint256 _value)
As we can see contract Erc20 is inherting from an abstract contract(when your contract is abstract you will not be able to compile it.)
IERC20. This way we can use the function of IERC20.
Let's understand the code
mapping (address => uint) balances;
mapping (address => mapping(address => uint)) allowed;
You can see two types of mapping the first one i.e. balances will hold the token balance of each owner’s account and the second mapping i.e. allowed is a nested mapping which includes all the accounts approved to withdraw from a given account together with the withdrawal sum allowed for each.
function name() public view returns (string memory){
return "cherry";
}
function symbol() public view returns (string memory){
return "ch";
}
function decimals() public view returns (uint8){
return 18;
}
function totalSupply() public view returns (uint256){
return 250;
}
In these above function you are free to use your creativity . You assign any values to these except fo decimals() function since solidity supports only upto 18 decimals. For rest you can give name and symbol of your choice and also you can decide how tokens your smart contract shall posses for you.
function balanceOf(address tokenOwner) public view returns(uint){
return balances[tokenOwner];
}
balanceOf() function takes one parameter tokenOwner and returns the balance of the owner.
function transfer(address _to, uint256 _value) public returns (bool success){
if(balances[msg.sender] >= _value){
balances[msg.sender] -= _value;
balances[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}
transfer() transfers the values if balance of sender is greater than amount we wanna send. This condition becomes important since the sender's account must hold greater amount than what he wants to spends or else the transaction should fail.
And we also have fired an event emit in this function.
function transferFrom(address _from, address _to, uint _value) public returns(bool success){
if(balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value>0 ){
balances[_from] -= _value;
balances[_to] += _value;
emit Transfer(_from, _to, _value);
return true;
}
else{
return false;
}
}
transferFrom() function allows contracts to send tokens on your behalf. It checks if the amount that is to be spent is not equal to zero and also checks if the account which who is making the transaction and spenders account balance are greater than zero.
Transfer event is fired as well.
function approve(address _spender, uint256 _value) public returns (bool success){
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
The approve() function checks if the given address is allowed to spend from his contract or not. We also have fired the event "Approval" to interact with the front end.
function allowance(address _owner, address _spender) public view returns (uint256 remaining){
return allowed[_owner][_spender];
This function allowance checks if address is allowed to spend on the owner's behalf or not. Here the owner has authority to allow someone else to spend his ether on his behalf as well as he can also regulate how the spender allowed to spend.
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.6;
interface IERC20{
function balanceOf(address _owner) external view returns (uint256 balance);
function transfer(address _to, uint256 _value) external returns (bool success);
function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);
function approve(address _spender, uint256 _value) external returns (bool success);
function allowance(address _owner, address _spender) external view returns (uint256 remaining);
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
contract Erc20 is IERC20{
mapping (address => uint) balances;
mapping (address => mapping(address => uint)) allowed;
function name() public view returns (string memory){
return "cherry";
}
function symbol() public view returns (string memory){
return "ch";
}
function decimals() public view returns (uint8){
return 18;
}
function totalSupply() public view returns (uint256){
return 250;
}
function balanceOf(address _owner) public view returns (uint256 balance){
return balances[_owner];
}
function transfer(address _to, uint256 _value) public returns (bool success){
if(balances[msg.sender] >= _value){
balances[msg.sender] -= _value;
balances[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success){
if(balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value>0 && balances[_to] + _value> balances[_to]){
balances[_from] -= _value;
balances[_to] += _value;
emit Transfer(_from, _to, _value);
return true;
}
else{
return false;
}
}
function approve(address _spender, uint256 _value) public returns (bool success){
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
function allowance(address _owner, address _spender) public view returns (uint256 remaining){
return allowed[_owner][_spender];
}
}