废话不少,先上完整代码:8 D. Q# U. f$ p; K1 X& V! C
- pragma solidity ^0.4.24;
- library SafeMath { /**7 S4 p/ P+ G5 l2 Q5 t" F8 F
- * @dev Multiplies two numbers, throws on overflow.& e$ p9 K& a" w1 V
- */, I% X2 G! _' {; r8 z/ |- x6 W" l' P
- function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c)4 I# p% j5 A7 j
- { if (_a == 0) { return 0;: g* b! t* ^- m1 ?$ t; m
- }! L' h; d5 {! w# L$ F. o+ Z
- c = _a * _b;
- assert(c / _a == _b); return c;
- } /**- P7 }9 q$ B4 y: q7 a
- * Integer division of two numbers, truncating the quotient.4 v7 O% @0 M% S! S G5 E- a
- */3 W0 s$ |' d) V; w' }
- function div(uint256 _a, uint256 _b) internal pure returns (uint256) { return _a / _b;" T: c2 V( J9 j4 G' x
- } /**
- * Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend)./ {& S: _' P, b
- */
- function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {. C7 p) b j( v7 g
- assert(_b = _a); return c;) W3 g# C4 Y0 _# r( x
- }/ [8 o: [- ~! {' S' q
- }8 a! q: \+ j9 v* K) G# c" k
- contract ERC20 {8 S X1 m, L; A. W9 _
- uint256 public totalSupply; function balanceOf(address _who); D4 ~* Q* ^5 m5 X7 `6 U
- public view returns (uint256);
- function allowance(address _owner, address _spender) public view returns (uint256);
- function transfer(address _to, uint256 _value) public returns (bool);
- function approve(address _spender, uint256 _value) public returns (bool); & g. l' h; u: d1 i2 k1 Y
- function transferFrom(address _from, address _to, uint256 _value) public returns (bool); 5 m. A" A& `! R; e3 Q
- event Transfer( address indexed from, address indexed to, uint256 value);
- event Approval(address indexed owner, address indexed spender, uint256 value);
- event Burn(address indexed from, uint256 value);
- }contract StandardToken is ERC20 {8 x" ?: ^5 `8 V' K8 I) s
- using SafeMath for uint256;5 G9 q8 z+ u- B: Y. e- C
- mapping(address => uint256) balances;- v% V3 W5 y" L: S& `0 o/ `
- mapping (address => mapping (address => uint256)) internal allowed; /**
- * Gets the balance of the specified address.* h" j- i: V$ Y8 M) t: ?
- * @param _owner The address to query the the balance of.* b( F3 u+ d. F2 ^
- * @return An uint256 representing the amount owned by the passed address.
- */
- function balanceOf(address _owner) public view returns (uint256) " Z$ t) g$ c \& n
- { return balances[_owner];
- } /**
- * Function to check the amount of tokens that an owner allowed to a spender.; K( n+ ?5 g y3 q& w: p9 e) a
- * @param _owner address The address which owns the funds.4 R0 i2 e+ f( z) \
- * @param _spender address The address which will spend the funds.! C( Q' j0 L7 Z* ]' h' H
- * @return A uint256 specifying the amount of tokens still available for the spender.
- */
- function allowance(address _owner, address _spender) public view returns
- (uint256){ return allowed[_owner][_spender];$ i* G3 M \, z7 |2 @/ g
- } /**" z1 r7 M5 ~3 Q8 w4 L
- * Transfer token for a specified address1 c$ Z \4 j( s2 [) h
- * @param _to The address to transfer to.
- * @param _value The amount to be transferred.
- */
- function transfer(address _to, uint256 _value) public returns & H Z. \$ z; H) q1 y0 U+ u* u" f
- (bool) { require(_value = oldValue) {- r. ~& \! z3 D* I! p
- allowed[msg.sender][_spender] = 0;; U5 m6 F7 H+ P6 ]0 V
- } else {1 y8 V8 u( w0 H9 ?2 k P: r2 [5 N9 c
- allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);9 z6 D! D- o2 F N8 |/ ^) Z! x
- }
- emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true;, D1 V, @7 b8 U6 H4 [% o' O9 [* Q+ I
- } 6 z. D5 M3 L% u7 u$ U1 K6 U
- /**8 }) ~# d, C$ Y+ n: h6 s
- * Destroy tokens; v O- E+ K( t- i# @. j
- *4 `6 G6 i' E( s$ }: F# d
- * Remove `_value` tokens from the system irreversibly
- *. p) y2 o2 T# V* a9 z" Q& W/ h! p
- * @param _value the amount of money to burn/ Z" Z$ y2 \! u0 f& c/ n6 |
- */
- function burn(uint256 _value) public returns (bool success)
- { require(balances[msg.sender] >= _value);
- balances[msg.sender] = balances[msg.sender].sub(_value);
- totalSupply = totalSupply.sub(_value); * V$ q7 s- }- D' g) _
- emit Burn(msg.sender, _value); return true;
- } /**
- * Destroy tokens from other account6 J* R7 |, W* {* ^3 P; }
- *
- * Remove `_value` tokens from the system irreversibly on behalf of `_from`.
- *
- * @param _from the address of the sender: u/ n, Z6 \6 E. s
- * @param _value the amount of money to burn. Z3 w9 _& f/ l
- */
- function burnFrom(address _from, uint256 _value) public returns (bool success)
- { require(balances[_from] >= _value); 9 o4 {, _3 D- t/ [: ~: E
- require(_value
这些代码是什么意思呢?4 t) d& Z8 B7 A4 d* ~3 ^7 B' K2 ^
一、ERC20(EIP-20)说明
ERC20是一个标准的token接口规范:A standard interface for tokens* k9 V6 u$ Q: ]3 z1 s" i7 x+ N" {
该接口的官网说明在下面的链接:https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
我们来简单介绍下这个接口规范,规范里面定义了9个方法和2个事件* T, N; T7 K. {4 G; F
9个方法包括: M# s# t: u# }& Q
返回token的名字6 {" V' H# V5 l) I5 |
function name() view returns (string name)
返回token的代码7 o, X! V) h, Q, Q' o
function symbol() view returns (string symbol)
返回token的小数点位数
function decimals() view returns (uint8 decimals)- D. l7 c6 e, U, `, ?) _+ y3 j9 u
返回供应总量
unction totalSupply() view returns (uint256 totalSupply)
查询某个地址的余额5 C+ F+ F% g9 w8 c/ V7 O
function balanceOf(address _owner) view returns (uint256 balance)$ K4 [5 @2 G) O. z* Y) ~$ U! j
给某个地址转账,如果余额不足,该方法必须抛出异常而不是返回false- b, V- f' o8 O9 e t0 q4 q5 Q
function transfer(address _to, uint256 _value) returns (bool success)
从from地址转账到to地址,该方法用于委托给其他合约代理你转账
function transferFrom(address _from, address _to, uint256 _value) returns (bool success)$ U; S1 \# i1 H9 K7 u# S
允许多次从您的帐户委托到_spender地址,最高_value金额。如果再次调用此函数,则会覆盖当前允许值_value9 z# G1 w- S: O* v
function approve(address _spender, uint256 _value) returns (bool success). {" H8 w" O, D$ Y& A0 ]6 o
返回_spender仍允许退出的金额_owner( ]0 i4 ]6 `9 p! M# @* ~9 h" @( L% D
function allowance(address _owner, address _spender) view returns (uint256 remaining)" ]8 K Q0 Y H* ~3 Z4 |+ ^" H
2个事件包括:1 t# C Y1 W* k& t$ x9 |
转移令牌时必须触发,包括零值转移,注意:创建新token的合约应该触发Transfer事件,即从_from地址设置为0x0创建token的时候
event Transfer(address indexed _from, address indexed _to, uint256 _value)+ V) e0 I4 C2 Y* u/ q
委托转账必须触发% z; a) V6 G2 y$ `9 m: }8 \
event Approval(address indexed _owner, address indexed _spender, uint256 _value)" H, U3 k, q; A/ ^1 e+ `+ ^6 q
二、代码解释2 J; }7 m# X0 w& {+ T6 ?) X
" Y* k6 n2 V0 S- n6 u! b! [
代码包括几部分:0 y% k$ w2 k+ \2 w
/ s. j) K" ~( |8 s1 |3 |1 }
安全的数学计算库
contract类 ERC20,主要针对ERC20规范定义方法和事件2 {. y9 f- g2 T
contract类StandardToken继承ERC20,定义具体的方法实现3 g# t0 z1 n% m9 ?9 @! R
contract 类MyTokenERC20集成StandardToken,定义名词,代号,总供应量和创建token



