# Solidity进阶实战 **Published by:** [Benson](https://paragraph.com/@bensonxu/) **Published on:** 2023-09-02 **URL:** https://paragraph.com/@bensonxu/solidity-2 ## Content 1.逐行解读PEPE合约// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); constructor() { _transferOwnership(_msgSender()); } function owner() public view virtual returns (address) { return _owner; } modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); } interface IERC20Metadata is IERC20 { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); } contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; // 代币余额 mapping(address => mapping(address => uint256)) private _allowances; // 代币授权额度 uint256 private _totalSupply; // 总量 string private _name; // 代币名称 string private _symbol; // 代币缩写 // 初始化 代币名称 代币缩写 constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } // 取读 代币名称 function name() public view virtual override returns (string memory) { return _name; } // 取读 代币缩写 function symbol() public view virtual override returns (string memory) { return _symbol; } // 取读 代币精度 function decimals() public view virtual override returns (uint8) { return 18; } // 取读 代币总量 function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } // 取读 某一地址代币余额 function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } // 写入 转账 function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } // 取读 某一地址授权额度 function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } // 写入 某一地址授权额度 function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } // 写入 转账 function transferFrom( address sender, address recipient, uint256 amount ) public virtual override 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; } // 写入 增加授权额度 function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } // 写入 减少授权额度 function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } // 写入 转账 function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; // 100 - 100 } _balances[recipient] += amount; // 0 + 100 emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } function _approve( address owner, address spender, uint256 amount ) internal virtual { 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); } function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } contract PepeToken is Ownable, ERC20 { bool public limited; uint256 public maxHoldingAmount; uint256 public minHoldingAmount; address public uniswapV2Pair; // V2交易对 mapping(address => bool) public blacklists; // 黑名单 constructor(uint256 _totalSupply) ERC20("Pepe", "PEPE") { _mint(msg.sender, _totalSupply); } // 写入 黑名单 function blacklist(address _address, bool _isBlacklisting) external onlyOwner { blacklists[_address] = _isBlacklisting; } // 写入 交易规则 function setRule(bool _limited, address _uniswapV2Pair, uint256 _maxHoldingAmount, uint256 _minHoldingAmount) external onlyOwner { limited = _limited; uniswapV2Pair = _uniswapV2Pair; maxHoldingAmount = _maxHoldingAmount; minHoldingAmount = _minHoldingAmount; } // 交易前 function _beforeTokenTransfer( address from, address to, uint256 amount ) override internal virtual { //黑名单限制 require(!blacklists[to] && !blacklists[from], "Blacklisted"); // 交易是否开始限制 if (uniswapV2Pair == address(0)) { require(from == owner() || to == owner(), "trading is not started"); return; } // 钱包数量限制 if (limited && from == uniswapV2Pair) { require(super.balanceOf(to) + amount <= maxHoldingAmount && super.balanceOf(to) + amount >= minHoldingAmount, "Forbid"); } } // 销毁 function burn(uint256 value) external { _burn(msg.sender, value); } } ## Publication Information - [Benson](https://paragraph.com/@bensonxu/): Publication homepage - [All Posts](https://paragraph.com/@bensonxu/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@bensonxu): Subscribe to updates - [Twitter](https://twitter.com/benson_btc): Follow on Twitter