ERC20 标准,是ETH上的一种合约标准。固定了事件和对应的接口
contract ERC20Interface {
function totalSupply() public constant returns (uint);
function balanceOf(address tokenOwner) public constant returns (uint balance);
function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
function transfer(address to, uint tokens) public returns (bool success);
function approve(address spender, uint tokens) public returns (bool success);
function transferFrom(address from, address to, uint tokens) public returns (bool success);
event Transfer(address indexed from, address indexed to, uint tokens);
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
string public constant name = "TEST Token";
string public constant symbol = "TST";
uint8 public constant decimals = 18; // 18 is the most common number of decimal places
uint256 public _totalSupply;
}
合约分为 函数和事件变量,三个部分,
变量
变量在 contract 里面是全局的。定义了Token 的名称符号和精度。
函数
totalSupply
可以看到函数部分,只是规定了接口名称。其中的实现逻辑就是开发者自行定义了。
比如这里的totalSupply 就是一个可以自定义的函数,这里的返回逻辑可以是一个定值。 或者是一个自动Burn的逻辑。
balanceOf
这里的balanceOf,就要说到 ETH 的模型了。ETH 是账户模型,不是UTXO 的模型。所以这里的 balance 在合约里面是有状态的。地址和与余额之间有着对应的关系。
// 这里保存着这个账户下的该Token的余额
mapping (address => uint256) public balances
// 这里是一个重要的授权额度,也就是允许 外层addr 操作 内层 addr 的该Token 的数量。
// 所以一般的 授权额度就是这里。
mapping (address => mapping (address => uint256)) public allowed
那么balanceOf这个就很好实现了,传入地址,返回地址在这个map 中的数量即可
function balanceOf(address tokenOwner) public constant returns (uint balance) {
return balances[tokenOwner];
}
transfer
前面提到的 Token 实际上只是一个 账户的mapping,我们可以理解这个合约存储了每个人的账户以及余额。你的 Token 实际上只是这张合约里面的数据而已,实际上并没有进行转出。所以在这里的逻辑其实和在支付宝中进行转账一样。直接对db中的数据进行操作。
function transfer(address to, uint tokens) public returns (bool success) {
balances[msg.sender] = balances[msg.sender].sub(tokens);
balances[to] = balances[to].add(tokens);
emit Transfer(msg.sender, to, tokens);
return true;
}
这里的msg.sender 是 保留字,实际上就是调用这个合约的账户(钱包 或者 另一个合约)
可以通过代码看到,在sender 的账户上 减去一定数量的token, 接受转账的账户上再增加一定的数量。就完成了最简单的转账操作。如果想实现,收5% 的转账手续费这种逻辑的话,就直接在前面加上一行转给合约方的逻辑就好。
所以这里实现的是本人向另一个账户来进行转账
另外这里emit了 Transfer ,在转账逻辑中没有实际的功能。在这里是一个事件。
如果我们不emit 这个事件的话,实际上我们的逻辑是已经完成了。但是,如果我们想,把完成转账的事件让大家知道,那么这里就需要去emit 这该事件。
var infoContract = web3.eth.contract(ABI INFO);
var info = infoContract.at('CONTRACT ADDRESS');
// 这里的Transfer 是通过ABI 获取的
var transferEvent = info.Transfer();
// 这里进行事件的监听,如果触发了 Transfer 就执行
var transferEvent.watch(function(error, result){
// handle result.args.from result.args.to
});
transferFrom
有了上面的Transfer 逻辑,这里的TransferFrom 也好理解了,其函数基本定义如下
function transferFrom(address from, address to, uint tokens) public returns (bool success){
balances[from] = balances[from].sub(tokens);
allowed[from][msg.sender] = allowed[from][msg.sender].sub(tokens);
balances[to] = balances[to].add(tokens);
Transfer(from, to, tokens);
return true;
}
这里的逻辑比上面复杂一点,第一行是在from 的账户来减去转账的份额。这点很好理解。
第二行稍稍复杂慢慢讲,刚刚前面提到来授权额度。
allowed[from][msg.sender] 这里表示的是 From 账户对 sender(合约调用者)的授权额度,也就是说允许 sender 来对我这一部分钱来进行操作。
所以这里有两个sub,一个是从From 账户中减去这一部分转账额,另一部分是从授权额度中减去from对该sender 的授权额度。(如果失败那么触发回滚,后面再讲)
所以简单来说这部分实现的是一个委托转账的功能
后面的就是换汤不换药的, To 账户增加对应的Token,触发Transfer 事件。
approve
刚刚已经讲了授权额度的事情,就是 A允许B对自己的一部分Token 来进行操作。那么这里的approve 就是来进行这一部分授权的。
function approve(address spender, uint tokens) public returns (bool success) {
allowed[msg.sender][spender] = tokens;
Approval(msg.sender, spender, tokens);
return true;
}
可以看到,两个参数一个是 被授权的地址,还有一个是 授权的 Token 份额。前面的委托转账的部分,就是需要在这里进行份额的扣除。
同样的这里有 Approval 事件,用于通知Dapp,这里的动作完成。
allowance
用于检查当前的授权额度,直接进行return来进行返回。
function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
reutrn allowed[_owner][_spender]
}
totalBalance
这里返回总的调用量,经典的实现,就是直接返回 _totalSupply
function totalSupply() public constant returns (uint) {
return _totalSupply
}
当然,这里拓展一下,除了协议的本身逻辑我们也可以进行自我拓展。
比如我这里就可以搞一个增发的逻辑,之前的total 的数量不够。
function mintToken(address target, uint256 mintedAmount) onlyOwner public {
balances[target] += mintedAmount;
_totalSupply += mintedAmount;
emit Transfer(address(0), address(this), mintedAmount);
emit Transfer(address(this), target, mintedAmount);
}
后
过了五年的时间,又一次开始学习智能合约。科技如果不去发展它得到的不是停止不前,而是退步。
上个世纪美国登上了月球,现在却上不去了。
希望这次自己可以坚定的学下去。知道自己想要什么就很幸福。