0%

erc20 | 固定总量的代币

参考


参考资料



固定总量代币


首先,这里认为已经创建好了 truffle solidity 项目。

npm install @openzeppelin/contracts@3.4.0
npm install @truffle/hdwallet-provider // 部署脚本

整个项目如下

--contracts
----ERC20FixedSupply.sol
--migrations
----2_deploy_ERC20FixedSupply.js
--.secret
--truffle-config.js

环境

"@openzeppelin/contracts": "^3.4.2",
"@truffle/hdwallet-provider": "^2.0.0",
"truffle": "^5.0.22"

其中,各文件内容如下

ERC20FixedSupply.sol

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
pragma solidity >=0.4.22 <0.8.0;

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


//固定总量代币
contract ERC20FixedSupply is ERC20 {
string private message;

constructor(
string memory name, //代币名称
string memory symbol, //代币缩写
uint256 totalSupply //发行总量
) public ERC20(name, symbol) {
message = "OK";
_mint(msg.sender, totalSupply * (10 ** decimals()));
}
}

2_deploy_ERC20FixedSupply.js

1
2
3
4
5
6
7
8
//固定总量代币
const ERC20FixedSupply = artifacts.require("ERC20FixedSupply");

module.exports = function (deployer) {
deployer.deploy(ERC20FixedSupply,
//构造函数的参数
"My Golden Coin", "MGC", 1000000000);
};

细节

我们主要说两种转移方式

  • transfer
  • transferFrom

放一下公共函数。

1
2
3
4
5
6
7
8
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");

_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}

transfer

1
2
3
4
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}

这个简单,不多说了。

transferFrom

1
2
3
4
5
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true;
}

transferForm 的意思是,把你的币的多少额度给一个账户,这个账户可以操纵你额度内的币。

上面的 transferForm 的执行顺序是

  • 先执行 transfer 不管账户有没有额度
  • 再执行 approve 校验,如果额度不足,则回滚交易

为什么会先执行 transfer ,再判断呢?

主要是可以节省 gas ,先看两个方法差异

先判断

  • 先判断是否有额度
  • 转移
  • 进行额度减少

后判断

  • 转移
  • 额度减少「如果出错则会回滚」

其实,也可以先

  • 额度减少
  • 转移

这样,如果,额度不够,只会执行一步,更能减少 gas

请我喝杯咖啡吧~