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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
| pragma solidity ^0.4.24;
import "./BasicToken.sol"; import "./ERC20.sol";
/** * @title 标准 ERC20 token * * @dev 实现基础的标准token * @dev https://github.com/ethereum/EIPs/issues/20 * @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol */ contract StandardToken is ERC20, BasicToken { mapping (address => mapping (address => uint256)) internal allowed;
/** * @dev 从一个地址向另外一个地址转token * @param _from 转账的from地址 * @param _to address 转账的to地址 * @param _value uint256 转账token数量 */ function transferFrom( address _from, address _to, uint256 _value ) public returns (bool) { // 做合法性检查 require(_to != address(0)); require(_value <= balances[_from]); require(_value <= allowed[_from][msg.sender]); //_from余额减去相应的金额 //_to余额加上相应的金额 //msg.sender可以从账户_from中转出的数量减少_value balances[_from] = balances[_from].sub(_value); balances[_to] = balances[_to].add(_value); allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); // 触发Transfer事件 emit Transfer(_from, _to, _value); return true; }
/** * @dev 批准传递的address以代表msg.sender花费指定数量的token * * Beware that changing an allowance with this method brings the risk that someone may use both the old * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * @param _spender 花费资金的地址 * @param _value 可以被花费的token数量 */ function approve(address _spender, uint256 _value) public returns (bool) { //记录msg.sender允许_spender动用的token allowed[msg.sender][_spender] = _value; //触发Approval事件 emit Approval(msg.sender, _spender, _value); return true; }
/** * @dev 函数检查所有者允许的_spender花费的token数量 * @param _owner address 资金所有者地址. * @param _spender address 花费资金的spender的地址. * @return A uint256 指定_spender仍可用token的数量。 */ function allowance( address _owner, address _spender ) public view returns (uint256) { //允许_spender从_owner中转出的token数 return allowed[_owner][_spender]; }
/** * @dev 增加所有者允许_spender花费代币的数量。 * * allowed[_spender] == 0时approve应该被调用. 增加allowed值最好使用此函数避免2此调用(等待知道第一笔交易被挖出) * From MonolithDAO Token.sol * @param _spender 花费资金的地址 * @param _addedValue 用于增加允许动用的token牌数量 */ function increaseApproval( address _spender, uint _addedValue ) public returns (bool) { //在之前允许的数量上增加_addedValue allowed[msg.sender][_spender] = ( allowed[msg.sender][_spender].add(_addedValue)); //触发Approval事件 emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true; }
/** * @dev 减少所有者允许_spender花费代币的数量 * * allowed[_spender] == 0时approve应该被调用. 减少allowed值最好使用此函数避免2此调用(等待知道第一笔交易被挖出) * From MonolithDAO Token.sol * @param _spender 花费资金的地址 * @param _subtractedValue 用于减少允许动用的token牌数量 */ function decreaseApproval( address _spender, uint _subtractedValue ) public returns (bool) { uint oldValue = allowed[msg.sender][_spender]; if (_subtractedValue > oldValue) { //减少的数量少于之前允许的数量,则清零 allowed[msg.sender][_spender] = 0; } else { //减少对应的_subtractedValue数量 allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue); } //触发Approval事件 emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true; }
}
|