Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
本以太坊教程主要是介绍:搭建一个开发环境、编写编译一个智能合约。# U3 B" \8 R% m" ?, }  z5 w
  N& e& p0 K. W. O4 [
    以太坊是什么1 ^( n7 Y! }4 {
5 \! K/ M1 L. k! W$ ^+ K/ s
    以太坊(Ethereum)是一个开源的有智能合约功能的公共区块链平台。通过其专用加密货币以太币(Ether)提供去中心化的虚拟机(“以太虚拟机”EthereumVirtualMachine)来处理点对点合约。3 k, K8 B+ Y9 {& L2 C& f- e
' M3 q5 V9 A: G' W7 G/ Y, j& z
    以太坊的概念首次在2013至2014年间由程序员VitalikButerin,受比特币启发后提出,大意为“下一代加密货币与去中心化应用平台”,在2014年通过ICO众筹得以开始发展。目前以太币是市值第二高的加密货币,仅次于比特币。
" k, q" Q- Y- }% V* \, J9 g* F, z( [) {# E3 w1 o- O
    以太坊区块链是什么?$ m0 c0 f4 {4 ~- ?
  c7 L+ I5 @% Y# o( A
    以太坊区块链有2个主要组件:
0 a! y) B) I( K) d) ^
5 W) U' g5 ^& |/ c/ t  n6 P    数据存储:网络中每笔交易都存储在区块链上。当你部署合约时,就是一笔交易。当你执行合约功能时,也是另一笔交易。所有的这些交易都是公开的,每个人都可以看到并进行验证。这个数据永远也无法篡改。为了确保网络中的所有节点都有着同一份数据拷贝,并且没有向区块链中写入任何的无效数据,以太坊使用一个叫做工作量证明的算法来保证网络安全。6 z* N4 _8 H! A4 Z: M0 D/ R" y
9 O  s4 n: S2 j, b' L/ s
    代码:就数据的层面而言,区块链就是存储交易。在以太坊的世界里,你可以通过一个叫Solidity的语言编写逻辑/应用代码(也就是智能合约)。然后用solidity编译器将代码编译为以太坊字节码,并将字节码部署到区块链上(也有一些其他的语言可以写合约,不过solidity是到目前为止用得最多也是相对更容易的选择)。所以,以太坊不仅仅会存储交易数据,它还会存储和执行智能合约代码。* {3 }7 d, o) n* l* t9 U& f

2 \1 L% g; b5 p    可以简单的理解以太坊区块链的作用就是存储数据和代码,并在EVM(EthereumVirtualMachine,以太坊虚拟机)中执行代码。
1 B1 z, u  I$ a5 m% x
* L0 `7 e! ^7 I( P    要准备的基础知识" m9 `, b4 p7 x2 ]

