Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
本以太坊教程主要是介绍:搭建一个开发环境、编写编译一个智能合约。
; T* ]7 d. {1 ?! k$ k4 S- l' ]; E3 X% F: f( X1 K$ @
    以太坊是什么
8 T! `  w# s8 z7 k% @) j& S+ _
9 w) p2 K9 p( K/ B2 x/ X7 A    以太坊(Ethereum)是一个开源的有智能合约功能的公共区块链平台。通过其专用加密货币以太币(Ether)提供去中心化的虚拟机(“以太虚拟机”EthereumVirtualMachine)来处理点对点合约。0 X% E( w8 {9 G* M( M# j+ W+ _

& B# \" {$ ?& f* [    以太坊的概念首次在2013至2014年间由程序员VitalikButerin,受比特币启发后提出,大意为“下一代加密货币与去中心化应用平台”,在2014年通过ICO众筹得以开始发展。目前以太币是市值第二高的加密货币,仅次于比特币。
7 T: H& W1 u% Q/ I- p3 v% m
8 S3 O3 N5 R+ Z8 G5 w  n    以太坊区块链是什么?
) A& S. ^1 a% g5 c$ ~/ b0 G
9 z/ f4 l  O& p  e: z    以太坊区块链有2个主要组件:  o: L6 K2 j) P: [; `
8 z5 [; K( t/ n0 Z' L
    数据存储:网络中每笔交易都存储在区块链上。当你部署合约时,就是一笔交易。当你执行合约功能时,也是另一笔交易。所有的这些交易都是公开的,每个人都可以看到并进行验证。这个数据永远也无法篡改。为了确保网络中的所有节点都有着同一份数据拷贝,并且没有向区块链中写入任何的无效数据,以太坊使用一个叫做工作量证明的算法来保证网络安全。
8 ~5 J) W3 [+ l* J5 i/ q4 r3 `( N, q/ d- s8 J( X
    代码:就数据的层面而言,区块链就是存储交易。在以太坊的世界里,你可以通过一个叫Solidity的语言编写逻辑/应用代码(也就是智能合约)。然后用solidity编译器将代码编译为以太坊字节码,并将字节码部署到区块链上(也有一些其他的语言可以写合约,不过solidity是到目前为止用得最多也是相对更容易的选择)。所以,以太坊不仅仅会存储交易数据,它还会存储和执行智能合约代码。, p/ x7 }5 j1 g. ^, H6 z, t" d

/ l/ ~& v6 s0 i2 A6 ^( F- o  w    可以简单的理解以太坊区块链的作用就是存储数据和代码,并在EVM(EthereumVirtualMachine,以太坊虚拟机)中执行代码。3 w4 z9 q% R+ d

( B' _. D# f  x+ Z  z& D" d) j% ]    要准备的基础知识
: L3 O# b  z" Y! c, V- a0 p
& G7 I0 M- h0 K( l  K; h    为了进行以太坊开发,你应该对以下语言/技术有基本了解:
6 A+ r' r; p5 |7 _! }
  Z; M; Y: g7 ~; j! v# w! \    熟悉某种面向对象语言(如Python,Java,go)
* J# e+ c8 ^3 H8 {; l4 T; L# }( [; i
    HTML/CSS/Javascript
' z. s9 F) D3 T4 p" `; R) _8 g" d. p+ D
    基本的命令行交互如Linuxshell命令- U+ u# h( i3 x! N7 n% ]8 s1 t4 @

# w3 h$ Z) u" a    理解数据库的基本概念
8 T, `6 E9 y; l5 f  k# A( m  {3 F  H* M- j2 b3 e0 v4 p+ l
    为了构建以太坊去中心化应用即Dapp(Decentralizedapplication),以太坊有一个非常方便的JavaScript库即web3.js,你也可以在一些js框架中直接引入该库构建应用,比如react,angular,vue等。+ n  j, _3 P. Q7 d, P, v
6 ^  Q- L1 {  I7 G# w
    示例:一个以太坊投票应用3 G* g5 y) C7 j6 w( J5 A
! x5 K! F+ x2 `$ v0 ?
    以太坊教程示例中,我们将会构建一个简单的去中心化投票应用。所谓去中心化应用,就是一个不只存在于某一中心化服务器上的应用。在网络中成百上千的电脑上,会运行着非常多的应用副本,这使得它几乎不可能出现宕机的情况。你将会构建一个投票应用,在这个应用中,你可以初始化参与选举的候选者,并对候选者投票,而这些投票将会被记录在区块链上。你将会经历编写投票合约,部署到区块链并与之交互的整个过程。你将会了解什么是一个合约,将合约部署到区块链上并与之交互意味着什么。  `1 m& u! v7 b0 X, R. e" }

2 h4 g! L* H/ M5 c    本质上,区块链就像是一个分布式数据库,这个数据库维护了一个不断增长的记录链表。如果熟悉关系型数据库,你应该知道一张表里有很多行的数据。现在,对数据进行批(batch)量处理(比如每批100行),并将每个处理的批次相连。就可以形成一个区块链了!在区块链里,每个批次的数据就叫一个块(block),块里的每一行就叫一笔交易(transaction)。/ W' p! w, W: P$ [" `5 ~
3 v% n4 x6 B! y
    现在,你对以太坊已经有了基本了解,我们可以开始构建投票的dapp了。这将会加强你对以太坊的认识,并且初略了解以太坊的功能。
' J3 j+ J- C- v! q6 w1 D: Y. ^" u% n" j+ \& l
    以太坊开发环境搭建& x7 _" K2 T) @; n5 L* s8 Q. P

. W1 b; d. U; }    Linux, n( }( b( a6 U' C

# A+ N7 x$ y# Q    示例是Ubuntu16.04下的学习环境搭建,你只需要成功安装了nodejs和npm,就可以继续项目的下一步了。) {4 T8 o( j4 V+ ^  y9 y9 v

$ H0 z  P8 N. N' h3 q4 X    我们通过npm安装ganache和web3包来为以太坊教程提供支撑。我们也需要安装solc来编译合约。
0 U' S, B) Q  a( ?) s8 i$ n
  c& L( e3 C6 `5 w$ Q+ g    下面是安装过程:8 s1 C, ?- o2 ]7 ]- T$ B

. X. B! p3 o9 y& ~* q* F    $sudoapt-getupdate$ w3 M; i  |- Y0 n

2 b( M/ L  `* x1 Z% r9 s3 V% U6 g    $curl-sLhttps://deb.nodesource.com/setup_7.x-onodesource_setup.sh# i' E4 ~9 v" r+ L0 S+ ~* V* C) V
; n8 C& ]4 h) d1 S
    $sudobashnodesource_setup.sh' [( M$ ^. @! t9 `( {. [9 [
' d6 v9 Q3 V/ k" |8 t2 W& v$ W
    $sudoapt-getinstallnodejs% X# A! m( \% t
: A) j2 W# g' k* X9 f
    $node--version7 _7 @# s+ \4 k  v3 ]7 w) Y& n% M

* R6 ]! S0 {0 x! n5 D6 f    v7.4.0( _% t8 y4 j6 j; J1 e

% k9 p* t, J  M# ?) k, w$ [# _5 k    $npm--version
4 S  R, u: V) G2 @. K9 f# Y( S! E2 b" k1 _+ S' i1 O8 c
    4.0.56 `% \" D. T# k2 b# B2 k
; C9 N0 J% {, d4 o
    $mkdir-pethereum_voting_dapp/chapter1+ K2 |2 M& ^  X% p$ N- o

( e! O& F& `  y! d    $cdethereum_voting_dapp/chapter10 P; a3 b; ?8 d) R
5 t- k, O" C+ O' x6 n( [3 J8 n
    $npminstallganache-cliweb3@0.20.1solc
