ERC-20: The Standard for Fungible Tokens
Introduction
ERC-20 is the most widely used Ethereum token standard for fungible tokens, meaning each token is identical and interchangeable (e.g., USDT, DAI, LINK). It defines a set of rules that all Ethereum-based tokens must follow.
Architecture
An ERC-20 token smart contract includes:
Balance Mapping: Stores token balances for each address
Total Supply: Defines the total number of tokens created
Transfer Mechanism: Allows tokens to be sent between addresses
Allowance Mechanism: Enables third-party contracts to spend tokens on behalf of users
Key Functions of ERC-20
totalSupply()
Returns total token supply
balanceOf(address)
Returns the balance of an address
transfer(address, uint256)
Transfers tokens to another address
approve(address, uint256)
Allows a spender to use a set amount
transferFrom(address, address, uint256)
Transfers tokens using the allowance
allowance(address, address)
Checks how many tokens a spender can use
Workflow of ERC-20 Transactions
Token Deployment: The ERC-20 smart contract is deployed on Ethereum.
Minting: The contract owner mints tokens.
Transfer: Users can send tokens to other addresses using
transfer()
.Approval & Spending:
User A calls
approve(spender, amount)
, allowing Spender to use a specific amount.Spender calls
transferFrom(userA, userB, amount)
to transfer the tokens.
Example: ERC-20 Smart Contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract MyERC20Token {
string public name = "MyToken";
string public symbol = "MTK";
uint8 public decimals = 18;
uint256 public totalSupply = 1000000 * 10**18;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
constructor() {
balanceOf[msg.sender] = totalSupply;
}
function transfer(address _to, uint256 _value) public returns (bool success) {
require(balanceOf[msg.sender] >= _value, "Insufficient balance");
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}
function approve(address _spender, uint256 _value) public returns (bool success) {
allowance[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
require(balanceOf[_from] >= _value, "Insufficient balance");
require(allowance[_from][msg.sender] >= _value, "Allowance exceeded");
balanceOf[_from] -= _value;
balanceOf[_to] += _value;
allowance[_from][msg.sender] -= _value;
emit Transfer(_from, _to, _value);
return true;
}
}
ERC-20 Token Flow
[ User A ] ---> (transfer 100 tokens) ---> [ User B ]
[ DApp ] ---> (approve & transferFrom) ---> [ Marketplace ]
Last updated
Was this helpful?