' S: f3 {) a8 U( I3 V% m% h9 _, p    为了进行以太坊开发,你应该对以下语言/技术有基本了解:
5 N: h+ B2 l3 V; J0 H3 v
% y% `1 `+ Z) ]/ a9 j( w* |    熟悉某种面向对象语言(如Python,Java,go)
; M; ^; C. H, ]0 o7 {# O( L
, A4 I0 u9 _9 T' e$ \+ o    HTML/CSS/Javascript
3 O$ y( X# {' j
- Q  |% Y/ \0 G' |  b/ u    基本的命令行交互如Linuxshell命令$ ?' x! q  Y+ @2 m

7 _4 c% d, e8 X; f    理解数据库的基本概念2 E6 E. [0 p2 _

" q3 k) q& p) ]6 a5 o( T" b* N5 W    为了构建以太坊去中心化应用即Dapp(Decentralizedapplication),以太坊有一个非常方便的JavaScript库即web3.js,你也可以在一些js框架中直接引入该库构建应用,比如react,angular,vue等。5 t. d0 K% |3 w' D6 p- l' @

/ D" O6 V. m4 O0 U) N4 ~! M    示例:一个以太坊投票应用: w6 U4 @" _& w. A7 [; M

, ]  o& u! h8 v; T    以太坊教程示例中,我们将会构建一个简单的去中心化投票应用。所谓去中心化应用,就是一个不只存在于某一中心化服务器上的应用。在网络中成百上千的电脑上,会运行着非常多的应用副本,这使得它几乎不可能出现宕机的情况。你将会构建一个投票应用,在这个应用中,你可以初始化参与选举的候选者,并对候选者投票,而这些投票将会被记录在区块链上。你将会经历编写投票合约,部署到区块链并与之交互的整个过程。你将会了解什么是一个合约,将合约部署到区块链上并与之交互意味着什么。$ a. N5 C" v. ]" Q0 d3 v) E
9 i3 k6 \+ n+ T& a
    本质上,区块链就像是一个分布式数据库,这个数据库维护了一个不断增长的记录链表。如果熟悉关系型数据库,你应该知道一张表里有很多行的数据。现在,对数据进行批(batch)量处理(比如每批100行),并将每个处理的批次相连。就可以形成一个区块链了!在区块链里,每个批次的数据就叫一个块(block),块里的每一行就叫一笔交易(transaction)。
. a4 N1 P$ L4 V2 b/ P0 e
: d& X+ P+ \- x- F- [$ s7 H    现在,你对以太坊已经有了基本了解,我们可以开始构建投票的dapp了。这将会加强你对以太坊的认识,并且初略了解以太坊的功能。# j# m; Z7 F+ Q/ {4 n. {  }  W: K

- e5 i1 [7 S' P    以太坊开发环境搭建9 l8 `8 ?, ^# }6 M- x# m
8 f/ b4 b) E! |
    Linux: e% m2 a+ v4 F' [
# U; P; ^6 O( E3 f/ P, ^
    示例是Ubuntu16.04下的学习环境搭建,你只需要成功安装了nodejs和npm,就可以继续项目的下一步了。
9 V* v4 Y0 }* R9 m& H% ?. ?; [" p) L* W) L3 k# i) ^: s% u
    我们通过npm安装ganache和web3包来为以太坊教程提供支撑。我们也需要安装solc来编译合约。: k: T  v- P+ p1 d$ e' l
4 I, P$ ?: `; T  _" o# C4 |5 O
    下面是安装过程:5 T4 v7 x3 W7 ~0 g% u& U% c  N
/ e9 \  @3 w' C3 u+ x# H6 o
    $sudoapt-getupdate8 o) o" D1 g( r  f5 B& d& ^# v, W' j
% A4 N  Q- z& {* U7 Q
    $curl-sLhttps://deb.nodesource.com/setup_7.x-onodesource_setup.sh6 G1 W5 Y& c) c5 z: w8 {

# g* u5 `; L( s% F3 V/ R    $sudobashnodesource_setup.sh
! }5 e9 P- l0 a, B% f0 E  G! m/ _& @
    $sudoapt-getinstallnodejs2 A5 j) P, b1 }& Z
: k0 Q8 y2 v  x9 e: ~2 i
    $node--version
( z4 ]3 V6 [. ?* P) e. d+ X" @5 P" @6 R
    v7.4.0
/ w/ D; m8 |2 H9 y% V: d- E3 T
8 ?7 D4 J/ X4 T" n, S5 K    $npm--version4 \! I) Y% \# Q

$ k' D2 {6 e) A; q  z) D% w3 Z    4.0.5- j* G# i3 l+ _# u- o
, \/ F0 ]- i! _( a+ w7 ]* ]
    $mkdir-pethereum_voting_dapp/chapter1* |1 E  Z2 J0 `2 ^

5 _6 L' t, `( p% n9 k8 N) ?    $cdethereum_voting_dapp/chapter14 V3 p- X  [  X( E9 N* t1 s1 ]7 R

) [2 J: U0 v4 F/ q6 G    $npminstallganache-cliweb3@0.20.1solc" u' q: S# C3 _8 H9 n$ _" |
# k+ u3 u  y3 E8 n" ^5 ?* }
    $node_modules/.bin/ganache-cli
, F( X  f. Y9 m2 Y: j. p2 U$ F3 D! T& F' G3 X# U: T
    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到下面的输出。
4 t9 K$ @5 M; [" O3 b' N- I8 c& I7 f
8 n% ?' x7 y3 l, s    GanacheCLIv6.0.3(ganache-core:2.0.2)3 `& z' e( B( n  Y, x

, ?0 E  A; j* Y+ g  ?5 V    AvailableAccounts
( B! Z) H0 O. T) m5 J* y; k  f) @, o. A* U: f% t; ^
    ==================
3 |- _; z) Y; ^, i+ Y9 s5 N. c) M) i" E6 j0 J
    (0)0x5c252a0c0475f9711b56ab160a1999729eccce979 E; |3 R$ E) @* M