2 [2 T5 |2 Y, B% ^& C5 ^8 d5 U: f5 G2 K  a# K& d
    $node_modules/.bin/ganache-cli
& F, y- C, M7 w! e
, y1 `$ A; e6 M1 d. R* J4 B    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到下面的输出。4 R7 |& T/ {1 u' K2 \
- D3 Q5 g! ^4 E: h
    GanacheCLIv6.0.3(ganache-core:2.0.2)+ q0 x1 Z5 G$ j1 G) q

8 \' C2 E" ?$ u6 f+ \4 c  n" N2 u    AvailableAccounts6 p9 o. G* ?1 R; Y( M
- ]( e: |! d: a. b1 R) |
    ==================
: A" c+ a$ k/ L$ `, n& S' {# r0 m; B
0 h+ F$ z3 Q; b& U$ J+ c    (0)0x5c252a0c0475f9711b56ab160a1999729eccce97
5 \7 k& R- L. h: c3 {/ L& y. m$ v4 G% @$ U9 `
    (1)0x353d310bed379b2d1df3b727645e200997016ba3
% M  E3 h: L- J5 Z& x6 {6 O/ w; }
# l7 z' v& s' `' E) g    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23
1 K7 b& ]: M, L6 m& j$ n! u0 z' H3 W* v  V3 g, \
    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5
/ S( V4 E" k, A& h0 T4 G
7 {6 {$ t- ]9 H, l    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798
1 g9 x# |) G$ r% E; S" X: j- j
- l- z6 [1 Y; N# `: e+ z/ s    (5)0xda695959ff85f0581ca924e549567390a0034058$ ~; S' z( L: {% U9 T, R4 C
2 f( v0 `2 z- G) I0 u" E9 j) T
    (6)0xd4ee63452555a87048dcfe2a039208d1133237903 c3 H$ p' r, a
" X9 s9 n% y. ]: u7 B
    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14
* X& e* W2 [" d" ~0 U: \' S7 r; c  \( h9 N$ s
    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42/ M, I+ {4 V4 u: c' L
' v. t7 R$ w- c0 j
    (9)0x208e02303fe29be3698732e92ca32b88d80a2d360 ]/ o6 P& l6 `8 _2 Z2 ~. a; t
* h% S) _# ?/ X5 M
    PrivateKeys/ h5 N1 ^9 T* x3 I
7 P) o5 \& y8 U8 L
    ==================
, m! ?$ @0 G9 Y, G% ]5 N3 q
& e& U1 |# |; i' ~% h' ]1 f' C. I' @    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b: _0 j' b' m* u$ D. n+ I- O

0 M5 g% K2 z2 E  _, ?- X5 G( h" C' \& x    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603& W0 w: r0 s/ y  b
+ Z) L+ Q+ c3 W% c
    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce990 R: C7 s/ y/ ~7 B
$ O5 t' H% G* m7 Z
    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430
! z8 m6 z6 F/ i
) ~" b: }5 a0 ^    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8
8 \7 M- f# {5 R+ Y/ r" j$ T0 T1 ]
. g- E1 p; p# s- [' f' }    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc7 v# Z& n9 o: I9 [
8 O: _0 X: R6 _# i
    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9
3 d/ P! l( h/ L- c: B$ Z5 s( |7 z7 W  g7 ?
    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d5 k6 \, g' {+ G* m8 k3 |3 k/ C
( }' ^( R$ }2 M3 ]" o
    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
5 P  ]" K* ~& A
* Z* J3 p, v2 ?2 G    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0+ p2 v2 B) ~; h- C* l

3 h" d) r( Z( M/ N' P: Q5 |    HDWallet
* e8 R! @3 F4 S8 _. W: i4 J8 X- v) G" g+ m# ]$ [5 O
    ==================
