0%

solidity | 再次探究 ERC20

之前写过好几次 ERC20 代码,但是,理解总是不深,这次再次探究一下。

这次我将从如何完整的建立一个合约项目开始。

根据 solidity | solidity 开发环境应该怎么选择

我选择的是使用 remix 进行编辑。首先建立一个项目工程。

这里认为你的电脑已经安装了 node.jsnpm 了。

创建项目与安装环境

npm init 建立项目

参考

只使用 openzeppelin 里面的接口和源码。

编写代码

直接复用 openzeppelin 的接口 @openzeppelin/contracts/token/ERC20/IERC20.sol

这里直接贴代码,下面的代码不能用于生产环境,BUG 非常多。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";

contract ERC20 is IERC20{

using SafeMath for uint256;
error mathError(address sender,string msg);

mapping(address => uint256) public override balanceOf;

mapping(address => mapping(address => uint256)) public override allowance;

uint256 public override 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 to, uint amount) external override returns (bool) {
balanceOf[msg.sender] -= amount;
balanceOf[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}

function approve(address spender, uint amount) external override returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}

function transferFrom(
address sender,
address recipient,
uint amount
) external override returns (bool) {
(bool state,) = allowance[sender][msg.sender].trySub(amount);
if(state == false){
revert mathError(msg.sender,"sub error");
}
balanceOf[sender].trySub(amount);
balanceOf[recipient].tryAdd(amount);
emit Transfer(sender, recipient, amount);
return true;
}

// 下面这两个不在标准中
function mint(uint amount) external {
balanceOf[msg.sender] += amount;
totalSupply += amount;
emit Transfer(address(0), msg.sender, amount);
}

function burn(uint amount) external {
balanceOf[msg.sender] -= amount;
totalSupply -= amount;
emit Transfer(msg.sender, address(0), amount);
}

}

然后我将其部署到了测试网

关于这个合约的相关细节,可以参考

也可以直接使用 openzeppelin 写好的合约。

1
2
3
4
5
6
7
8
9
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract Test is ERC20 {

constructor() ERC20("Doge Test", "doge") {
}
}
请我喝杯咖啡吧~