6 l. w6 P/ ?9 U! I' t# O: J; Q4 b    (1)0x353d310bed379b2d1df3b727645e200997016ba3
: R- F, B+ B( s0 r# M: B9 Y/ _; p& Z
    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23
/ D0 e7 t/ d3 F  l
0 R4 p. C" J+ S8 X    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5
$ x. G- Q- s4 G( O! y0 m' L: n9 R
    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798: ~" N6 d- Q' x: w- Q
, `5 E" I0 ]1 Q0 m
    (5)0xda695959ff85f0581ca924e549567390a00340588 S2 n! B2 q2 \1 f$ u& M+ y5 j1 j
) }/ d! @0 k2 m* ]* x, n5 V" V
    (6)0xd4ee63452555a87048dcfe2a039208d113323790; y- c' [# Z# B- p/ a% W
0 z8 A  r  o& y- ^  r
    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14. a0 s5 I/ Q- r6 o4 Z5 V

0 W, o0 G4 a$ @3 T2 s' l    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42
% G1 K( y" x6 {& W* e. e- |  c- E
$ y! h% @" Z0 t) ^6 Y+ K6 Q    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36' N& d: ~$ s/ F! B# ]# d
( i! [* l( r$ c1 `3 h' e
    PrivateKeys9 T; f6 m* [3 ?7 v2 T
- B% p/ R5 K( p& ~
    ==================+ x/ X% k- n% |. }- R/ t3 n5 g

. e4 |3 w. d6 e; Q. @' W    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b
' s* L7 I) g: l' n; S/ ~1 y9 i
+ y5 @% A( K# `    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603! k0 \7 W+ T% i) y" I) _

) h% w; d& Q$ g! J8 K    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99( @$ N8 R5 B7 Q$ P4 ]+ _& V2 Z

  H9 {* D! ~1 N0 ]' Q+ g2 c4 [    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430# V* ]' x0 y, j/ M5 @

7 B  L( d  H7 b+ ~$ ]3 p3 I! }. y    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8
) A. o" P& l' _6 r( L$ ], d, y4 |3 m4 f- a
    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc
2 M1 T1 l# I; l; f9 t$ i
/ r' [& {5 o7 S  I0 ?+ R: O( A    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9
) Q  e4 U6 n) c8 M* y9 j% c! Y' E' i  A  b4 K. Y; u
    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d