! J; x0 }/ w( {2 o) C( l8 b+ t/ r0 A
    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella
- \0 s. G( F2 ?2 U; ?/ ?0 t
8 ^2 F3 {1 m, ]/ C$ b! A; s  w+ r    BaseHDPath:m/44'/60'/0'/0/{account_index}
6 \* h! I; V# l9 `! K$ O1 f' ]* V% J' l% \. J5 _; Z
    Listeningonlocalhost:8545$ N  _8 B2 W& I; ?
  o" E( i% C1 Q4 v) @* f3 s: e
    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。, I( Q1 y  @( T; k8 l+ w6 D8 T

( q' ?' y1 r7 m1 O8 T    MacOS* l! G6 j9 K# Z' K- I
+ s8 ~' t2 \3 b: P
    如果你还没有安装homebrew,请按照https://brew.sh/的指示安装homebrew。homebrew是一个包管理器,它可以帮助我们安装开发所需的所有其他软件。按照下面的指示安装所有其他所需的包。
  D4 S) l0 O/ o/ Y4 l
9 P; q/ J) Q* x  @    $brewupdate
1 a! K" f; K- Z5 D- a+ Q# r2 b4 U7 K, Y! h+ N
    $brewinstallnodejs4 n" w* z; j7 ?) b
4 P! i3 v9 G  ~* _8 f+ d0 ^
    $node--version9 q  m7 l5 ~4 w% x1 R- ]% i9 C
7 M# J' q2 G; F
    v7.10.0" A) l, _% a8 c/ H4 y
3 v0 I6 _9 U: @6 }9 R( v% }& J) M
    $npm--version
- Q* V! o) s' @( o) \
; E, y- [7 ?/ ~7 x' C* y7 D+ `    4.2.0
2 v6 \, o9 T. ]6 e  q/ T/ j: E% _3 V! U8 E% a& V
    $mkdir-pethereum_voting_dapp/chapter10 B' U: X" P& N3 B! F

1 u: K% q( q) G$ D) Z2 F& U( {    $cdethereum_voting_dapp/chapter1
7 X5 Y* g" \! [/ z% `& p8 l0 P8 G. W+ e; G
    $npminstallganache-cliweb3@0.20.1solc
