跳转至主要内容

了解ERC-20通证智能合约

智能合约通证solidityerc-20
初学者
jdourlens
EthereumDev(opens in a new tab)
2020年4月5日
6 分钟阅读 minute read
comp-tutorial-metadata-tip-author 0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE

ERC-20是以太坊上最重要的智能合约标准之一。它已经成为以太坊区块链上用于可替换通证实现的所有智能合约的技术标准。

ERC-20 定义了所有可替换的以太坊通证都应该遵守的通用规则列表。 因此,该通证标准使所有类型的开发者能够准确预测新通证在更大的以太坊系统中将如何工作。 这简化了开发者的任务,因为他们可以继续他们的工作,知道只要通证遵循规则,每次发布新的通证时就不需要重做每个新项目。

这里以接口的形式介绍了 ERC-20 必须实现的函数。 如果您不知道什么是接口:请查看我们关于使用 Solidity 进行 OOP 编程(opens in a new tab)的文章。

1pragma solidity ^0.6.0;
2
3interface IERC20 {
4
5 function totalSupply() external view returns (uint256);
6 function balanceOf(address account) external view returns (uint256);
7 function allowance(address owner, address spender) external view returns (uint256);
8
9 function transfer(address recipient, uint256 amount) external returns (bool);
10 function approve(address spender, uint256 amount) external returns (bool);
11 function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
12
13
14 event Transfer(address indexed from, address indexed to, uint256 value);
15 event Approval(address indexed owner, address indexed spender, uint256 value);
16}
显示全部
复制

下面逐行解释每个函数的用途。 在这之后,我们将展示一个 ERC-20 通证的简单实现。

取值器

1function totalSupply() external view returns (uint256);
复制

返回存在的通证数量。 此函数是一个取值器,不会修改合约的状态。 请记住,Solidity 中没有浮点数。 因此,大多数通证都会采用 18 位小数,并且会返回总供应量和其他结果,如下所示:1 个通证 100000000000000000。 您需要在处理通证时格外注意,并不是每个通证都有 18 位小数。

1function balanceOf(address account) external view returns (uint256);
复制

返回地址拥有的通证数量(account)。 此函数是一个取值器,不会修改合约的状态。

1function allowance(address owner, address spender) external view returns (uint256);
复制

ERC-20 标准使一个地址能够允许另一个地址从中检索通证。 此取值器返回允许spender代表owner花费的剩余通证数量。 此函数是一个取值器,不会修改合约的状态,并且默认应返回 0。

函数

1function transfer(address recipient, uint256 amount) external returns (bool);
复制

将通证的amount从函数调用者地址(msg.sender) 移动到接收者地址。 此函数发出稍后定义的Transfer事件。 如果可进行转账,它将返回 true。

1function approve(address spender, uint256 amount) external returns (bool);
复制

设置允许spender从函数调用方(msg.sender)余额转账的allowance的数额。 此函数发出 Approval 事件。 此函数返回是否成功设置了余量。

1function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
复制

使用余量机制将通证的amountsender移动到recipient。 然后从调用者的余量中扣除该数额。 此函数发出Transfer事件。

事件

1event Transfer(address indexed from, address indexed to, uint256 value);
复制

将通证(值)的数量从from地址发送到to地址时会发出此事件。

在铸造新代币时,转账通常会在 from 0x00..0000 地址进行,而在销毁代币时,转账会在 to 0x00..0000 地址进行。

1event Approval(address indexed owner, address indexed spender, uint256 value);
复制

owner批准要由spender使用的通证数量(value)时,将发出此事件。

ERC-20 通证的基本实现

下面是 ERC-20 通证的最简单代码:

1pragma solidity ^0.8.0;
2
3interface IERC20 {
4
5 function totalSupply() external view returns (uint256);
6 function balanceOf(address account) external view returns (uint256);
7 function allowance(address owner, address spender) external view returns (uint256);
8
9 function transfer(address recipient, uint256 amount) external returns (bool);
10 function approve(address spender, uint256 amount) external returns (bool);
11 function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
12
13
14 event Transfer(address indexed from, address indexed to, uint256 value);
15 event Approval(address indexed owner, address indexed spender, uint256 value);
16}
17
18
19contract ERC20Basic is IERC20 {
20
21 string public constant name = "ERC20Basic";
22 string public constant symbol = "ERC";
23 uint8 public constant decimals = 18;
24
25
26 mapping(address => uint256) balances;
27
28 mapping(address => mapping (address => uint256)) allowed;
29
30 uint256 totalSupply_ = 10 ether;
31
32
33 constructor() {
34 balances[msg.sender] = totalSupply_;
35 }
36
37 function totalSupply() public override view returns (uint256) {
38 return totalSupply_;
39 }
40
41 function balanceOf(address tokenOwner) public override view returns (uint256) {
42 return balances[tokenOwner];
43 }
44
45 function transfer(address receiver, uint256 numTokens) public override returns (bool) {
46 require(numTokens <= balances[msg.sender]);
47 balances[msg.sender] = balances[msg.sender]-numTokens;
48 balances[receiver] = balances[receiver]+numTokens;
49 emit Transfer(msg.sender, receiver, numTokens);
50 return true;
51 }
52
53 function approve(address delegate, uint256 numTokens) public override returns (bool) {
54 allowed[msg.sender][delegate] = numTokens;
55 emit Approval(msg.sender, delegate, numTokens);
56 return true;
57 }
58
59 function allowance(address owner, address delegate) public override view returns (uint) {
60 return allowed[owner][delegate];
61 }
62
63 function transferFrom(address owner, address buyer, uint256 numTokens) public override returns (bool) {
64 require(numTokens <= balances[owner]);
65 require(numTokens <= allowed[owner][msg.sender]);
66
67 balances[owner] = balances[owner]-numTokens;
68 allowed[owner][msg.sender] = allowed[owner][msg.sender]-numTokens;
69 balances[buyer] = balances[buyer]+numTokens;
70 emit Transfer(owner, buyer, numTokens);
71 return true;
72 }
73}
显示全部
复制

ERC-20 代币标准的另一个优秀实现是 OpenZepelin ERC-20 实现(opens in a new tab)

上次修改时间: @tyevlag(opens in a new tab), 2023年8月15日

本教程对你有帮助吗?