8 u4 u4 k; H; e( R3 i. K4 k% f2 w( C( F( T  j1 A6 Y
    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
7 @$ @$ J" h1 J! }/ Y1 a6 c- Y4 ?# H3 Q8 _! I
    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0/ w5 Q! F& Z8 b4 y1 y

- w+ ^: ^9 v3 B  J" h0 ?. y# H% ^$ K    HDWallet; y2 ~( _3 l  D* `+ s/ O6 W9 b

/ x" A0 S0 ?  v; Y0 Q2 e    ==================) K" `# ~% m' N* \* y
. s6 N' A# u  g3 }- R
    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella; q" `& t+ V8 E& X" _' ]
% x0 p; n; l% Q% u- s- a% S+ |
    BaseHDPath:m/44'/60'/0'/0/{account_index}
: {8 q7 u9 \/ o3 H4 `' l/ X  C
6 l# U$ X( o1 o) ?5 T5 x8 V    Listeningonlocalhost:85458 h" K: Z+ R: z6 Z% B

* Z& q& s. `8 o3 W$ g1 X: ?, T    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。
% P/ M/ s$ M  a# v. X
( s, H( g2 G2 T7 P: s    MacOS6 s7 B% v( q& p" z! Q
3 z* S, p; d& E: N8 @2 _8 b
    如果你还没有安装homebrew,请按照https://brew.sh/的指示安装homebrew。homebrew是一个包管理器,它可以帮助我们安装开发所需的所有其他软件。按照下面的指示安装所有其他所需的包。
# v& Z4 @9 N% |5 [; o5 f1 {$ ^: U5 l
    $brewupdate
3 [. y" |1 l4 m% V/ x- Z* _
* U! y. ~( t+ r) w    $brewinstallnodejs, T/ o$ M3 l2 ^8 i8 N

4 o1 @9 y  r9 q$ p! k4 O    $node--version
, R+ _5 d$ _/ S! f3 d% T* b0 `5 Y) i) |& D5 g
    v7.10.0
6 J% \4 @/ N3 B9 e: [- `7 H6 H; \! o: H& L) ]  I& T1 u
    $npm--version
1 }/ Q: o6 r- j, y  G8 r5 f; y/ x, D
    4.2.0) t7 U3 x% V* T* r1 Z$ ]

9 y0 A! `2 y4 b7 _7 Z: B- X    $mkdir-pethereum_voting_dapp/chapter1& s6 _9 \% S. J4 K
( c$ I0 U" v6 U# R
    $cdethereum_voting_dapp/chapter1
: }9 M+ M! E2 }! z8 d) [9 P  h7 L. c/ i" P
    $npminstallganache-cliweb3@0.20.1solc
3 ^4 V3 v9 l+ c* |" t) N' T1 m2 a% r! G- V  p8 @/ I0 D
    $node_modules/.bin/ganache-cli  C. H' R* s. K" `* ^; C5 {  x1 [
( ~, ]% j5 f8 H& o
    我们通过npm安装ganache和web3包。我们也需要安装solc来编译合约。1 ~* U; t9 ?. X; K& X% @- d+ r/ @

$ B. f: n5 ]8 t5 M/ ?' O; M    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到右图所示的输出。4 w8 Q% X) g! g0 y1 n7 _( k" V3 `

- v7 ~& s$ T! V& s. S' B2 M    GanacheCLIv6.0.3(ganache-core:2.0.2)2 t# D7 C; u; z5 g9 l

! Z6 F$ r5 F4 b( V7 K0 F    AvailableAccounts) d0 R0 e' N% ^8 {& v/ y  f

& D4 O0 d6 I5 T' o7 s6 Y# \: l    ==================
$ E  E- c1 f6 x& O8 ]) L: t) W- O( V8 Z) X* K5 T
    (0)0x5c252a0c0475f9711b56ab160a1999729eccce978 Q$ ?/ l) U. Z; K: U9 D

* s  S; M* \5 A& H* n2 G' S$ ?/ s; @    (1)0x353d310bed379b2d1df3b727645e200997016ba3
" z/ Z4 d, v8 m
) o5 S$ I! p( }( }    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23+ X/ i6 n! A* |, R$ z
  K! G1 x0 I3 C3 t( z! e3 A7 p: C
    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec59 C4 x) t' _) ^# [+ @4 M5 v4 P" J1 U