" T# S" Y, Z6 Q) w, `% I) [6 J
; n# e. N3 z& k( s! Y    $node_modules/.bin/ganache-cli, l9 a% ?, ]# h1 F' G) g& m

+ `; v2 z" y% r% a8 r( f+ r* c    我们通过npm安装ganache和web3包。我们也需要安装solc来编译合约。* {8 J( V' \9 K! r3 g" P/ ~! {/ B" y
4 P" H% t1 [/ l, T) [8 Q1 ^
    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到右图所示的输出。- c- w4 a0 K8 q8 o' s+ O) ?
/ d) l- C4 ]4 [8 v" a3 a9 @+ q
    GanacheCLIv6.0.3(ganache-core:2.0.2)
9 ]$ R+ Z2 G* k1 ^, L8 w' \0 X7 T: h/ V7 [! m5 q* [
    AvailableAccounts- @3 _0 T1 s3 `( {9 P6 p5 K
# P8 l. o: e0 l9 |" n
    ==================
6 N; z% V3 _# o& u6 @9 w
. ^1 \+ a9 b+ P1 Q7 w" w    (0)0x5c252a0c0475f9711b56ab160a1999729eccce97
8 |! a( M+ T( j+ G  `. G( r+ w! n& d4 F  c9 L
    (1)0x353d310bed379b2d1df3b727645e200997016ba3; `5 ]  Q6 ?7 L' p4 ^
9 B% |, j# j8 y# o9 h/ I0 A$ c
    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23' _# h% Y( t0 L, r$ T+ k- E+ v

/ C7 g+ C: d$ F# ^( A0 f8 H    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5# r' `. O6 N) ?) P5 y# F

6 c$ u/ [7 p1 j) K9 T    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798% o: D" k/ z8 R6 \) j* \( [

