ERC 20详解

列出 OpenZeppelin 的 ERC20 合约中主要的内部和公共方法:

主要内部方法(以_开头):

solidity
// 内部方法(合约内部和继承的合约可以使用)
_mint(address account, uint256 amount)       // 铸造代币
_burn(address account, uint256 amount)       // 销毁代币
_approve(address owner, address spender, uint256 amount)  // 批准代币
_transfer(address from, address to, uint256 amount)       // 转移代币
_spendAllowance(address owner, address spender, uint256 amount)  // 花费授权额度
_beforeTokenTransfer(address from, address to, uint256 amount)   // 转账前钩子
_afterTokenTransfer(address from, address to, uint256 amount)    // 转账后钩子

主要公共方法:

solidity
// 公共视图方法
name() public view returns (string)              // 代币名称
symbol() public view returns (string)            // 代币符号
decimals() public view returns (uint8)           // 小数位数
totalSupply() public view returns (uint256)      // 总供应量
balanceOf(address account) public view returns (uint256)  // 查询余额
allowance(address owner, address spender) public view returns (uint256)  // 查询授权额度

// 公共写入方法
transfer(address to, uint256 amount) public returns (bool)  // 转账
approve(address spender, uint256 amount) public returns (bool)  // 授权
transferFrom(address from, address to, uint256 amount) public returns (bool)  // 授权转账
increaseAllowance(address spender, uint256 addedValue) public returns (bool)  // 增加授权额度
decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool)  // 减少授权额度

 

以下是一个完整的、安全的 ERC-20 代币合约示例,包含铸币(mint)、销毁(burn)和转移(transfer)功能, gpt生成的:

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

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

contract MyToken is ERC20, Ownable, Pausable, ReentrancyGuard {
    // 事件声明
    event Mint(address indexed to, uint256 amount);
    event Burn(address indexed from, uint256 amount);
    
    // 铸币限制
    uint256 public constant MAX_SUPPLY = 1000000000 * 10**18; // 10亿代币
    
    // 黑名单映射
    mapping(address => bool) public blacklist;
    
    constructor(string memory name, string memory symbol) 
        ERC20(name, symbol) 
        Ownable(msg.sender) 
    {}

    // 修饰符:检查地址是否在黑名单中
    modifier notBlacklisted(address _address) {
        require(!blacklist[_address], "Address is blacklisted");
        _;
    }

    // 铸币功能
    function mint(address to, uint256 amount) 
        external 
        onlyOwner 
        whenNotPaused 
        nonReentrant 
    {
        require(to != address(0), "Cannot mint to zero address");
        require(amount > 0, "Amount must be positive");
        require(
            totalSupply() + amount <= MAX_SUPPLY, 
            "Would exceed max supply"
        );

        _mint(to, amount);
        emit Mint(to, amount);
    }

    // 批量铸币
    function batchMint(
        address[] calldata recipients, 
        uint256[] calldata amounts
    ) 
        external 
        onlyOwner 
        whenNotPaused 
        nonReentrant 
    {
        require(
            recipients.length == amounts.length,
            "Arrays length mismatch"
        );
        
        uint256 totalAmount = 0;
        for(uint i = 0; i < amounts.length; i++) {
            totalAmount += amounts[i];
        }
        
        require(
            totalSupply() + totalAmount <= MAX_SUPPLY,
            "Would exceed max supply"
        );

        for(uint i = 0; i < recipients.length; i++) {
            require(
                recipients[i] != address(0),
                "Cannot mint to zero address"
            );
            require(amounts[i] > 0, "Amount must be positive");
            
            _mint(recipients[i], amounts[i]);
            emit Mint(recipients[i], amounts[i]);
        }
    }

    // 销毁功能
    function burn(uint256 amount) 
        external 
        whenNotPaused 
        nonReentrant 
    {
        require(amount > 0, "Amount must be positive");
        require(
            balanceOf(msg.sender) >= amount,
            "Insufficient balance"
        );

        _burn(msg.sender, amount);
        emit Burn(msg.sender, amount);
    }

    // 覆写转账功能,添加额外的检查
    function transfer(address to, uint256 amount)
        public
        override
        whenNotPaused
        notBlacklisted(msg.sender)
        notBlacklisted(to)
        returns (bool)
    {
        require(to != address(0), "Cannot transfer to zero address");
        require(amount > 0, "Amount must be positive");
        return super.transfer(to, amount);
    }

    // 覆写授权转账功能
    function transferFrom(
        address from,
        address to,
        uint256 amount
    )
        public
        override
        whenNotPaused
        notBlacklisted(from)
        notBlacklisted(to)
        returns (bool)
    {
        require(to != address(0), "Cannot transfer to zero address");
        require(amount > 0, "Amount must be positive");
        return super.transferFrom(from, to, amount);
    }

    // 管理功能

    // 添加地址到黑名单
    function addToBlacklist(address _address) 
        external 
        onlyOwner 
    {
        blacklist[_address] = true;
    }

    // 从黑名单中移除地址
    function removeFromBlacklist(address _address) 
        external 
        onlyOwner 
    {
        blacklist[_address] = false;
    }

    // 暂停合约
    function pause() external onlyOwner {
        _pause();
    }

    // 取消暂停
    function unpause() external onlyOwner {
        _unpause();
    }

    // 紧急代币恢复(从合约地址救回意外转入的代币)
    function recoverERC20(
        address tokenAddress,
        uint256 tokenAmount
    ) 
        external 
        onlyOwner 
    {
        require(
            tokenAddress != address(this),
            "Cannot recover native token"
        );
        
        IERC20(tokenAddress).transfer(
            owner(),
            tokenAmount
        );
    }
}
posted @ 2024-12-24 10:16  若-飞  阅读(136)  评论(0)    收藏  举报