乐闻世界logo
搜索文章和话题

What is the ERC-20 token standard? Please explain the interface specification and implementation methods of ERC-20 in detail

2月21日 16:06

ERC-20 is the most widely used token standard on Ethereum, defining the interface specification for fungible tokens. Here's a detailed analysis of the ERC-20 standard:

ERC-20 Standard Overview

ERC-20 stands for "Ethereum Request for Comments 20," proposed by Fabian Vogelsteller in 2015. It defines a set of standard interfaces that enable different tokens to interoperate within the Ethereum ecosystem.

Required Methods

1. totalSupply()

Returns the total supply of tokens.

solidity
function totalSupply() external view returns (uint256) { return _totalSupply; }

2. balanceOf(address account)

Returns the token balance of a specified account.

solidity
function balanceOf(address account) external view returns (uint256) { return _balances[account]; }

3. transfer(address recipient, uint256 amount)

Transfers tokens from the caller's account to the recipient's account.

solidity
function transfer(address recipient, uint256 amount) external returns (bool) { _transfer(_msgSender(), recipient, amount); return true; }

4. allowance(address owner, address spender)

Returns the amount of tokens authorized for the spender.

solidity
function allowance(address owner, address spender) external view returns (uint256) { return _allowances[owner][spender]; }

5. approve(address spender, uint256 amount)

Authorizes the spender to use the caller's tokens.

solidity
function approve(address spender, uint256 amount) external returns (bool) { _approve(_msgSender(), spender, amount); return true; }

6. transferFrom(address sender, address recipient, uint256 amount)

Transfers tokens from the sender's account to the recipient's account using the authorized allowance.

solidity
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; }

Optional Methods

1. name()

Returns the token name.

solidity
function name() external view returns (string memory) { return _name; }

2. symbol()

Returns the token symbol.

solidity
function symbol() external view returns (string memory) { return _symbol; }

3. decimals()

Returns the number of decimal places for the token, typically 18.

solidity
function decimals() external view returns (uint8) { return _decimals; }

Events

1. Transfer

Triggered when tokens are transferred.

solidity
event Transfer(address indexed from, address indexed to, uint256 value);

2. Approval

Triggered when authorization occurs.

solidity
event Approval(address indexed owner, address indexed spender, uint256 value);

Complete ERC-20 Implementation Example

solidity
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract MyToken { string private _name; string private _symbol; uint8 private _decimals; uint256 private _totalSupply; mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; constructor(string memory name_, string memory symbol_, uint256 initialSupply) { _name = name_; _symbol = symbol_; _decimals = 18; _totalSupply = initialSupply; _balances[msg.sender] = initialSupply; emit Transfer(address(0), msg.sender, initialSupply); } function name() external view returns (string memory) { return _name; } function symbol() external view returns (string memory) { return _symbol; } function decimals() external view returns (uint8) { return _decimals; } function totalSupply() external view returns (uint256) { return _totalSupply; } function balanceOf(address account) external view returns (uint256) { return _balances[account]; } function transfer(address recipient, uint256 amount) external returns (bool) { _transfer(msg.sender, recipient, amount); return true; } function allowance(address owner, address spender) external view returns (uint256) { return _allowances[owner][spender]; } function approve(address spender, uint256 amount) external returns (bool) { _approve(msg.sender, spender, amount); return true; } function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][msg.sender]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, msg.sender, currentAllowance - amount); } return true; } function _transfer(address sender, address recipient, uint256 amount) internal { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; _balances[recipient] += amount; } emit Transfer(sender, recipient, amount); } function _approve(address owner, address spender, uint256 amount) internal { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } }

Using OpenZeppelin Library

OpenZeppelin provides audited ERC-20 implementations, recommended for production use.

solidity
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract MyToken is ERC20, Ownable { constructor(uint256 initialSupply) ERC20("My Token", "MTK") { _mint(msg.sender, initialSupply); } function mint(address to, uint256 amount) public onlyOwner { _mint(to, amount); } }

ERC-20 Use Cases

1. Decentralized Finance (DeFi)

  • Liquidity provision
  • Lending protocols
  • Derivative trading

2. Governance Tokens

  • DAO voting
  • Protocol governance
  • Community incentives

3. Stablecoins

  • USDT, USDC, DAI
  • Fiat-collateralized
  • Algorithmic stability

4. Utility Tokens

  • Platform access rights
  • Service payments
  • Reward mechanisms

ERC-20 Limitations

1. Authorization Mechanism Issues

  • Requires two transactions (approve + transferFrom)
  • May lead to authorization allowance leakage

2. Lack of Batch Operations

  • Each transfer requires a separate transaction
  • Higher Gas costs

3. No Token Callback Support

  • Doesn't support notifications when receiving tokens
  • May lead to token loss

Other ERC Token Standards

ERC-721

Non-Fungible Token (NFT) standard, each token is unique.

ERC-1155

Multi-token standard supporting both fungible and non-fungible tokens.

ERC-777

Improved ERC-20 standard with token callbacks and batch operations.

ERC-4626

Vault token standard for DeFi yield aggregators.

Best Practices

  1. Use OpenZeppelin Library: Avoid reinventing the wheel, use audited code
  2. Add Access Control: Implement proper permission management
  3. Event Logging: Record all important operations
  4. Security Audit: Conduct professional audits before deployment
  5. Test Coverage: Ensure adequate test coverage

The ERC-20 standard is the foundation of the Ethereum ecosystem, and understanding how it works is crucial for developing blockchain applications.

标签:以太坊