$ G1 K0 Y2 j- P- A$ a3 C- W    (5)0xda695959ff85f0581ca924e549567390a0034058
# a7 ~" z9 ^0 U) y% G9 k" s/ z8 r% q5 r( S  B, Y
    (6)0xd4ee63452555a87048dcfe2a039208d113323790
# ]' e: U  P, Y) _. e8 h* z8 ?
3 a+ d) J0 O  f    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14* v( z1 K3 f3 R( R+ A! X  N
5 ~' Y2 B2 ^( L
    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42
; b8 Y: r" l1 q% D1 d! }8 b9 X; P% ~7 j
    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36" y% B6 u  `: X

0 I3 b0 @  R( }5 q/ L    PrivateKeys$ E8 `# F, V0 u. Y
# h' ^! w( d9 m, I: V+ I
    ==================
* o" l0 R6 E; c) a- w& V3 x& ~" O8 w) S$ p$ B$ R. L
    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b+ h) s# B4 m6 c% {2 [* K7 M

( t1 o' W7 n, a; }( I9 ]/ t    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603
( q' f/ d; @6 n7 _! Z: b
" o" V$ u9 Q; U) Y    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99
( a1 m# \0 d& L! P4 |# A/ b$ V( S3 H
    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f354306 g# w. f0 |8 \; M0 M0 U
8 E  C6 D& f' a  ~
    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8% `: {: s. |6 q' L

% h  b+ k' R6 j+ q$ g8 e    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc/ o- ^( _$ g3 t- z: t

  a! [6 R. |; k/ D6 |    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9: Z; N) k! c3 |2 O, w2 ?

3 N% N8 w" n+ d. V* ?: _    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d5 c/ W' G+ |* H' C! n& V8 s2 K/ e

1 ^8 }! o7 U2 |4 ~! h4 o    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
* Q! `6 i# l" c; b; j4 q
9 }3 {) O6 }. u- l: a. f5 o    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0
! n% ~; g4 Q1 s( z' [1 h3 m9 n# g# P% W8 P! a- i" m
    HDWallet
- Y4 ^1 [% ~# |/ B' P% W! [; D2 c+ ]( t( t6 K
    ==================) a' ^5 o/ A: b+ {1 c- a. V! W0 z

. u; ]) \& b& F% g. p& c7 |    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella+ Y; W6 B0 o0 p: k3 D& G
$ z. j  W  v3 @' h4 W
    BaseHDPath:m/44'/60'/0'/0/{account_index}" D$ @9 Y# B8 u2 b

5 a: u6 j7 ?' g+ T2 e& z+ S7 ]) w    Listeningonlocalhost:8545+ g6 J8 M$ K: t7 D, r

& s  |2 ]  s' `* z7 y) i; }8 _5 |# O    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是以太坊账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。& G! _( g" R6 }