2 |+ B! D! ]3 H/ I; E3 R; |
    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd27980 }) x' H% }8 Q) w2 \
- S  `2 }: K( w( B
    (5)0xda695959ff85f0581ca924e549567390a0034058
& ?/ B0 q! r8 ]
. h5 c! `+ t6 h    (6)0xd4ee63452555a87048dcfe2a039208d113323790
( V7 S* E/ F  a& `3 E1 w, T$ f. G9 D: ]* G( z9 I
    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d141 x4 r# `  P6 M' G2 u3 G

* ^0 e& T% f. _7 }1 N/ o    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42$ i7 }  C/ ^5 I6 j, k, I# @: l
$ R! w7 z: q. |7 e% I# F4 d, [: g
    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36
3 g; U' H; L/ c2 g: n' T' a( C, M1 O
    PrivateKeys
( f! ?3 Q( g/ @" T, L
6 h5 z$ r5 z2 s( v6 D- `    ==================6 @7 W; \4 z5 p3 m+ f

- R9 b; c/ f$ V2 C! s9 Y! Y8 i( n    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b# |- W4 i4 O) _* n3 G$ ^! W9 M

7 w, D, C% t* n3 N( o; Z5 P    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603, R$ _4 \! n" Y( _+ U

. \# U, f, Q6 o  V* ?+ Q+ p    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99
) j; u. J* P+ a, z$ b+ G6 `% u8 g! m# L
    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430
$ Z9 N7 J- l" O: Q! u8 Y+ u: \) {
6 j# n( }; A# e! Q1 I. ?4 Q    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a83 q- h# j0 O7 |/ t. ^; T  h

; W- S) [4 B  ]5 i) ?0 ^    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc
& o6 R$ w! V1 i% E) b# X- q9 l3 p5 z, b3 B& B
    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9# W* G6 N; n, N: k) Q
" p5 y0 l/ r( o5 O1 B4 K, R9 J) @
    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d
, a, q( N+ o0 V  }2 k+ D, r1 H" X. H2 s4 c8 E) b1 |- m( ?7 T& H
    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
. |5 v3 a* T4 b$ I; L: w/ u2 _4 b; C. G! ]* ~7 U: W7 `
    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0) t: ~- {  W/ N. s% u- w% g- M

* N* d4 H2 V$ I$ u+ @3 J' Z; I& k8 e9 ?    HDWallet  R+ i* L& l( g5 {$ S! j. P
+ J2 c9 F2 q9 w. D/ H% _
    ==================1 P; K! D' P# V6 t8 J$ a" D
& z# f0 V0 J6 b. K
    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella
2 N8 G3 V% |( ]' s( K  a, V
$ Q6 s( ]* a+ x    BaseHDPath:m/44'/60'/0'/0/{account_index}
% B, w8 G% Z& Y  m+ J% |3 {/ _
    Listeningonlocalhost:85456 @" S! d5 j# L& q, y* ?

) o- T( q5 R# o' s" M    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是以太坊账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。
& w* E! Q" M, B  V5 N1 Y) y2 X- T) S6 l: ~) r# M
    Windows, R: D0 ^/ W2 [8 Q' I

! m6 C, C" N8 C    安装VisualStudioCommunityEdition。如果你选择定制安装,那么至少应该安装VisualC++(目前的版本是VS2017)
; H4 C2 G! u; a: W+ m  s: C0 a) k0 p  n* N, N. ~2 }7 F3 \
    安装WindowsSDKforWindows
) m1 s9 E2 j( B! J* a5 M% e1 ?% ?- h. g+ e
    安装Python2.7如果你还没有安装的话,并且确保将它加入到环境变量PATH
! j. c' w+ ]+ K5 m$ j, b2 \2 R5 j1 t! z
    安装git如果你还没有安装并加入到PATH
$ K0 g+ }: g0 u: c2 e1 x6 U5 W* e5 i# y( U$ b
    安装OpenSSL。确保选择了正确的安装包,并且只安装完整版(而不是轻装版)。你必须将OpenSSL安装到推荐安装的位置–不要改变安装路径
: ]: e+ Y6 B- W8 @8 w" F3 F7 ?: Q9 J+ e+ r4 R# y# S, j7 o
    下载和安装nodev8.1.2。不推荐使用版本v6.11.0搭配VS2017
- }/ }( s! o* @( A6 M- }' M: V
4 m7 o5 @6 c2 y6 d- x3 v: g    执行命令npminstallganache-cliweb3@0.20.1solc
6 @. {6 s$ ^. k7 F' f
2 s, w+ w" n" r/ n1 d# Y) V5 K    SolidityContracts
7 d0 V, E" t! C5 g7 M  Z1 x+ k; n, E$ J$ z( \4 D% O
    现在已经安装好ganache并运行,我们将会开始编写第一个以太坊智能合约。! M7 {8 P5 n% ?0 d3 W* {, [

* V6 W8 `; C' p$ M    我们会使用solidity编程语言来编写合约。如果你熟悉面向对象编程,学习用solidity写合约应该非常简单。我们会写一个叫做Voting的合约(可以把合约看成是面对对象编程语言的一个类),这个合约有以下内容:9 x- F  R1 i- B7 o4 Z0 f
, |" w6 S2 I9 e7 Z) J% K9 @- S+ S
    一个构造函数,用来初始化一些候选者。
