跳转至主要内容

了解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)

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

本教程对你有帮助吗?