原文链接:http://blog.51cto.com/clovemfong/2170725
获取到18.75个ETH测试币
三套测试环境的测试币我们均已获得,现在我们可以开始代码设计工作了。
三.代码设计解读
以上信息中,我们姑且先关注一下总量: 500,000,000 HT,其他信息均为交易所信息,暂时不关注,现在,我们开始通过ERC20标准实现我们自己的Token合约。
4.1 创建合约接口 EIP20Interface
首先定义一个合约EIP20Interface,将ERC20标准中需要实现的所有方法与事件全部进行引用,作为Token合约的父合约,用于被其他合约集成使用。
pragma solidity ^0.4.24;
contract EIP20Interface{
/
//获取token名字,比如”BruceFeng Coin”
function name() view returns (string name);
//获取Token简称,比如”BFC”
function symbol() view returns (string symbol);
//获取小数位,比如以太坊的decimals为18
function decimals() view returns (uint8 decimals);
//4.获取token发布的总量,比如HT 5亿
function totalSupply() view returns (uint256 totalSupply);
/
//获取token发布的总量,比如HT 5亿
function totalSupply() view returns (uint256 totalSupply);
/
//获取_owner地址的余额
function balanceOf(address _owner) public view returns (uint256 balance);
//主动转账:当前地址主动发起转账,从当前地址向_to地址转入_value个Token
function transfer(address _to, uint256 _value)public returns (bool success);
//被动转账:允许_to地址从_from(一般为当前地址)向_to转_value个Token
function transferFrom(address _from, address _to, uint256 _value) returns (bool success);
//允许_spender从自己(调用方)账户转走_value个Token
function approve(address _spender, uint256 _value) returns (bool success);
//自己_owner查询__spender地址可以转走自己多少个Token
function allowance(address _owner, address _spender) view returns (uint256 remaining);
//转账的时候必须要调用的事件,比如Tranfer,TransferFrom
event Transfer(address indexed _from, address indexed _to, uint256 _value);
//成功执行approve方法后调用的事件
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
请严格参照3.规范解读中的英文网页进行对比查看,我们此处将网页中需要实现的方法全部贴入代码中,在下面会依次实现。
3.2 创建继承合约 BFCToken
contract BFCToken is EIP20Interface {
// 合约体
}
创建一个新合约名为BFCToken作为子类集成EIP20Interface合约中的所有方法。
3.3 设置Token合约参数
//1.获取token名字,比如”BruceFeng Coin”
string public name;
//2.获取Token简称,比如”BFC”
string public symbol;
//3.获取小数位,比如以太坊的decimals为18
uint8 public decimals;
//4.获取token发布的总量,比如HT 5亿
uint256 public totalSupply;
在合约标准中,通过function name() view returns (string name);实现,由于这些变量是存储固定信息的变量,不参与任何运算,只为显示所需,所以,通过public类型进行声明即可自动提供变量值的获取方法,这是行业内的常规做法,大家可以先参考实现,所以,我们将获取这四个参数的函数都先注释掉。
3.4 定义存储变量
这两个变量非常重要,请仔细思考
//存储地址余额
mapping(address=>uint256) balances ;
//存储允许转出的金额
mapping(address=>mapping(address=>uint256)) allowances;
balances 存储账户余额
如balance[“0xca35b7d915458ef540ade6068dfe2f44e8fa733c”]=10000
allowances 允许转出的金额
key :0x18850c9cE7B2274EbB0c78e6221844AC76715494value : key : 0xca35b7d915458ef540ade6068dfe2f44e8fa733c value : 100value : key : 0xxv3fe7d915458ef540ade6068dfe2f44e8fa34xb value : 2001.表示地址0x18850c9cE7B2274EbB0c78e6221844AC76715494允许地址0xca35b7d915458ef540ade6068dfe2f44e8fa733c从自己账户中转出100个TOKENmap[0x18850c9cE7B2274EbB0c78e6221844AC76715494][0xca35b7d915458ef540ade6068dfe2f44e8fa733c]=1002.表示地址0x18850c9cE7B2274EbB0c78e6221844AC76715494允许地址0xxv3fe7d915458ef540ade6068dfe2f44e8fa34xb从自己账户中转出200个TOKENmap[0x18850c9cE7B2274EbB0c78e6221844AC76715494][0xxv3fe7d915458ef540ade6068dfe2f44e8fa34xb]=200
请仔细参考以上讲解说明,此处均为被动转账模式。
3.5 定义构造函数
function BFCToken(string _name,string _symbol, uint8 _decimals,uint256 _totalSupply) public{
name = _name;
symbol = _symbol;
decimals = _decimals;
totalSupply = _totalSupply;
balances[msg.sender] = _totalSupply;
}
通过该函数定义部署Token合约时的传入参数
3.5 查询地址余额 balanceOf
function balanceOf(address _owner) public view returns (uint256 balance){
return balances[_owner];
}
查询指定地址拥有该Token的数量
3.5 主动转账 transfer
function transfer(address _to, uint256 _value)public returns (bool success){
require(_value >0 && balances[_to] + _value > balances[_to] && balances[msg.sender] > _value);
balances[_to] += _value;
balances[msg.sender] -= _value;
Transfer(msg.sender, _to,_value);
return true;
}
转账:从自己账户向地址_to地址转入_value个Token
3.6 被动转账
实现转账批准:approve
function approve(address _spender, uint256 _value) returns (bool success){
//定义依赖条件,转账金额>0 并且 被转账户余额>转账金额
require(_value >0 && balances[msg.sender] > _value);
//将转账金额存入allowances集合中,对应关系可参考···3.4定义存储变量···
allowances[msg.sender][_spender] = _value;
//触发Approval事件
Approval(msg.sender,_spender,_value);
return true;
}
允许_spender从自己(合约调用方msg.sender)账户转走_value个Token
实现批准金额查看:allowance
functionallowance(address _owner, address _spender)viewreturns(uint256 remaining){returnallowances[_owner][_spender]; }
查询当前地址_owner(msg.sender)可以被_spender地址多少个Token
创建被动转账函数:transferFrom
function transferFrom(address _from, address _to, uint256 _value) returns (bool success){
//取出本次当前地址对中允许转账的金额
uint256 allowan = allowances[_from][_to];
/定义依赖条件:
1. 允许转账的金额 > 转出的金额
2. 转出方地址的余额>=转出的金额
3. 转入方地址务必是当前账户地址
4. 转入方转账后地址务必大于原来余额
*/
require(allowan > _value && balances[_from] >= _value && _to == msg.sender && balances[_to] + _value>balances[_to]);
//将本次转账金额从允许转账金额中扣除
allowances[_from][_to] -= _value;
//将本次转账金额从转出方余额中扣除
balances[_from] -= _value;
//将本次转账金额加入到转入方余额中
balances[_to] += _value;
//触发Transfer事件
Transfer(_from,_to,_value);
return true;
}
<img class="preview" src="http://i2.51cto.com/images/blog/201809/05/b5129642bda046c7306727f4f750656a.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk="> 网络异常 [取消](javascript:void(0)) [重新上传](javascript:void(0))
读者可以继续执行转账测试工作,如从地址2转入地址1中。
六.学习用途申明
本文所有内容均为学习交流使用,各位技术人在进行技术研究以及业务落地的过程中切记以遵守国家法律为前提,合法开展相关技术支撑的业务与市场活动。
最后,祝大家学习愉快!