Token协议-ERC20

2023/02/05 Solidity 共 3350 字,约 10 分钟
咔咔咔酷酷

大概会先把ERC20、ERC721、ERC1155、ERC165、EIP2612、EIP712、ERC511_SBT、ERC1820看一下。

ERC20

标准接口

// 6 REQUIRED FUNCTIONS
function totalSupply() public view returns (uint256)
function balanceOf(address _owner) public view returns (uint256 balance)
function transfer(address _to, uint256 _value) public returns (bool success)
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
function approve(address _spender, uint256 _value) public returns (bool success)
function allowance(address _owner, address _spender) public view returns (uint256 remaining)

// 2 REQUIRED EVENTS
event Transfer(address indexed _from, address indexed _to, uint256 _value)
event Approval(address indexed _owner, address indexed _spender, uint256 _value)

// 3. OPTIONAL FUNCTIONS
function name() public view returns (string)
function symbol() public view returns (string)
function decimals() public view returns (uint8)

分析

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    // 转账事件
    event Transfer(address indexed from, address indexed to, uint256 value);

    // 授权事件
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev 返回总的发行数量.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev 查询账号余额
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * 币的持有人直接调用,进行转账
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     *1. 我这个owner对合约进行approve,此时approve内部会修改allowance变量
    * 2. 合约内部调用transferFrom来支配owner的token
     */
    function transferFrom(address from, address to, uint256 amount) external returns (bool);

    /**
     * spender: 是指定帮助花费的代理人(被授权的人)
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * 持有人对spender进行授权,在approve内部,会调用msg.sender来知道owner是谁
     */
    function approve(address spender, uint256 amount) external returns (bool);

    
}

以上是OpenZeppelin ERC20的接口,下面是调用ERC20接口的案例。
案例:

    // SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import "./IERC20.sol";

contract ERC20 is IERC20 {
    // 定变量
    // 代币总供给
    uint256 public override totalSupply;    
    // 记录账户余额
     mapping(address => uint256) public override balanceOf;
    // 授权的额度
    mapping(address => mapping(address => uint256)) public override allowance;
    // 代币的名字
    string public name = "WalnutTTTT ";
    // 代币的简写
    string public symbol = "Walnut";
    // 小数位
    uint8 public decimals = 18;
    
    // 构造函数
     constructor(string memory name_, string memory symbol_){
        name = name_;
        symbol = symbol_;
    }
    // @dev 实现`transfer`函数,代币转账逻辑
    function transfer(address recipient, uint amount) external override returns (bool) {
        balanceOf[msg.sender] -= amount;
        balanceOf[recipient] += amount;
        emit Transfer(msg.sender, recipient, amount);
        return true;
    }

    // @dev 实现 `approve` 函数, 代币授权逻辑
    function approve(address spender, uint amount) external override returns (bool) {
        allowance[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }

    // @dev 实现`transferFrom`函数,代币授权转账逻辑
    function transferFrom(
        address sender,
        address recipient,
        uint amount
    ) external override returns (bool) {
        allowance[sender][msg.sender] -= amount;
        balanceOf[sender] -= amount;
        balanceOf[recipient] += amount;
        emit Transfer(sender, recipient, amount);
        return true;
    }

    // @dev 铸造代币,从 `0` 地址转账给 调用者地址
    function mint(uint amount) external {
        balanceOf[msg.sender] += amount;
        totalSupply += amount;
        emit Transfer(address(0), msg.sender, amount);
    }

    // @dev 销毁代币,从 调用者地址 转账给  `0` 地址
    function burn(uint amount) external {
        balanceOf[msg.sender] -= amount;
        totalSupply -= amount;
        emit Transfer(msg.sender, address(0), amount);
    }
}

资料:

https://dukedaily.github.io/solidity-expert/03_token%E5%8D%8F%E8%AE%AE/01_ERC20.html

文档信息

Search

    Table of Contents