Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
本以太坊教程主要是介绍:搭建一个开发环境、编写编译一个智能合约。
; U  ?9 E2 {/ M% z8 i4 S8 Q3 [8 V" |; e3 y" W, _' l
    以太坊是什么1 _+ \; W. p/ d$ \- ^
* l$ s+ H" h: H: k3 i
    以太坊(Ethereum)是一个开源的有智能合约功能的公共区块链平台。通过其专用加密货币以太币(Ether)提供去中心化的虚拟机(“以太虚拟机”EthereumVirtualMachine)来处理点对点合约。5 [% D5 H9 S3 Y

; t- G6 Y% [5 n- u& Q    以太坊的概念首次在2013至2014年间由程序员VitalikButerin,受比特币启发后提出,大意为“下一代加密货币与去中心化应用平台”,在2014年通过ICO众筹得以开始发展。目前以太币是市值第二高的加密货币,仅次于比特币。
) x. @, E. x. M
9 q$ e6 @; u. x    以太坊区块链是什么?
0 h2 w; s  ?- ~4 H
* k! q% K6 d9 {7 W! G0 Z1 c    以太坊区块链有2个主要组件:+ F: ]+ {8 S8 C8 Z& [/ E
- P: y3 w( o" l) g* z
    数据存储:网络中每笔交易都存储在区块链上。当你部署合约时,就是一笔交易。当你执行合约功能时,也是另一笔交易。所有的这些交易都是公开的,每个人都可以看到并进行验证。这个数据永远也无法篡改。为了确保网络中的所有节点都有着同一份数据拷贝,并且没有向区块链中写入任何的无效数据,以太坊使用一个叫做工作量证明的算法来保证网络安全。
7 Q. S  p5 R8 V4 z0 V9 u
* _: c1 V& K" H1 Z2 z    代码:就数据的层面而言,区块链就是存储交易。在以太坊的世界里,你可以通过一个叫Solidity的语言编写逻辑/应用代码(也就是智能合约)。然后用solidity编译器将代码编译为以太坊字节码,并将字节码部署到区块链上(也有一些其他的语言可以写合约,不过solidity是到目前为止用得最多也是相对更容易的选择)。所以,以太坊不仅仅会存储交易数据,它还会存储和执行智能合约代码。/ X" j: |7 F' h4 k. Q: b
) h$ y: @# ]+ s) z
    可以简单的理解以太坊区块链的作用就是存储数据和代码,并在EVM(EthereumVirtualMachine,以太坊虚拟机)中执行代码。/ T3 O8 I) d7 u  U# K
% k: t1 f. L4 V6 j6 P7 i+ V8 R, c
    要准备的基础知识0 i. F  n9 A  ~% ?3 ^
+ D% v' ?! T+ B
    为了进行以太坊开发,你应该对以下语言/技术有基本了解:+ ?' I. C  e- {1 i1 s
( l9 ~! v; }" S" W. w& ^
    熟悉某种面向对象语言(如Python,Java,go)5 z5 \, c  Y* s7 d
. A' O% ?: o% f! |9 d' A6 X/ q7 i4 X
    HTML/CSS/Javascript9 d* w& o2 H  W' A$ N

4 A' v3 _+ q& L" U3 i" P0 v% h    基本的命令行交互如Linuxshell命令. E5 C5 I9 G) d+ V: g2 x
: K; e! r- ]" w' J
    理解数据库的基本概念
9 M- R2 H* O, x7 [& {; a+ D( y- g- j* x3 [' R! c  L
    为了构建以太坊去中心化应用即Dapp(Decentralizedapplication),以太坊有一个非常方便的JavaScript库即web3.js,你也可以在一些js框架中直接引入该库构建应用,比如react,angular,vue等。
+ a% p5 L. {) f
( O8 X5 g& e9 S3 x+ u    示例:一个以太坊投票应用; X  R# O! @$ w& E1 L
# g6 H; K- w: R" L! g( n0 f0 D: S( K
    以太坊教程示例中,我们将会构建一个简单的去中心化投票应用。所谓去中心化应用,就是一个不只存在于某一中心化服务器上的应用。在网络中成百上千的电脑上,会运行着非常多的应用副本,这使得它几乎不可能出现宕机的情况。你将会构建一个投票应用,在这个应用中,你可以初始化参与选举的候选者,并对候选者投票,而这些投票将会被记录在区块链上。你将会经历编写投票合约,部署到区块链并与之交互的整个过程。你将会了解什么是一个合约,将合约部署到区块链上并与之交互意味着什么。
) V; i. k* L5 R) [( j. T2 P& J8 ]5 y4 u
    本质上,区块链就像是一个分布式数据库,这个数据库维护了一个不断增长的记录链表。如果熟悉关系型数据库,你应该知道一张表里有很多行的数据。现在,对数据进行批(batch)量处理(比如每批100行),并将每个处理的批次相连。就可以形成一个区块链了!在区块链里,每个批次的数据就叫一个块(block),块里的每一行就叫一笔交易(transaction)。- u* R# @  q$ ~; ~+ V& u  W
; t8 z/ r, H. F  {/ \- R6 R6 |, r
    现在,你对以太坊已经有了基本了解,我们可以开始构建投票的dapp了。这将会加强你对以太坊的认识,并且初略了解以太坊的功能。9 o+ K5 c( ~" W' |

9 |6 n. W8 o0 H$ p    以太坊开发环境搭建
7 f0 u$ N7 ]# E3 Y! C. @5 d7 h4 N  a; \7 e  C: n
    Linux( b7 z5 x$ i; R7 [$ _
; {( v, ~1 \# h7 R
    示例是Ubuntu16.04下的学习环境搭建,你只需要成功安装了nodejs和npm,就可以继续项目的下一步了。; q: ]7 \2 o8 A( p) n  |

5 l. ?- [. L  B    我们通过npm安装ganache和web3包来为以太坊教程提供支撑。我们也需要安装solc来编译合约。7 o. v* n) _2 z

  I- A; v1 t( x    下面是安装过程:
. a! b8 Q1 i! J' x& _$ K+ m# k, s1 n, ?$ w7 @5 V
    $sudoapt-getupdate, T# \! W: }" m3 u8 i; a

! t, C: j' w/ _) `    $curl-sLhttps://deb.nodesource.com/setup_7.x-onodesource_setup.sh
1 B5 \# Z6 v" @8 \9 X4 A! g6 u& O+ x2 ]2 R! @4 m1 e( ~# K9 h
    $sudobashnodesource_setup.sh
7 O7 f* R3 d7 s+ M+ c# c) {) x# d; J! p) n; ^* }
    $sudoapt-getinstallnodejs6 M, j& k* w7 F, F2 H6 ^+ W
9 a3 |* R6 S. R1 a2 {3 E$ y9 U
    $node--version
6 l! V: I9 @' S, L" A8 u8 N+ o3 Q. N& j, B& _' C
    v7.4.0
+ M  G: O% H; V' o+ t. ^; Q; p6 l9 U6 Y: u- v: i
    $npm--version
4 f% O2 C/ u2 _  \. J# {6 M: L: m6 m" ]9 b' l2 D' ]- i
    4.0.5& w8 _2 a' n. d0 n; N- f
% S, f: d7 a$ {* x6 K. s" Z4 h5 \
    $mkdir-pethereum_voting_dapp/chapter17 U. j1 [( O/ _6 ^0 E" Y
! M% l5 I/ ~  D$ j) D3 w5 }
    $cdethereum_voting_dapp/chapter1
  X# S  u" K3 ~, V- ?
1 o& K/ J  b4 p- K% H1 T  [6 k    $npminstallganache-cliweb3@0.20.1solc) @1 p  `  |* |

( N5 k! C0 i! D# m0 j+ @# `1 }    $node_modules/.bin/ganache-cli- I7 _, y6 ~! `) j, ^
. O/ n; K" h( G; B2 \$ M* i+ e
    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到下面的输出。4 c7 c2 f/ C/ V  A  i( [9 b6 D2 m
; @7 _+ ~- o6 c, w
    GanacheCLIv6.0.3(ganache-core:2.0.2)5 P: P- w/ e* j6 J( O; b

6 z) Y. Z  g1 K# g5 J: I9 h* B( _    AvailableAccounts. d3 |' s- E. E9 c) O' v

1 j2 H) t" H. {    ==================
* v6 ~% ]5 e7 e$ m1 z
9 N, g! ^2 F+ K( K# l( U, b    (0)0x5c252a0c0475f9711b56ab160a1999729eccce97
/ X  ]3 E' Y( c; A" `8 x* ~2 w2 p  `- d; \' X; n% i
    (1)0x353d310bed379b2d1df3b727645e200997016ba3
0 C# j* D% G. f. O) [1 E
! M9 a1 z  j; b$ t    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23
9 P6 H* U1 y- N2 ?2 e
9 V/ f/ `$ g9 u    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5
% u7 S& X. n; N2 v5 S: ~( T# E, r. m. O+ O! Q6 ~) C% f
    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798
7 ]% s6 j+ M& [& e3 X
3 y, J7 u" Z8 B& `* h, ]    (5)0xda695959ff85f0581ca924e549567390a0034058; i8 P8 O+ h* x3 @; p9 y* d

& a9 ]6 V. o, [    (6)0xd4ee63452555a87048dcfe2a039208d113323790
$ S( |1 e. S/ M8 _# o' R* d9 q# B9 N- S
    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d148 P! C8 I( j( s6 w" o( Q

3 C. t0 N/ s; ^" ], A    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42
  r9 ]& W" U1 ]- y7 o
8 Y' P7 z  q4 e* V    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36! W  ~2 T* @; |; E/ a

5 K" o  t% Z% `    PrivateKeys. L! d! i2 Q; N( o/ z( p+ N$ q5 B

. O" S8 T5 [1 A1 i+ w3 }    ==================" q, o5 L6 V, @" |4 ?$ s8 I, f

% ~5 |, {/ u- M, l& H9 t    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b
8 B. \: }  P; }  Y6 }6 h. ]$ ^+ r& P" F8 ?+ Y6 e/ s& z% M
    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603. R+ x& q2 j% p/ r
0 Y2 l" M* g2 B1 B9 I
    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce991 m2 f  r! [/ x4 l
* i) ^# \. Q( @, z# }- C
    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430' N5 Z4 x# M7 A" |" ], k2 c) J2 e
' i. g6 H; \2 J6 B
    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a89 S% r- F+ n) J7 j& _/ J  ]9 a2 _

1 b* m4 w, h7 t- p; u! X0 g    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc
$ h. L; d* E, t5 E
' O# d5 |! r7 i& H    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a94 V, {% t5 Q4 s

" I- T$ ~- P* N8 M# n% U    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d
+ W6 \! ?; d! T2 p0 D; K
2 M+ x# I! T3 [  T' T    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a. P+ j! ]8 W- G; W4 H7 E9 \

3 H7 M& j# z% d+ U, _    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0
. s/ g" p+ P- Y% u
0 e, H4 K) a1 y# a    HDWallet
7 u7 A- n* f, A- g+ L' A" _/ u
    ==================9 B) z* _' K3 w4 |

; e* F8 Y3 i5 g: U    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella! w7 H7 d" Y% h* ?2 H
+ s! V9 X; v. }
    BaseHDPath:m/44'/60'/0'/0/{account_index}7 X8 g5 l9 B5 ?3 W$ ~

- g. t5 A. l: I# H2 u) L! o    Listeningonlocalhost:8545/ o0 z# ~# h: i, X) Q

$ V; [& [) L/ w4 M+ |+ P    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。
/ E0 U4 Y8 m6 ?
, m+ f2 H3 G6 \0 @    MacOS& i, G, w. G' {! \3 [9 e

6 C8 ^. ^. D8 p5 |    如果你还没有安装homebrew,请按照https://brew.sh/的指示安装homebrew。homebrew是一个包管理器,它可以帮助我们安装开发所需的所有其他软件。按照下面的指示安装所有其他所需的包。
: A; ?) f3 S/ ~! @. W, ]' m7 V; o5 ~% v5 \* S: L; i
    $brewupdate
: i0 m1 t0 w/ Q' O2 f0 u0 A2 u, D+ D1 y8 a- `' w+ R9 [
    $brewinstallnodejs$ A2 Z1 ^9 Y( G: T5 ]* m
; E& d% |3 ]$ i- i
    $node--version
2 A/ r5 l0 |( I. q+ D1 i# ~& M, \1 H, K) Z  M- Y0 D
    v7.10.0
1 S  }' d  s* g5 D, q( H" [5 ]
) m% M4 W3 Z& c8 r/ I    $npm--version+ I3 S0 ?  {: c5 X% ~+ d: P% j9 k& O

  k5 X0 ], [( j    4.2.01 c) y$ K- J' ^' i6 d

5 |7 g; C, a6 w) N1 [! Q4 J8 H+ V    $mkdir-pethereum_voting_dapp/chapter1
6 X! o! F, }( o" W2 t5 R: y, V0 N
* R- L. l6 w- ~    $cdethereum_voting_dapp/chapter1
8 K1 E' S4 l) c) K$ z  s* y
  r$ ?: z' v  Q2 m$ P0 `; I1 J    $npminstallganache-cliweb3@0.20.1solc
( }9 y: T" v8 {$ g) J/ L# L" h+ \2 j$ B+ u
    $node_modules/.bin/ganache-cli$ o6 R) t( B  G  D" ^& b

# `1 ~( p* u: W: h1 y5 P6 U    我们通过npm安装ganache和web3包。我们也需要安装solc来编译合约。
8 h8 c5 ~5 U% B( T1 J  X; `% t% e7 s
    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到右图所示的输出。* }' G- [: e+ j; G! M5 C/ G: G
7 G3 ?: }$ k# e9 g
    GanacheCLIv6.0.3(ganache-core:2.0.2)8 \+ b, H5 m; n, a8 z

( K) K% S7 ]5 Q* `+ f) h    AvailableAccounts
- ?: d1 ^/ K  p0 @2 ]" a3 e& s1 y5 a% y; \  G; v
    ==================
: ]! U) W2 V9 s; H# S0 M8 i8 _4 ~8 Z' V
    (0)0x5c252a0c0475f9711b56ab160a1999729eccce97
, H% b5 l" J) ^; P1 N/ _
) S" ?. N, ]% _; v) r- _% L    (1)0x353d310bed379b2d1df3b727645e200997016ba37 [& }. U4 A3 S/ T4 {, @6 A8 q7 m0 O, I

/ K; _* o0 K1 V9 k3 H0 ~  j3 q1 z    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd239 q3 S/ p9 c' y3 d6 [  c
, y/ ?( n- \. T; C# n8 H
    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5  s' A6 j1 l; O8 J* N

$ J" J. v/ W0 o$ [9 t/ Z1 Q7 M! l" v/ j    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798
, x1 M3 G- h+ I! ^( F' Z  ~( x  Z  @" H0 S5 |% V0 Q
    (5)0xda695959ff85f0581ca924e549567390a0034058; o) H9 J% e8 q
9 j; t: y6 N1 W( n! S
    (6)0xd4ee63452555a87048dcfe2a039208d1133237903 m# x- i/ I1 T; G9 a) o( W# J
: v% S9 q+ g, H/ j/ L" h7 u9 p2 _1 X
    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14. {5 {9 _0 I( {9 y5 H9 Q" t
- w7 S/ I+ D0 y7 T9 x8 s, R
    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42
  f( J/ C6 X4 D1 _
& k0 i0 O4 J7 \    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36/ W6 r# _. X) E: i! r# V' a# D4 |1 k
' x9 v8 |  X/ O4 t
    PrivateKeys" `1 n- ]! V, k; |) w

% I5 }' d7 W+ ^. Y  u1 K  E    ==================
- I" G1 j9 t$ S) K5 O  P' M% W% l) O8 [. S. W6 j
    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b1 d7 H9 N0 J* y0 W! Z
4 [8 t( o4 k$ d9 F% J+ a( O
    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603; T0 ?( G+ B6 k( M

, ^3 A  P) P* J5 k& Z    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce993 I( B# m* n$ I# R+ K7 V/ J
- q5 D4 l. k1 Z1 k& \% I! M
    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430) S4 O$ T9 D) d# H- M& }! m

" P# ?% i# A. G' I8 x    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8
% Q( M7 ]4 e# x, ~- c; g: g7 P/ \% p5 A8 u2 N
    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc
: C! G8 ]2 {9 @) ]5 ?! z5 N
# g- j8 g* ]8 d* H( f  \2 x! ~    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9
0 b  T* v8 S2 h6 ], O9 \+ n9 a  f
, @+ i7 b: F2 v* E; }7 o    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d
1 J* u2 n6 D9 |( q: [; H/ x+ @! Z  H9 ?! W/ R
    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
. [! t' S7 V' y( p  `5 b( d5 S: Z1 Y7 a6 C7 O/ A
    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0
+ z* l& d! `/ _7 C7 x2 O2 W8 Z0 b$ _
    HDWallet
; l  m5 [: a7 h! ^2 k1 \
9 s) a, g7 g: d7 o; V! B$ m, Z    ==================3 Q8 y" {( ~$ k5 h6 W

3 W2 H+ q/ _! F. o; c. b    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella
1 C7 ~, `/ z) V7 y
- u& `, ^) e0 V% T0 d* L    BaseHDPath:m/44'/60'/0'/0/{account_index}- G% d# R6 W. ~% F9 ^

" Y4 o6 M/ Q6 `7 t' u" Y, S    Listeningonlocalhost:8545$ W* K* O' y& a0 e( \* L7 r
' ~, ]  r8 q# T1 Q0 p) {" A
    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是以太坊账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。& j( T; V- j. u# Y2 E5 j" _

# Q) J" v& {+ n1 @; B) P, @, m    Windows' ?% Y7 H! g- @2 \5 q$ H# Y

' u7 w' u$ d: L( }1 y: D' p    安装VisualStudioCommunityEdition。如果你选择定制安装,那么至少应该安装VisualC++(目前的版本是VS2017)& I, W5 L! r. C6 B' v4 d
7 {3 X- G7 d% b/ T) C' l9 b" z
    安装WindowsSDKforWindows
1 a. g/ g* p! }! A5 W- m
- q9 E  p  {8 X1 |: V, I" }: T    安装Python2.7如果你还没有安装的话,并且确保将它加入到环境变量PATH- U7 x* y1 |2 j% M1 B

6 O# b/ V! {4 ~, n, o    安装git如果你还没有安装并加入到PATH
" ~, F, O% T; Q% u* M+ a7 _) M4 V2 [" B5 u. s% I
    安装OpenSSL。确保选择了正确的安装包,并且只安装完整版(而不是轻装版)。你必须将OpenSSL安装到推荐安装的位置–不要改变安装路径8 A+ n! u* A) @, K4 E6 K" c* A
8 N7 a& U7 p2 y! \# A2 C8 J
    下载和安装nodev8.1.2。不推荐使用版本v6.11.0搭配VS20178 ]0 F) ?1 [9 s

3 W/ v5 i4 z- I- h1 j; G$ o+ `" V    执行命令npminstallganache-cliweb3@0.20.1solc+ {3 I$ Q0 {( F% O- c( f7 s' x5 C5 T

; N; {/ V+ A4 |, Q6 L    SolidityContracts- c, S- {* s6 [4 _; U

; f8 h) _* g/ ?2 O  K( P    现在已经安装好ganache并运行,我们将会开始编写第一个以太坊智能合约。
* c/ Y. d, E& K1 @/ t. Q
4 i  @( f5 J1 |6 J, J! P( W% p- A- P    我们会使用solidity编程语言来编写合约。如果你熟悉面向对象编程,学习用solidity写合约应该非常简单。我们会写一个叫做Voting的合约(可以把合约看成是面对对象编程语言的一个类),这个合约有以下内容:
) `2 l6 K% o: G1 l3 U- S
4 ^$ h/ e$ p* E% G/ D7 Q    一个构造函数,用来初始化一些候选者。- h5 d( b7 M. W/ G3 i
# j* j* T5 `* s" ]
    一个用来投票的方法(对投票数加1)# a% H! Z2 N4 r
" @( K& }5 n, l  i
    一个返回候选者所获得的总票数的方法8 `/ x: T& u6 a8 `7 s# J

( U/ J/ ^- z0 n. i( Z1 x. Y3 a: \    当你把合约部署到区块链的时候,就会调用构造函数,并只调用一次。与web世界里每次部署代码都会覆盖旧代码不同,在区块链上部署的合约是不可改变的,也就是说,如果你更新合约并再次部署,旧的合约仍然会在区块链上存在,并且数据仍在。新的部署将会创建合约的一个新的实例。
" @  v0 ^- ]) u* |
7 W2 L9 j& y$ ?( l2 m    pragmasolidity^0.4.18;
1 F$ w: Z" K& ?7 e& ^/ t: g' I8 D  R' U- I0 |) d* P8 d, P2 e
    contractVoting{4 z: y3 t# e% i

7 V$ C. a  O; ~    mapping(bytes32=>uint8)publicvotesReceived;
% ?; ?. M# |  a& b  @, L4 u" C( X' t0 i- u6 K
    bytes32[]publiccandidateList;. M% r% J: m2 i4 ]/ p

) Y- k4 K5 i) `% f7 ^! N* o    functionVoting(bytes32[]candidateNames)public{
9 u5 y& e# Q2 q8 G; ^& G! b  P( {* \  s' A# |6 }3 t
    candidateList=candidateNames;
1 l) b% w# L3 d8 [* `# }0 ]' p: L/ E& w8 D* S
    }
1 `9 L, f2 K  S+ C) h8 L  N
6 e: U9 }: k! s( i7 f    functiontotalVotesFor(bytes32candidate)viewpublicreturns(uint8){: z$ `/ Z: }6 G
# A4 B/ z* @4 g& _
    require(validCandidate(candidate));
/ r/ t/ J1 u, @
1 f. Y5 }, ^: _. Q1 j0 r' j0 q    returnvotesReceived[candidate];* ]/ Y6 ]0 R6 h$ j! K
3 t+ U6 j% I& c+ m7 ]1 k
    }2 ?5 Z% L9 F' ]' H9 b
8 T9 `! v) f- e1 S! k& u' I
    functionvoteForCandidate(bytes32candidate)public{
# f$ t3 h. D% p
! X( v1 [& w: \( x! k    require(validCandidate(candidate));' J+ R- Q% ^! c# a5 e, G
  Z5 Q0 l) z  \8 a& b" k% X' ~
    votesReceived[candidate]+=1;
( J$ w6 ]7 p  K' L. V
0 k8 S2 J9 w6 ~) ?1 H! \    }) e- J0 v& _( r' E, F2 `( e
; p5 g& b5 F$ [2 @+ Q1 G. Y
    functionvalidCandidate(bytes32candidate)viewpublicreturns(bool){
# I2 b0 I# B8 M4 L" \' A
' i; h% C# O: S3 g3 w& F0 J    for(uinti=0;i4 }" K; B- t  @7 Q

& h2 L, B0 ^, F; b4 C2 f2 L    将右侧代码拷贝到一个叫做Voting.sol的文件中,并保存到chapter1目录下面。  ]# |4 W7 R0 f: H' G# v  c: S

9 P5 j# p( h$ c    代码和解释
0 ~$ @1 A% F  e& M+ l, G6 p4 W
! K3 E: V7 k8 z8 e" N    Line1.我们必须指定代码将会哪个版本的编译器进行编译
4 l4 g8 H+ N: p$ Z0 O6 y) E  @! p* Z, Z" t1 a7 ~* A/ ]& P1 O
    Line3.mapping相当于一个关联数组或者是字典,是一个键值对。mappingvotesReceived的键是候选者的名字,类型为bytes32。mapping的值是一个未赋值的整型,存储的是投票数。$ B6 Y$ |5 g/ O
! B; ~$ X. Q, |7 m' K: p* E/ c' p. u
    Line4.在很多编程语言中,仅仅通过votesReceived.keys就可以获取所有的候选者姓名。但是,但是在solidity中没有这样的方法,所以我们必须单独管理一个候选者数组candidateList。
3 f: O( B, l6 c* g" g8 e9 c. N& e) L8 w! {# h
    Line14.注意到votesReceived[key]有一个默认值0,所以你不需要将其初始化为0,直接加1即可。3 D- K- a! @: }2 }. {! a; J( W0 t) `! v; P. \
0 n2 U' @' Y) n
    你也会注意到每个函数有个可见性说明符(visibilityspecifier)(比如本例中的public)。这意味着,函数可以从合约外调用。如果你不想要其他任何人调用这个函数,你可以把它设置为私有(private)函数。如果你不指定可见性,编译器会抛出一个警告。最近solidity编译器进行了一些改进,如果用户忘记了对私有函数进行标记导致了外部可以调用私有函数,编译器会捕获这个问题。这里可以看到所有的可见性说明符。9 o0 d3 B% |0 j# U+ g) \7 Q( C

+ U- w( g3 t8 G7 r8 E1 R) y' u    你也会在一些函数上看到一个修饰符view。它通常用来告诉编译器函数是只读的(也就是说,调用该函数,区块链状态并不会更新)。所有的修饰符都可以在这里看到。/ A" V' l/ _; F  p* ]7 f

" V+ H+ T: h$ p; A" Q    编译智能合约% H3 a: k4 Q3 H

' ~' i. x& w: F; F4 ?    我们将会使用上一节安装的solc库来编译代码。如果你还记得的话,之前我们提到过web3js是一个库,它能够让你通过RPC与区块链进行交互。我们将会在node控制台里用这个库部署合约,并与区块链进行交互。8 J% i1 Y; `1 k8 O; g
' g6 o: J$ [, h
    首先,在终端中运行node进入node控制台,初始化web3对象,并向区块链查询获取所有的账户。
1 x% }5 |, l8 |" }8 p! g8 J& P5 p: i3 \* A" }: H1 U* J
    确保与此同时ganache已经在另一个窗口中运行
: K+ C) B3 u4 i1 X: j5 h; ^  `( r: P7 g
    为了编译合约,先从Voting.sol中加载代码并绑定到一个string类型的变量,然后像下边这样对合约进行编译。
) w3 ]4 I! z. v. }) V- \! H# o+ \5 X8 l$ @
    $node$ _! D4 x, Z+ R( t+ r, X4 G3 P
  _+ Q- `- I3 V7 I0 u  V/ ]
    Inthenodeconsole
+ ^, f+ y% i' q. c+ X, M6 Z. U# C3 O# I  m& d- B* b# `
    >Web3=require('web3')
" S0 s' z0 l- m: J8 \7 }8 h7 @
    >web3=newWeb3(newWeb3.providers.HttpProvider("http://localhost:8545"));
( ?, O& I7 C9 _
; c5 Y: B2 R/ ]: w! b* o" L" z0 k    >web3.eth.accounts: t& Q. v9 B: q$ n8 W

' ~0 {* P7 ~7 @: S' m; Q# F+ p    ['0x5c252a0c0475f9711b56ab160a1999729eccce97'
( B, A" H# ]1 a  D/ T1 Z, l# c. I6 i
' `! Q1 h0 W& Y# t! `2 P    '0x353d310bed379b2d1df3b727645e200997016ba3'$ p. U" F- q( i% y3 ?+ S0 }) H, }

6 S! N) N. t% N/ W( G6 t) g! t: l    '0xa3ddc09b5e49d654a43e161cae3f865261cabd23'
6 t* x& \* K% s9 o! F# D; ]" r+ r4 ~0 @8 I
    '0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5'; v4 K' j: ]' n1 R! ]. B
# f" W* k8 ?+ A  b
    '0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798'
/ k& G: R, N! Q# z  |; W7 M  h: P3 n+ @1 u. b
    '0xda695959ff85f0581ca924e549567390a0034058'
& D; \3 J% ]2 k8 Y' L4 m' W% r' P6 e6 ?9 ?
    '0xd4ee63452555a87048dcfe2a039208d113323790'' y( ]+ I$ r# j) q

