废话不少,先上完整代码:% d' |- x: c) ^, S
- pragma solidity ^0.4.24;* B8 b1 ~; V+ X
- library SafeMath { /**( Y/ u1 A7 @7 o" [# f& W" V
- * @dev Multiplies two numbers, throws on overflow.
- */
- function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c)- y& N; D5 a. }
- { if (_a == 0) { return 0;' e3 |6 _/ U# Y! [. u1 R
- }
- c = _a * _b;
- assert(c / _a == _b); return c;: Q/ G9 T5 X6 k; D: v+ u
- } /**, ?8 W* k, |0 D* ]
- * Integer division of two numbers, truncating the quotient.
- */
- function div(uint256 _a, uint256 _b) internal pure returns (uint256) { return _a / _b;& C. w, z1 U, _4 Y. J" {
- } /**
- * Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
- */
- function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {2 |* d, [& P8 p( O% N% E8 c
- assert(_b = _a); return c;* n: Y7 p0 o/ M' }
- }% Q7 Z. C; U* V$ E/ D" h
- }
- contract ERC20 {1 f" T3 B7 j' d8 n9 D0 g* f b% u
- uint256 public totalSupply; function balanceOf(address _who) `! y0 Y4 v+ Y3 ?, q, M
- public view returns (uint256); & F; o# x) v( a
- function allowance(address _owner, address _spender) public view returns (uint256); 6 ]! H+ ?( e3 Y: K# @ N4 G
- function transfer(address _to, uint256 _value) public returns (bool); e) s7 \; V7 w8 _1 h- D, a
- function approve(address _spender, uint256 _value) public returns (bool); ' ?9 b8 H( p# D* [
- function transferFrom(address _from, address _to, uint256 _value) public returns (bool);
- event Transfer( address indexed from, address indexed to, uint256 value); 0 H6 B5 N3 S; [5 I
- event Approval(address indexed owner, address indexed spender, uint256 value);
- event Burn(address indexed from, uint256 value);
- }contract StandardToken is ERC20 {
- using SafeMath for uint256;
- mapping(address => uint256) balances;7 S. }* {' I8 G. H) K, }. s8 U+ ^
- mapping (address => mapping (address => uint256)) internal allowed; /**# ]& \- w- l3 \" F+ {
- * Gets the balance of the specified address./ z" |6 Q1 D! p1 q
- * @param _owner The address to query the the balance of.6 ?% v, h3 O: u" W2 T
- * @return An uint256 representing the amount owned by the passed address.
- */7 M. p# g/ ~7 `7 z+ o
- function balanceOf(address _owner) public view returns (uint256) 1 a; {& h' ]# `4 _
- { return balances[_owner];
- } /**
- * Function to check the amount of tokens that an owner allowed to a spender.
- * @param _owner address The address which owns the funds.
- * @param _spender address The address which will spend the funds.$ Y6 u$ K G/ Z' w, [
- * @return A uint256 specifying the amount of tokens still available for the spender.: \! a3 V" g S8 A: T2 j ~ j. I
- */: V3 ^& I3 _6 D& ?( u) x+ i9 C
- function allowance(address _owner, address _spender) public view returns \. B5 S; L6 V$ I5 C
- (uint256){ return allowed[_owner][_spender]; ?2 u& P; Y. K4 g5 m
- } /**
- * Transfer token for a specified address3 r5 m4 A9 O s: G+ r# e
- * @param _to The address to transfer to.8 M3 b: n6 A6 j6 H& Z! N1 j
- * @param _value The amount to be transferred.
- */4 p* P( e# x$ I3 d
- function transfer(address _to, uint256 _value) public returns
- (bool) { require(_value = oldValue) {
- allowed[msg.sender][_spender] = 0;
- } else {
- allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
- }) J0 l* k( \. j7 I
- emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true;
- } & y. I9 O( Y" ^! B; U: E( X) V
- /**
- * Destroy tokens; g5 M, o" I. H* B2 j. o. F
- *
- * Remove `_value` tokens from the system irreversibly
- *6 t# g% z* v! }0 i1 M5 t+ ~ {
- * @param _value the amount of money to burn
- */
- function burn(uint256 _value) public returns (bool success)! ^# M- d+ r/ Z
- { require(balances[msg.sender] >= _value);
- balances[msg.sender] = balances[msg.sender].sub(_value);
- totalSupply = totalSupply.sub(_value);
- emit Burn(msg.sender, _value); return true;
- } /**
- * Destroy tokens from other account
- *4 u- Z) k* R& K
- * Remove `_value` tokens from the system irreversibly on behalf of `_from`.
- *
- * @param _from the address of the sender) M2 P N+ M7 b" z
- * @param _value the amount of money to burn+ m- Z" M% W* X7 a+ ?! I
- */4 I9 `2 N B2 p! E+ p+ I
- function burnFrom(address _from, uint256 _value) public returns (bool success) 7 k) u8 j% c" X1 H- D4 Z/ ^
- { require(balances[_from] >= _value);
- require(_value
这些代码是什么意思呢?9 M2 @8 Q# J( V( S8 K7 U5 G; ]
一、ERC20(EIP-20)说明$ H! F) ]2 z% d5 |; N
ERC20是一个标准的token接口规范:A standard interface for tokens) P# e6 x+ h1 G i% V/ A" ?3 {
该接口的官网说明在下面的链接:https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
我们来简单介绍下这个接口规范,规范里面定义了9个方法和2个事件
9个方法包括:; W/ P$ b/ B5 W* f3 h
返回token的名字
function name() view returns (string name)
返回token的代码
function symbol() view returns (string symbol)
返回token的小数点位数# C' w9 y! |( p8 A* x1 V C
function decimals() view returns (uint8 decimals)/ U; L Q4 e0 `" I3 j5 Q5 y- a+ o
返回供应总量7 q' H. z6 p+ f3 b0 l* \# s
unction totalSupply() view returns (uint256 totalSupply)# O# \6 y0 W' s B5 r- h# k+ w
查询某个地址的余额
function balanceOf(address _owner) view returns (uint256 balance)
给某个地址转账,如果余额不足,该方法必须抛出异常而不是返回false
function transfer(address _to, uint256 _value) returns (bool success)
从from地址转账到to地址,该方法用于委托给其他合约代理你转账
function transferFrom(address _from, address _to, uint256 _value) returns (bool success)
允许多次从您的帐户委托到_spender地址,最高_value金额。如果再次调用此函数,则会覆盖当前允许值_value
function approve(address _spender, uint256 _value) returns (bool success)
返回_spender仍允许退出的金额_owner; u; N) n; n+ C/ H5 i
function allowance(address _owner, address _spender) view returns (uint256 remaining)9 w: | L- q e& c! }1 N
2个事件包括:0 N; |, k7 l4 d
转移令牌时必须触发,包括零值转移,注意:创建新token的合约应该触发Transfer事件,即从_from地址设置为0x0创建token的时候* g' p" E% _( d, H
event Transfer(address indexed _from, address indexed _to, uint256 _value)& }! _& I: F0 i6 s5 @
委托转账必须触发 ]3 J/ t0 d* r. P# S9 ~. j& ?( `0 S. q
event Approval(address indexed _owner, address indexed _spender, uint256 _value)# ]! T- P( g' d5 y
0 i% D g- i; \% n
$ k! f! \. L' m. b- z" D/ Y6 e6 a+ W) v8 @
二、代码解释, e' [$ `! W# N' `: B
代码包括几部分:5 B4 G! ?1 b6 W7 d8 M- I3 v
) X3 l$ F/ N: Q0 D
安全的数学计算库3 } B" ?# C) D9 L; C. h4 E, t5 p
0 C: ~1 V( X: B
contract类 ERC20,主要针对ERC20规范定义方法和事件
+ x w2 C+ c) T0 n K
contract类StandardToken继承ERC20,定义具体的方法实现. T. l1 V( Q3 L
contract 类MyTokenERC20集成StandardToken,定义名词,代号,总供应量和创建token