发行 ERC 代币的发行已经标准化,最好采用 openzeppelin 的模板,并搭配 solidity5.x 版本和 truffle 工具使用,效果更佳。
1 2 3 4 5 6 7 8 9 10 pragma solidity ^0.5 .0 ; import 'openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol' ;import 'openzeppelin-solidity/contracts/token/ERC721/ERC721Mintable.sol' ;contract MyNFT is ERC721Full, ERC721Mintable { constructor ( ) ERC721Full ("MyNFT" , "MNFT" ) public { } }
1 2 3 4 5 6 7 8 9 10 11 12 pragma solidity ^0.5 .0 ; import 'openzeppelin-solidity/contracts/token/ERC20/ERC20.sol' ;import 'openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol' ;import 'openzeppelin-solidity/contracts/ownership/Ownable.sol' ;contract MyERC20 is ERC20, ERC20Detailed, Ownable { constructor (uint256 initialSupply ) ERC20Detailed ("MyToken" , "MT" , 18 ) public { _mint(msg.sender, initialSupply); } }
Freeze 功能 (openzeppelin-contracts v3.2.0之后) 也叫做 pause 或者 close,具体就是停止 Token 相关的 transfer(转账)功能
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 pragma solidity ^0.5 .0 ; import 'openzeppelin-solidity/contracts/token/ERC20/ERC20.sol' ;import 'openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol' ;import 'openzeppelin-solidity/contracts/ownership/Ownable.sol' ;contract MyERC20 is ERC20, ERC20Detailed, Ownable { bool public closed = false ; event Close(); event Open(); constructor (uint256 initialSupply ) ERC20Detailed ("MyToken" , "MT" , 18 ) public { _mint(msg.sender, initialSupply); } function ( ) external payable { revert("Don't accept ETH" ); } function transfer (address _to, uint _value ) whenOpen public returns (bool ) { return super .transfer(_to, _value); } function transferFrom (address _from, address _to, uint _value ) whenOpen public returns (bool ) { return super .transferFrom(_from, _to, _value); } function close ( ) onlyOwner whenOpen public { closed = true ; emit Close(); } function open ( ) onlyOwner whenClosed public { closed = false ; emit Open(); } modifier whenOpen ( ) { require (!closed); _; } modifier whenClosed ( ) { require (closed); _; } }
openzeppelin-contracts v3.2.0版本中的实现代码如下 ERC721Pausable
1 2 3 contract ERC721PresetMinterPauserAutoId is Context, AccessControl, ERC721Burnable, ERC721Pausable { ...... }
MultiSigWallet 多方签名 gnosis 的 multisignature 功能 最为完善。已经有多个生产项目采用此工具。目前此工具合约的 solidity 版本为0.4.15,项目语言版本交旧,但没有发生过安全问题。
首先 ERC20 合约的初始化总金额地址需要给到 MultiSigWallet 的合约地址,由 MultiSigWallet 合约完成多方签名确认后,ERC20 代币从 MultiSigWallet 合约的地址发送到接收人的账户地址。
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 pragma solidity ^0.5 .0 ; import 'openzeppelin-solidity/contracts/token/ERC20/ERC20.sol' ;import 'openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol' ;import 'openzeppelin-solidity/contracts/ownership/Ownable.sol' ;contract MyERC20 is ERC20, ERC20Detailed, Ownable { bool public closed = false ; event Close(); event Open(); constructor (uint256 initialSupply ) ERC20Detailed ("MyToken" , "MT" , 18 ) public { _mint(msg.sender, initialSupply); } function ( ) external payable {} function transfer (address _to, uint _value ) whenOpen public returns (bool ) { return super .transfer(_to, _value); } function transferFrom (address _from, address _to, uint _value ) whenOpen public returns (bool ) { return super .transferFrom(_from, _to, _value); } function close ( ) onlyOwner whenOpen public { closed = true ; emit Close(); } function open ( ) onlyOwner whenClosed public { closed = false ; emit Open(); } modifier whenOpen ( ) { require (!closed); _; } modifier whenClosed ( ) { require (closed); _; } }
Live website 地址在这里 ,以下操作均为https://wallet.gnosis.pm/上的截图。
1.增加钱包。如下图,完成钱包增加配置
2.点击 Wallets Name,即点击’Lcoin’,进入钱包的详细页面,如下图,进入后需要手动添加 Tokens Name,其后点击 Withdraw,最后经过 2 位 Required confirmations 后,Executed 状态变为 Yes
注意,此处,由 MultiSigWallet 合约完成多方签名确认后,ERC20 代币从 MultiSigWallet 合约的地址发送到接收人的账户地址(a825),MultiSigWallet 合约执行 transfer 给到接收人的账户地址(a825),所以 MultiSigWallet 合约的地址上需要有足够的 Eth 作为 gas
即使用 MultiSigWallet 转账时,花费的 gas 是 2 位 Required confirmations 和一次 transfer 的总和
3.如下图,虽然在 MultiSigWallet中可以选择到调用 ERC20 合约中的 close 函数,但是 close 函数并不受 MultiSigWallet 的控制,由onlyOwner,即 msg.sender 单独控制并操作
4.如下图,具体交易的内容在 MultiSigWallet,并配合etherscan 和 MyEtherWallet 中的结果
关联内容 ==> https://willzhuang.github.io/2020/09/07/ERC721%E5%AE%9E%E8%B7%B5/ 实践