以太坊(Ethereum)是一个去中心化的开源的有智能合约功能的公共区块链平台。以太币(ETH 或 Ξ)是以太坊的原生加密货币。截至2021年12月,以太币是市值第二高的加密货币,仅次于比特币。以太坊是使用最多的区块链,主要的代币标准有 ERC-20、ERC-721、ERC-1155、ERC-223、ERC-677 等等,其中 ERC-20 是最常用的代币标准。
IERC20 是 ERC20 标准的接口规范,它定义和规范了一个标准 ERC20 代币合约应该实现的功能。这里让 ERC20 合约直接继承自 IERC20 接口。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
interface IERC20 {
// 当 `value` 单位的货币从账户 (`from`) 转账到另一账户 (`to`)时 触发
event Transfer(address indexed from, address indexed to, uint256 value);
// 当 `value` 单位的货币从账户 (`owner`) 授权给另一账户 (`spender`)时触发
event Approval(address indexed owner, address indexed spender, uint256 value);
// 返回代币总供给.
function totalSupply() external view returns (uint256);
// 返回账户`account`所持有的代币数.
function balanceOf(address account) external view returns (uint256);
// 转账 `amount` 单位代币,从调用者账户到另一账户 `to`.
function transfer(address to, uint256 amount) external returns (bool);
// 返回`owner`账户授权给`spender`账户的额度,默认为0。
function allowances(address owner, address spender) external view returns (uint256);
// 调用者账户给`spender`账户授权 `amount`数量代币。
function approve(address spender, uint256 amount) external returns (bool);
// 通过授权机制,从`from`账户向`to`账户转账`amount`数量代币。转账的部分会从调用者的`allowances`中扣除。
function transferFrom( address from, address to, uint256 amount ) external returns (bool);
}
ERC20 是以太坊上最常用的代币标准,用于发行同质化代币。它定义了一套规则和接口,使得不同的代币可以在同一个平台上互相交换和使用。ERC-20 定义的代币实现了基本功能如转账、查询余额、授权、总供给量等。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "./IERC20.sol";
contract MyToken is IERC20 {
mapping(address => uint256) public override balanceOf;
mapping(address => mapping(address => uint256)) public override allowances;
uint256 public totalSupply; // 代币总供给
string public name; // 代币名称
string public symbol; // 代币代号
uint8 public decimals = 18; // 小数位数
// 构造函数
constructor(string memory name_, string memory symbol_) {
name = name_;
symbol = symbol_;
}
// 转账
function transfer(address recipient, uint256 amount) public override returns (bool) {
_transfer(msg.sender, recipient, amount);
return true;
}
// 授权转账
function transferFrom(address sender, address recipient, uint amount) external override returns (bool){
_transfer(sender, recipient, amount);
uint256 currentAllowance = allowances[sender][msg.sender];
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowances"); // 是否超过授权额度
_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 = balanceOf[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
balanceOf[sender] = senderBalance - amount;
balanceOf[recipient] += amount;
emit Transfer(sender, recipient, amount);
}
// 授权
function approve(address spender, uint amount) external override returns (bool){
_approve(msg.sender, spender, amount);
return true;
}
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);
}
// 锻造代币
function mint(address account, uint amount) external {
require(account != address(0), "ERC20: mint to the zero address");
balanceOf[account] += amount;
totalSupply += amount;
emit Transfer(address(0), msg.sender, amount);
}
// 销毁代币
function burn(address account, uint amount) external {
require(account != address(0), "ERC20: burn from the zero address");
uint256 accountBalance = balanceOf[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
balanceOf[account] = accountBalance - amount;
totalSupply -= amount;
emit Transfer(account, address(0), amount);
}
}
1、可以直接在 Remix IDE 上编译部署。
2、 点击 mint 函数输入 account 和 amount 两个参数锻造代币。