( k0 S, G+ r: {, G$ E( I    '0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14'
7 i; f+ Y5 x$ E! f4 ~  H* ~$ N5 K# U. x* B7 g# _
    '0xba7ec95286334e8634e89760fab8d2ec1226bf42'+ P! S9 i+ g0 d: y

( x: H8 \* P6 P& n4 m    '0x208e02303fe29be3698732e92ca32b88d80a2d36']0 @' O% l% s0 \; W* D% e

2 A% U* N% H3 u3 S1 I8 k1 p    >code=fs.readFileSync('Voting.sol').toString()( r3 u8 \9 ]* N" _) j
# z8 ^: G3 e9 R. s% k9 C3 b
    >solc=require('solc')
: d0 J5 S7 t5 n8 E2 z: O0 Y. B  ~2 w6 G/ G
    >compiledCode=solc.compile(code)2 b2 V6 S7 f* f) _- B
# X4 w1 q; P/ ^& ^8 R' X% |5 @
    当你成功地编译好合约,打印compiledCode对象(直接在node控制台输入compiledCode就可以看到内容),你会注意到有两个重要的字段,它们很重要,你必须要理解:: h+ ^7 C1 m9 w* U

5 g' U0 u4 L4 I1 r; G1 @    1.compiledCode.contracts[’:Voting’].bytecode:这就是Voting.sol编译好后的字节码。也是要部署到区块链上的代码。+ N) a9 _" }  P, e! \; \1 w
1 i9 V! G! Y  W2 G8 ~1 q" E: `$ Q1 |
    2.compiledCode.contracts[’:Voting’].interface:这是一个合约的接口或者说模板(叫做abi定义),它告诉了用户在这个合约里有哪些方法。在未来无论何时你想要跟任意一个合约进行交互,你都会需要这个abi定义。你可以在这里看到ABI的更多内容。8 K, J, ^; c' u% f' @
$ e& }; {4 L  H
    教程参考汇智网的DAPP开发入门教程,如果大家等不及博客更新,也可以直接访问这个以太坊教程。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

dancing520 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    1