前置介绍
这是一个将 ERC20 Token 映射为主网币的一个合约。
- Token 地址: 0x9eb7006b8b9010a9856f20611af462f872f6a40e
- 合约代码 : https://etherscan.io/token/0x9eb7006b8b9010a9856f20611af462f872f6a40e#code
- CoinMarketCap : https://coinmarketcap.com/currencies/cononchain/
- 官网: https://www.canonchain.com/
场景描述
在 canonchain 募资的时候,只有老的测试链,生产环境的链没有,所以借助以太坊网络发 ERC20 代币。但是 2019 年 6 月,生产链已经完成了。所以开启将 ERC20 代币,映射到主网币的业务。
合约分析
只有一个 CZRMainNetMapping
合约,合约是基于pragma solidity >=0.4.0 <0.7.0;
开发。
合约内注意做以下的事情
- 构造函数: 初始化 Token 地址,并且实例化出
token t;
。- 实例化之后再使用,可以节省很多 gas
- 前置判断,调用判断(必须 Token 合约调用)
pragma solidity >=0.4.0 <0.7.0;
interface token {
function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);
}
contract CZRMainNetMapping {
address tokenAddress;
mapping(bytes=>uint) private record;
token t;
event Mapping(uint indexed amount,bytes czrAddr,address from,uint time);
constructor(address _CZRAddress) public {
tokenAddress=_CZRAddress;
t = token(tokenAddress);
}
/// @notice impl tokenRecipient interface
function receiveApproval(address _from, uint256 _value, address _token, bytes memory _extraData)
public OnlyTokenAddressCanCall {
require(
_token == tokenAddress
&&_extraData.length == 32
&&_value>0
&&record[_extraData]<record[_extraData]+_value
);
t.transferFrom(_from, address(this), _value);
record[_extraData]+=_value;
emit Mapping(_value,_extraData,_from,now);
}
function getRecord(bytes memory _extraData) view public returns(uint amount){
return record[_extraData];
}
modifier OnlyTokenAddressCanCall(){
require(msg.sender==tokenAddress);
_;
}
}
这里比较有意思的是 record
的结构,使用的是 bytes
结构,然后可以通过 getRecord(czrAddress)
来查询到应该得到多少数量的主网币币。