# Y& ?7 _  _" J/ {
( u# {9 D& w+ G    一个用来投票的方法(对投票数加1)( K8 c" g- }4 X% }) C1 y7 L% a
# [# {- ]) v# j! X
    一个返回候选者所获得的总票数的方法! x% N+ @3 |, y( I9 _

( o% a. p8 r  w: d! U    当你把合约部署到区块链的时候,就会调用构造函数,并只调用一次。与web世界里每次部署代码都会覆盖旧代码不同,在区块链上部署的合约是不可改变的,也就是说,如果你更新合约并再次部署,旧的合约仍然会在区块链上存在,并且数据仍在。新的部署将会创建合约的一个新的实例。
6 |! ?$ U% n. A4 P6 }2 h
- v* o* G# \7 ]    pragmasolidity^0.4.18;+ V; \& m; U4 J6 _( K3 O* W. w
3 {- z. H: H7 [: w
    contractVoting{
* ?4 z- b9 l6 X' f& J7 \/ _( s, q2 ]* g; \/ Q
    mapping(bytes32=>uint8)publicvotesReceived;
6 e% o) w5 y( [. M  a8 X; B
4 Z! l+ b3 W2 z! L; u    bytes32[]publiccandidateList;
2 F9 k7 Z) {; w  o# k
9 v6 @' }8 S( ~7 B; s    functionVoting(bytes32[]candidateNames)public{; ?8 x3 s4 ^, n

) @! k: n7 n$ D7 A7 S9 M: ?4 [    candidateList=candidateNames;
2 O1 `& b) K* l# q  X7 U. q4 F. J+ U  P- T( O  ~+ g
    }- k& z3 A+ F7 M# U8 [

' V, q: K0 L0 n& K  L3 ^' M    functiontotalVotesFor(bytes32candidate)viewpublicreturns(uint8){
8 D1 f; Z7 f; x3 ~
% C" {' ]. h0 e& j) v4 q    require(validCandidate(candidate));
" R+ |  w4 C3 A; Z1 f
  x& I3 `3 S1 f5 l: ^    returnvotesReceived[candidate];- k5 t: ~0 c  G
4 a  ^2 L/ I/ f6 B  S! w
    }  ]* }) C( Y& c; S- `8 f9 u& O
7 z7 M& ], W8 e6 A" T& p8 r6 s
    functionvoteForCandidate(bytes32candidate)public{
$ D" t9 U% f, X' @* N- }/ K% I! R! g
    require(validCandidate(candidate));
. U$ ^% h5 }/ m3 h+ O- R5 z& V4 o8 m
    votesReceived[candidate]+=1;( T' F$ x+ D$ m( O7 e6 [8 c
+ g7 f: y# `2 v! F5 v
    }2 N' l% V9 ?6 O# n
2 O9 j. V7 D. ^. T
    functionvalidCandidate(bytes32candidate)viewpublicreturns(bool){
  h/ q( e5 _! F+ R9 d
, ]2 O" B4 m- c& C    for(uinti=0;i
7 f2 M1 G$ h4 q0 h
$ L! |' {2 R, p& x5 s9 f. n    将右侧代码拷贝到一个叫做Voting.sol的文件中,并保存到chapter1目录下面。
3 j3 C$ h( [+ m3 X$ Y: p1 J8 B3 g) L2 ^" t$ q) w- D* X$ K' K& ~0 w
    代码和解释
8 e6 k- K  r+ r! y2 z$ C7 A1 X, g. d* e- \/ v0 |. H8 }; ^
    Line1.我们必须指定代码将会哪个版本的编译器进行编译2 X: d9 G- {5 e5 s" w

9 |. B& s1 o5 n! V- T    Line3.mapping相当于一个关联数组或者是字典,是一个键值对。mappingvotesReceived的键是候选者的名字,类型为bytes32。mapping的值是一个未赋值的整型,存储的是投票数。0 }( v/ o9 S* H! e1 p7 y2 s
. ?' ^+ e& m: ~! \4 N8 c% F
    Line4.在很多编程语言中,仅仅通过votesReceived.keys就可以获取所有的候选者姓名。但是,但是在solidity中没有这样的方法,所以我们必须单独管理一个候选者数组candidateList。, @- m( x8 J2 F; M- Q2 O
# x) D( C& O+ ]
    Line14.注意到votesReceived[key]有一个默认值0,所以你不需要将其初始化为0,直接加1即可。
& @6 _0 M$ B) i5 B2 N5 o, l+ z
7 W# C4 w4 l' _    你也会注意到每个函数有个可见性说明符(visibilityspecifier)(比如本例中的public)。这意味着,函数可以从合约外调用。如果你不想要其他任何人调用这个函数,你可以把它设置为私有(private)函数。如果你不指定可见性,编译器会抛出一个警告。最近solidity编译器进行了一些改进,如果用户忘记了对私有函数进行标记导致了外部可以调用私有函数,编译器会捕获这个问题。这里可以看到所有的可见性说明符。8 H, s+ U$ W7 V+ r5 B4 y7 M4 n

; X- A, l" m0 U" P9 r; O: j    你也会在一些函数上看到一个修饰符view。它通常用来告诉编译器函数是只读的(也就是说,调用该函数,区块链状态并不会更新)。所有的修饰符都可以在这里看到。
7 u/ V6 R3 V$ R3 ~5 t& R# h
2 t3 ~2 @% j/ V" }5 c# r: y    编译智能合约2 T2 q+ D( L" c% N% w- [  m

( m# f2 j! u8 R# P4 a' d    我们将会使用上一节安装的solc库来编译代码。如果你还记得的话,之前我们提到过web3js是一个库,它能够让你通过RPC与区块链进行交互。我们将会在node控制台里用这个库部署合约,并与区块链进行交互。  P9 m5 s* n! ^9 \% \( H5 d

# j% F8 G0 K* t    首先,在终端中运行node进入node控制台,初始化web3对象,并向区块链查询获取所有的账户。
, k& _) O$ q& P, v: ?. j" G8 x/ g
( w. L8 B$ q4 Z$ Z( p  S- S    确保与此同时ganache已经在另一个窗口中运行7 A% u; F1 g1 R! o* I

9 e+ B) @+ X; F: i3 ]* I! z    为了编译合约,先从Voting.sol中加载代码并绑定到一个string类型的变量,然后像下边这样对合约进行编译。
  q' t& Q6 I" C; j
/ f1 ~" _2 ?* i7 o    $node
" z4 R+ h4 x* g% r3 }& P
# y4 W6 y2 J* ]8 N6 i: v" i    Inthenodeconsole6 i) H2 Z: `. m! B& s
6 h8 V1 V6 D8 r& ^, W. ^7 B
    >Web3=require('web3')
- \" w1 ^4 F# _  {$ s
9 ?3 e# a  B; r    >web3=newWeb3(newWeb3.providers.HttpProvider("http://localhost:8545"));
$ R5 f4 X+ v4 |! b
6 M" `9 h: @3 z) k/ Z# R    >web3.eth.accounts  I: z8 ^' R: q' d/ p" H
* X! O8 |0 ^/ F& [6 m! u
    ['0x5c252a0c0475f9711b56ab160a1999729eccce97'
: w9 J8 o) R8 d8 G: L/ |  L8 O! W) f4 t" K" v$ B
    '0x353d310bed379b2d1df3b727645e200997016ba3'
7 Q4 m9 S$ b1 Z4 ?0 t5 c7 t" X. q$ \* \4 [
    '0xa3ddc09b5e49d654a43e161cae3f865261cabd23'
; u+ R1 \4 m- j) q! |  e+ A6 ]. o
; T5 }+ f! g* E    '0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5'  y* H  d! x0 {% |) F$ j
1 n% @6 V# G# R
    '0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798'
3 W$ D0 }  z7 h( l0 W' @, ]& q  @5 f/ n! z' F
    '0xda695959ff85f0581ca924e549567390a0034058'
" p/ x" g; ?& g4 }+ v
& V1 }4 C# [7 s0 m  J    '0xd4ee63452555a87048dcfe2a039208d113323790'# g4 k! ^- ]8 m' }. `2 m
. ^5 R) ?3 w& A( z
    '0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14'
7 M4 j2 t  @8 K( c4 M+ z. r% ^9 ]2 @& o5 R9 V) {
    '0xba7ec95286334e8634e89760fab8d2ec1226bf42'- G  A. l1 l3 l+ F0 F# t* H

& l2 p: v2 o- z5 H( m# t# o& S    '0x208e02303fe29be3698732e92ca32b88d80a2d36']
0 ?: T8 C" l# b) l
2 [8 V: I. ?- s    >code=fs.readFileSync('Voting.sol').toString(), v" a8 k: d  R% C" s+ q7 d0 O+ j

, _: B) V9 B2 c    >solc=require('solc')
1 G5 R+ b/ m/ @4 z- f  ^
& |& s* J. d2 h# D: e    >compiledCode=solc.compile(code). l7 C/ f7 E7 q3 j

3 Y2 B& |0 R: x    当你成功地编译好合约,打印compiledCode对象(直接在node控制台输入compiledCode就可以看到内容),你会注意到有两个重要的字段,它们很重要,你必须要理解:
  K5 d; I' O8 |1 [
( ^+ q  J# v2 G/ _3 O    1.compiledCode.contracts[’:Voting’].bytecode:这就是Voting.sol编译好后的字节码。也是要部署到区块链上的代码。
( K9 T7 M, s4 O' B5 ~1 w
# z6 x- @# k! I0 z% R4 W+ ~4 {    2.compiledCode.contracts[’:Voting’].interface:这是一个合约的接口或者说模板(叫做abi定义),它告诉了用户在这个合约里有哪些方法。在未来无论何时你想要跟任意一个合约进行交互,你都会需要这个abi定义。你可以在这里看到ABI的更多内容。$ t$ B  S- Q+ D9 e( \- C
0 }" ^  ?) V! U1 |  H  {% A- G
    教程参考汇智网的DAPP开发入门教程,如果大家等不及博客更新,也可以直接访问这个以太坊教程。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

dancing520 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    1