# ERC20 代币合约
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.8.0;
library SafeMath {
function safeMul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {return 0;}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function safeDiv(uint256 a, uint256 b) internal pure returns (uint256) {
require(b>0);
uint256 c=a/b;
require(!(a==b*c+a%b));
return c;
}
function safeAdd(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c=a+b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function safeSub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
return a - b;
}
}
// Recipient 收件人
interface tokenRecipient {
function receiveApproval(
address _from,
uint256 _value,
address _token,
bytes memory _extraData
) external;
}
contract ERC20 {
using SafeMath for uint256;
string public name; // fancy name eg: OVM Coin
string public symbol; // An identifier(标识符) eg: OVM
uint8 public decimals=18; // 精度是多少
uint256 public totalSupply; // 发行总量
address payable public owner;
/// balances
mapping(address=>uint256) public balanceOf;
// 冻结数组
mapping(address=>uint256) public freezeOf;
// allowance - 允许别人用你的名义划转
mapping(address=>mapping(address=>uint256)) public allowance;
// indexed 一个事件的检索
event Transfer(address indexed from, address indexed to, uint256 value);
// 冻结事件监听
event Freeze(address indexed from, uint256 value);
// 释放冻结事件监听
event Unfreeze(address indexed from, uint256 value);
// Approval 谁拥有授权 谁给他的授权 有多少 value
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
// Burn 销毁机制
event Burn(address indexed from, uint256 value);
constructor(
uint256 _initialAmount,
uint8 _decimalUints,
string memory _tokenName,
string memory _tokenSymbol
) {
balanceOf[msg.sender] = _initialAmount;
totalSupply = _initialAmount;
name = _tokenName;
decimals = _decimalUints;
symbol = _tokenSymbol;
owner = msg.sender;
}
// 内部划转,只能合约内部调用
function _transfer(address _from, address _to, uint _value) internal {
// 阻止划转到 0x0地址,用burn()函数
require(_to != address(0x0));
// 划出的账户有足够的余额
require(balanceOf[_from]>=_value);
// 增加后会不会栈溢出
require(balanceOf[_to]+_value>=balanceOf[_to]);
// 保存值为接下来的断言使用
uint previousBalances = balanceOf[_from].safeAdd(balanceOf[_to]);
balanceOf[_from] =balanceOf[_from].safeSub(_value);
balanceOf[_to] = balanceOf[_to].safeAdd(_value);
// 调用Transfer 发信息
emit Transfer(_from, _to, _value);
// 使用断言静态分析代码中的错误
assert(balanceOf[_from].safeAdd(balanceOf[_to]) == previousBalances);
}
// 外部调用划转 从大账户划转
function transfer(address _to, uint256 _value) public returns (bool success){
_transfer(msg.sender, _to, _value);
return true;
}
// 从其他地址划转 授权
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success){
// 查看是否是有划转权限的账户
// _from 额度里 给到 调用者的额度
require(_value<=allowance[_from][msg.sender]);
allowance[_from][msg.sender] = allowance[_from][msg.sender].safeSub(_value); // 更新allowance表
_transfer(_from, _to, _value);
return true;
}
// 设置某个地址容许以主账户名义转账额度
function approve(address _spender, uint256 _value) public returns(bool success){
require(_value >0);
allowance[msg.sender][_spender] = _value;
// 谁给谁发布了多少额度
emit Approval(msg.sender, _spender, _value);
return true;
}
// 调用并返回
function approveAndCall(address _spender, uint256 _value, bytes memory _extraData) public returns (bool success){
tokenRecipient spender = tokenRecipient(_spender);
if(approve(_spender, _value)){
spender.receiveApproval(msg.sender, _value, address(this), _extraData);
return true;
}
}
// 主账号销毁
function burn(uint256 _value) public returns (bool success) {
require(_value>0);
require(balanceOf[msg.sender] >= _value);
balanceOf[msg.sender] = balanceOf[msg.sender].safeSub(_value);
totalSupply = totalSupply.safeSub(_value);
emit Burn(msg.sender, _value);
return true;
}
// 其他账户调用销毁
function burnFrom(address _from, uint256 _value) public returns (bool success){
// 查看要销毁的账户是否有足够的余额
require(_value>0);
require(balanceOf[_from]>=_value);
require(_value<=allowance[_from][msg.sender]);
balanceOf[_from] = balanceOf[_from].safeSub(_value);
allowance[_from][msg.sender] = allowance[_from][msg.sender].safeSub(_value);
totalSupply = totalSupply.safeSub(_value);
emit Burn(_from, _value);
return true;
}
// 冻结
function freeze(uint256 _value) public returns (bool success){
require(_value>0);
require(balanceOf[msg.sender]>=_value);
balanceOf[msg.sender] = balanceOf[msg.sender].safeSub(_value);
freezeOf[msg.sender] = freezeOf[msg.sender].safeAdd(_value);
emit Freeze(msg.sender, _value);
return true;
}
// 解冻
function unfreeze(uint256 _value) public returns (bool success){
require(freezeOf[msg.sender] >=_value);
require(_value>0);
freezeOf[msg.sender] = freezeOf[msg.sender].safeSub(_value);
balanceOf[msg.sender] = balanceOf[msg.sender].safeAdd(_value);
emit Unfreeze(msg.sender, _value);
return true;
}
function withdrawEther(uint256 amount) payable public returns (bool success){
require(msg.sender==owner);
owner.transfer(amount);
return true;
}
}