% O5 e$ [8 m, w  T4 i7 H    Windows
0 _2 `. Z, i% ~* v
9 K- Q6 W& x2 a: B    安装VisualStudioCommunityEdition。如果你选择定制安装,那么至少应该安装VisualC++(目前的版本是VS2017)2 J2 y5 `$ j4 S; m( a6 c
7 t) J4 L6 R4 f% ?: u+ e; h
    安装WindowsSDKforWindows) [$ L# U, I- D, T4 v6 a

6 a* }; J' e( |    安装Python2.7如果你还没有安装的话,并且确保将它加入到环境变量PATH) p* q) n) Q( a8 {6 M& }
  |/ {9 R+ a' C7 N% {) L$ M
    安装git如果你还没有安装并加入到PATH( A' n0 E3 V& I% O! T

5 C, _  g+ k, `; [( S0 \6 [" ~6 q! l    安装OpenSSL。确保选择了正确的安装包,并且只安装完整版(而不是轻装版)。你必须将OpenSSL安装到推荐安装的位置–不要改变安装路径% A9 W0 E6 T( R7 a  b2 j0 b

7 f  D7 y9 [0 c+ n9 ]    下载和安装nodev8.1.2。不推荐使用版本v6.11.0搭配VS2017  e$ b1 [5 j& }7 G* N6 q+ d
: N3 [. [- V- K- L  J" z6 ?. M% {
    执行命令npminstallganache-cliweb3@0.20.1solc
& ]: o5 C, u: j9 N& e8 k3 k6 R& B
    SolidityContracts
0 y: N# h6 Z* V/ [: P$ {. N. ~% p$ y/ H  r( V2 \; [8 k8 t
    现在已经安装好ganache并运行,我们将会开始编写第一个以太坊智能合约。
. X+ S6 |  J: R* E2 |; F7 l9 Z8 G4 `4 d  }$ g/ K* j0 H
    我们会使用solidity编程语言来编写合约。如果你熟悉面向对象编程,学习用solidity写合约应该非常简单。我们会写一个叫做Voting的合约(可以把合约看成是面对对象编程语言的一个类),这个合约有以下内容:+ z$ x" G; x. q9 B, ]

( ~3 }! E5 ]  [7 K( N0 L    一个构造函数,用来初始化一些候选者。* u, w9 }" S% h: K; t

( Y3 [/ @8 c! _( v$ ?2 ~) j    一个用来投票的方法(对投票数加1)
  E8 W! \1 g6 |7 @$ _8 V. u% N, \9 {" D: Z% H
    一个返回候选者所获得的总票数的方法6 L7 n: N! Q6 |: G8 _
8 a( \  _% X9 v! g
    当你把合约部署到区块链的时候,就会调用构造函数,并只调用一次。与web世界里每次部署代码都会覆盖旧代码不同,在区块链上部署的合约是不可改变的,也就是说,如果你更新合约并再次部署,旧的合约仍然会在区块链上存在,并且数据仍在。新的部署将会创建合约的一个新的实例。7 x+ c, r! }' L1 ~( ?! o* m
2 g, A8 S  C" z* m4 y! `; Q9 I
    pragmasolidity^0.4.18;: R1 m7 h+ q* e; X1 z: h3 M
) B, m9 w7 ]* x; {
    contractVoting{
4 C! U* n% ]- A2 F# v* A1 V% \7 @1 P
    mapping(bytes32=>uint8)publicvotesReceived;7 F7 {0 A2 U/ @- U5 m7 g, n! M
  E2 }& T" A- T
    bytes32[]publiccandidateList;6 X, v' L* V/ v0 k% U
! K- X6 H' g& v- U: _) n
    functionVoting(bytes32[]candidateNames)public{
4 c: A& ~# y- L( {
; C7 A2 O' m; l2 Z    candidateList=candidateNames;
4 @9 x' e1 i+ a% `  H/ [$ s! m  P  V; t
    }
* e# y; Y" i- h; z, U- H9 p1 P8 D0 {% V& e& P8 ]8 U. G
    functiontotalVotesFor(bytes32candidate)viewpublicreturns(uint8){
7 Y! }( e. \3 R3 g( H3 y4 d9 A/ x3 R$ Q& l# x: U
    require(validCandidate(candidate));
+ Y. m2 t! s' k1 A; f# x1 b8 z9 I; X. l
    returnvotesReceived[candidate];
; E4 B8 O% g; e  p" M0 k7 G
+ q0 Z2 R9 a2 R* ~    }
- {  {4 o; _0 E0 h
# K4 X% u: J1 [& |/ Q& n( A6 W* S; a    functionvoteForCandidate(bytes32candidate)public{
1 y# f, z  v# ]( y, c- v/ W- d3 [
, S' t- s7 q4 g/ B; K) _5 x    require(validCandidate(candidate));
$ u4 ~5 _7 I( A  @. y# M
" ?" k3 I  U) w, e6 ~0 w    votesReceived[candidate]+=1;
7 p6 F/ q% }  v4 G4 ^: [/ p: n% x1 y( f+ S
    }
) U+ t$ z: d! W/ J& h& e
$ `# r, K) n7 J4 a3 M7 ~    functionvalidCandidate(bytes32candidate)viewpublicreturns(bool){# Q$ M. h$ |5 i1 k  y/ H9 L
$ q6 g% [4 [; X& g) n
    for(uinti=0;i+ w/ D: V3 P3 A7 k0 Q6 T% u% E, s5 R
! a. }5 v! ^; \
    将右侧代码拷贝到一个叫做Voting.sol的文件中,并保存到chapter1目录下面。& n, C4 p+ y# t' w- z
* S- |' t8 B, ?4 x8 i% S% w
    代码和解释
+ u4 ~' J0 a% {* z) B$ Y
7 Q' o5 ~' q3 y( _& f8 J  ^) o    Line1.我们必须指定代码将会哪个版本的编译器进行编译6 _5 m  [; c- s5 r+ ^
& M! m) \% v  S6 [
    Line3.mapping相当于一个关联数组或者是字典,是一个键值对。mappingvotesReceived的键是候选者的名字,类型为bytes32。mapping的值是一个未赋值的整型,存储的是投票数。
9 Y) u% L2 A; I& j5 g" X& {# y. B) a4 z0 u
    Line4.在很多编程语言中,仅仅通过votesReceived.keys就可以获取所有的候选者姓名。但是,但是在solidity中没有这样的方法,所以我们必须单独管理一个候选者数组candidateList。* F) g* E/ m; i& J! J

2 [+ N3 Y5 {4 c; h* T7 L    Line14.注意到votesReceived[key]有一个默认值0,所以你不需要将其初始化为0,直接加1即可。2 R+ f6 s  e; P& a+ }
2 c( j6 A3 N) u0 c
    你也会注意到每个函数有个可见性说明符(visibilityspecifier)(比如本例中的public)。这意味着,函数可以从合约外调用。如果你不想要其他任何人调用这个函数,你可以把它设置为私有(private)函数。如果你不指定可见性,编译器会抛出一个警告。最近solidity编译器进行了一些改进,如果用户忘记了对私有函数进行标记导致了外部可以调用私有函数,编译器会捕获这个问题。这里可以看到所有的可见性说明符。* k# c5 J0 U+ X: S' U( L
: q* F8 T5 ^( Q. l" P" W
    你也会在一些函数上看到一个修饰符view。它通常用来告诉编译器函数是只读的(也就是说,调用该函数,区块链状态并不会更新)。所有的修饰符都可以在这里看到。6 E5 d* |( [2 f9 g8 E/ M/ q/ J0 _( U' G
2 E) {9 X3 j- q6 L9 X/ X
    编译智能合约6 B! W8 l! n# {- b' J+ o/ k

' l1 w) f8 t% D. O7 v    我们将会使用上一节安装的solc库来编译代码。如果你还记得的话,之前我们提到过web3js是一个库,它能够让你通过RPC与区块链进行交互。我们将会在node控制台里用这个库部署合约,并与区块链进行交互。& H, c% J$ C/ k& o( Y

+ y# J; q1 f6 r: V+ d% Y% e    首先,在终端中运行node进入node控制台,初始化web3对象,并向区块链查询获取所有的账户。
1 e% M" h/ M2 T. j$ u1 [- d" c, M
: y7 n( {9 V/ m2 |7 h4 u+ n    确保与此同时ganache已经在另一个窗口中运行# ~3 s* l) R" H
, ]5 {$ |& z  ?* O& d) l% Q- t5 p
    为了编译合约,先从Voting.sol中加载代码并绑定到一个string类型的变量,然后像下边这样对合约进行编译。
/ D9 B5 v9 }4 u$ s
# l* O, n' n3 x3 z$ T    $node/ a' j2 c5 v0 [2 q/ z+ y5 @7 m
, ?1 }9 \* \2 j5 ^0 Z# [$ m
    Inthenodeconsole
5 V" \. m4 d; R: N- f9 W. ?$ @. R! ^4 ]# A# d/ |; R2 w/ f
    >Web3=require('web3')
( X0 p- W' m4 L. A0 @' X: M- y* P4 V( |0 `, E6 M( N! Z% j$ `" U
    >web3=newWeb3(newWeb3.providers.HttpProvider("http://localhost:8545"));
) s+ p; K+ M# J5 R! r
6 f5 J4 Q: v5 [0 z4 g' }    >web3.eth.accounts
( H0 s( a; D4 u& [; e2 A- G
5 g, N! F4 g  g    ['0x5c252a0c0475f9711b56ab160a1999729eccce97'
5 o3 p$ e: Z% t  v' [' |0 U" E" S+ G9 ~0 \) _+ C( x6 L
    '0x353d310bed379b2d1df3b727645e200997016ba3'
0 ^: f, m0 s* Y4 {( ?: v
8 u0 g3 Y1 p9 v* u: g5 [" n    '0xa3ddc09b5e49d654a43e161cae3f865261cabd23'
* J" u2 A* ^, q9 ~2 O
( L& x9 g5 P$ ^$ b! N2 r% A    '0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5'
! U# |( U$ V+ b+ O' U8 B+ r9 W6 m; O; P0 Y: `! D0 M* P, p
    '0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798'
' h7 V/ H& a2 O8 P& I9 N4 ]; [1 k# j7 Q! F4 L
    '0xda695959ff85f0581ca924e549567390a0034058'
, @* L- @4 ]6 e& [1 V
/ z& f2 u) ?7 V    '0xd4ee63452555a87048dcfe2a039208d113323790'
5 Y9 O3 @1 Q; z3 F% m6 F; W$ b5 I7 I' ^0 I/ c& ^0 H  ?! Q. m/ o
    '0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14'
/ a+ F" `& Y) @6 }
* u7 t, Z6 [% A" Q2 I! i  h! t    '0xba7ec95286334e8634e89760fab8d2ec1226bf42'* k0 M1 ~' L+ R% _4 S7 J

1 r8 u  S) k; l0 I    '0x208e02303fe29be3698732e92ca32b88d80a2d36']8 i( k) ]4 T; f4 G& T7 C% _1 c
3 a# q6 T, v8 m  y( y7 l
    >code=fs.readFileSync('Voting.sol').toString()
7 w2 S1 n: [2 N8 V
, e. o1 E& z4 f    >solc=require('solc')( ]8 c3 }. r7 Y* b/ A
' l/ R/ `5 ^- c9 `% @0 V
    >compiledCode=solc.compile(code)
3 x1 \2 K$ P% }2 i) }9 W; Q8 k0 }6 w- k4 H' \3 b' g9 f
    当你成功地编译好合约,打印compiledCode对象(直接在node控制台输入compiledCode就可以看到内容),你会注意到有两个重要的字段,它们很重要,你必须要理解:
4 H* ^& [4 h' ^7 N7 k- v8 @& i  {- `% K
    1.compiledCode.contracts[’:Voting’].bytecode:这就是Voting.sol编译好后的字节码。也是要部署到区块链上的代码。! h9 G* x! Q) E1 g. x

0 S$ U1 @4 N. Z& g  q7 I    2.compiledCode.contracts[’:Voting’].interface:这是一个合约的接口或者说模板(叫做abi定义),它告诉了用户在这个合约里有哪些方法。在未来无论何时你想要跟任意一个合约进行交互,你都会需要这个abi定义。你可以在这里看到ABI的更多内容。8 F  M& ]: Z: G# c9 ]9 D
; g- {( P2 I6 S
    教程参考汇智网的DAPP开发入门教程,如果大家等不及博客更新,也可以直接访问这个以太坊教程。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

dancing520 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    1