Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
本以太坊教程主要是介绍:搭建一个开发环境、编写编译一个智能合约。+ V, B, o: U" O. z) x+ |7 U7 c
1 s: l& m; U5 g
    以太坊是什么
) q3 y# f) F( m/ z! N8 i2 E- V8 M$ x
    以太坊(Ethereum)是一个开源的有智能合约功能的公共区块链平台。通过其专用加密货币以太币(Ether)提供去中心化的虚拟机(“以太虚拟机”EthereumVirtualMachine)来处理点对点合约。0 W' }% V/ j4 |. O$ V% W, f

+ P3 \; a/ g( B% k$ v    以太坊的概念首次在2013至2014年间由程序员VitalikButerin,受比特币启发后提出,大意为“下一代加密货币与去中心化应用平台”,在2014年通过ICO众筹得以开始发展。目前以太币是市值第二高的加密货币,仅次于比特币。
$ E: c: s/ J  t( D. G0 P
% T3 R3 A5 P5 J" X, W; d    以太坊区块链是什么?
! R- @8 u0 C3 B- w$ u5 |+ ?
/ i" X2 q3 f' y+ O$ P    以太坊区块链有2个主要组件:7 W- P# d' \  D6 M1 Z

9 Y; M9 w. \& q    数据存储:网络中每笔交易都存储在区块链上。当你部署合约时,就是一笔交易。当你执行合约功能时,也是另一笔交易。所有的这些交易都是公开的,每个人都可以看到并进行验证。这个数据永远也无法篡改。为了确保网络中的所有节点都有着同一份数据拷贝,并且没有向区块链中写入任何的无效数据,以太坊使用一个叫做工作量证明的算法来保证网络安全。
! b1 O& Q/ {8 `( J  l9 C9 [/ v) c# I! w4 O2 C9 b! k
    代码:就数据的层面而言,区块链就是存储交易。在以太坊的世界里,你可以通过一个叫Solidity的语言编写逻辑/应用代码(也就是智能合约)。然后用solidity编译器将代码编译为以太坊字节码,并将字节码部署到区块链上(也有一些其他的语言可以写合约,不过solidity是到目前为止用得最多也是相对更容易的选择)。所以,以太坊不仅仅会存储交易数据,它还会存储和执行智能合约代码。, n/ N  `, q  C% V' _5 T  M! S
! Z+ x2 `! o5 j+ ]( p
    可以简单的理解以太坊区块链的作用就是存储数据和代码,并在EVM(EthereumVirtualMachine,以太坊虚拟机)中执行代码。) B, p! Z  q% E1 f
2 J0 m6 y4 i3 `- b' A
    要准备的基础知识* _; l2 S. C& v& [4 [

6 [8 A0 H: L& u    为了进行以太坊开发,你应该对以下语言/技术有基本了解:3 N$ n5 R& H9 g: r1 f3 x+ M
* l# j- Z3 ^+ ^3 X+ O- s; s9 a
    熟悉某种面向对象语言(如Python,Java,go)1 O' q0 \/ T9 R

& ]% [5 H$ B3 V0 w* H    HTML/CSS/Javascript
4 ~  l$ A( h& i3 y/ k3 @9 a* R
3 w8 |# t, Q# j; s% K- Z6 z; m2 d4 A    基本的命令行交互如Linuxshell命令5 X! E! ?" f& O8 K

; v* ]. K+ U, W) v% L- m* ^    理解数据库的基本概念+ d+ G4 [* b; F& N/ F- S
1 f1 _  t/ N" U
    为了构建以太坊去中心化应用即Dapp(Decentralizedapplication),以太坊有一个非常方便的JavaScript库即web3.js,你也可以在一些js框架中直接引入该库构建应用,比如react,angular,vue等。' Q  y# S9 Q2 x9 U* ?( W& a
. H: m- A3 o3 g0 F4 `& y% N
    示例:一个以太坊投票应用
8 Q* \" H& ]& d* x8 X6 o. {# h7 M, i) P( {6 H
    以太坊教程示例中,我们将会构建一个简单的去中心化投票应用。所谓去中心化应用,就是一个不只存在于某一中心化服务器上的应用。在网络中成百上千的电脑上,会运行着非常多的应用副本,这使得它几乎不可能出现宕机的情况。你将会构建一个投票应用,在这个应用中,你可以初始化参与选举的候选者,并对候选者投票,而这些投票将会被记录在区块链上。你将会经历编写投票合约,部署到区块链并与之交互的整个过程。你将会了解什么是一个合约,将合约部署到区块链上并与之交互意味着什么。
% f! }: Z3 R8 j$ L9 [  d! }/ [+ V+ X  n( [1 w: T  B
    本质上,区块链就像是一个分布式数据库,这个数据库维护了一个不断增长的记录链表。如果熟悉关系型数据库,你应该知道一张表里有很多行的数据。现在,对数据进行批(batch)量处理(比如每批100行),并将每个处理的批次相连。就可以形成一个区块链了!在区块链里,每个批次的数据就叫一个块(block),块里的每一行就叫一笔交易(transaction)。0 B: z4 ?$ Z6 H& L- R
) v& S- ]# F  ]+ c
    现在,你对以太坊已经有了基本了解,我们可以开始构建投票的dapp了。这将会加强你对以太坊的认识,并且初略了解以太坊的功能。
; d% V6 P& A7 P# w7 o' s
) Q* @% j/ K$ z7 s! }    以太坊开发环境搭建
2 G4 u5 M" z: h" b1 h6 W, Q6 f
# V6 u6 @! N$ }    Linux
) w7 P/ z  Z! [- S  ]# K2 V6 h5 [9 J; W- s* I( @5 E7 l$ Q* h; w6 a
    示例是Ubuntu16.04下的学习环境搭建,你只需要成功安装了nodejs和npm,就可以继续项目的下一步了。
  O+ H3 V! {( a* B' F! {# K6 _+ E3 q9 _$ C7 c4 _
    我们通过npm安装ganache和web3包来为以太坊教程提供支撑。我们也需要安装solc来编译合约。8 |1 @$ O! G% Y3 r5 Q9 n
7 K6 |: D2 p8 j1 C5 m% m
    下面是安装过程:9 Z# G0 v% H4 ?' \

" A/ V$ `$ v5 g* P, a4 e1 V2 L8 A+ K; k2 i, N    $sudoapt-getupdate
  |& c9 S: C& K) I, H( f/ v9 m1 G- X; ^3 |' `
    $curl-sLhttps://deb.nodesource.com/setup_7.x-onodesource_setup.sh) M4 Q: \- n, r+ ~) d! U

8 {6 A2 w; n4 F. B    $sudobashnodesource_setup.sh: L1 c0 P* L2 I0 U1 j1 g% i; v- g' t

2 n; G9 g+ b5 q' R" `    $sudoapt-getinstallnodejs% g) C% U' ]" y) z9 C5 x, }

( O: ^/ V1 j+ [* n8 Z9 S    $node--version
4 |0 V, o9 Z3 B9 ~) D( P) C  Y9 p6 h9 S3 k1 T2 e
    v7.4.0
& _' o* D; J, x2 M
6 \9 r( n: L$ J" E    $npm--version
* V) ^% ^' z% p$ D/ o
' k% k6 O8 X1 Z9 B  ^9 m# Q; v& v' G    4.0.5
  f) F4 k% D  B7 \% J9 w9 N' p4 ?6 Q$ z) {# q
    $mkdir-pethereum_voting_dapp/chapter1
9 Q, y0 C9 _1 L5 q" n) m: G$ C, L( w7 \# `% s
    $cdethereum_voting_dapp/chapter1
# A7 R0 j* Q6 n/ P. @
; `' n4 @$ L/ P$ |! J    $npminstallganache-cliweb3@0.20.1solc
+ r+ {3 F. _# y1 F9 O" y5 g$ y9 G$ L# l+ |' {/ _
    $node_modules/.bin/ganache-cli( W& C1 ]& y$ }- v: R# ^
/ ^/ \! l" h$ G3 T% z8 I
    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到下面的输出。8 i2 X% [; V" {) L) X

8 x$ J; B) h5 O! v) W! A) v/ A% u    GanacheCLIv6.0.3(ganache-core:2.0.2)- Y5 H$ O* U8 N" v& k/ Y6 I* K/ _

, @7 K2 i/ @: x9 `    AvailableAccounts
2 l6 f: g' P& y8 c% C1 x, v5 E% I
    ==================7 k0 Y/ i* U, p. U& O
, @* {. V+ S1 Z9 \) L& {
    (0)0x5c252a0c0475f9711b56ab160a1999729eccce978 t: J" T7 ?' R) l7 I+ `9 s) }- v
* ^" P, X5 J' t: X, g8 O
    (1)0x353d310bed379b2d1df3b727645e200997016ba3
% ~! w6 ~. V5 i! N# L. v+ Y% H
) o0 O6 f- u8 B8 r' s    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd235 s9 `8 t  ?' K" A

7 q$ l% H3 P' s3 X8 X' t    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5/ F8 c. Y7 |) C, W8 Y5 c
9 A2 P6 y0 }, Z: {( t$ b* h
    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798: U( V) G1 P. V" R/ O9 b

4 x7 j/ k9 }: z% |5 o' G& ~    (5)0xda695959ff85f0581ca924e549567390a0034058
( U" w  `* e) F1 q5 @& u$ N! K8 q' D* b' @
    (6)0xd4ee63452555a87048dcfe2a039208d113323790
$ a- A" `9 s0 @+ T" r5 b
) c8 H0 Z8 d# ~- A' d8 m4 e8 u) }8 }    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14
" Y. U4 C- w* n- G# z8 ?/ p* r- s1 _% W  N6 h) b6 H% p
    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42
% L" I: D9 E& J8 ]! g
# d- q9 r, ^% `: s1 e    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36/ p1 B( c/ x' J8 V7 Y! x0 D

8 }1 `. ]0 ?9 O    PrivateKeys8 k2 b2 u/ a, s9 y! z$ N8 g
2 H: ~. M. e5 V" M/ M; G
    ==================8 x4 ?- z0 y0 h$ x, r) s' {

' X4 i( k  m2 l% g+ Y& \/ p( U; i    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b
  x! R, |% G' Z5 h
5 x" `% N5 K) B* N- _! A    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603; q: c4 {+ V) K0 P# R( P1 U- D* m
8 b: V, h& ^* q3 K8 r" X
    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99& X4 \' F$ [6 `8 n& e; P/ k% M

% G' T5 c% U& l3 z* A  _4 l; ^: s    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f354304 l0 n8 D! `/ ?7 }9 x

2 z3 d9 z5 g* j5 }    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8
" e+ u. N% M! |. R& I0 H+ j  L) n+ E, I
    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc3 a6 q) U, j* |6 f! d: G& Q: D
' _( P& k$ J+ @3 ^
    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9; Y  L( x( l* A! a
* Z8 D  C5 m  A+ N
    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d7 |, Y8 r9 }! F# e0 w5 O" n
: u# \. }' o0 h0 ~
    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
6 R, W4 M9 [( i7 F* Z  S! n9 y" l; }
8 H+ c/ g8 U! ^+ ~' Z5 C  L    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0( [9 s0 S6 p- ]2 `( u# N

! H, G6 N4 d  K- ?. V# e: L    HDWallet* `6 ^" g; p% a+ b' a4 p) B) V3 U
* c0 Q0 r3 \- {
    ==================3 t7 Y7 A3 p; {/ I/ K

) {5 l" }' o$ _    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella1 z8 l+ a1 a9 J! i: H
# n5 X5 m  @. N7 l" m/ t1 Z
    BaseHDPath:m/44'/60'/0'/0/{account_index}
4 G( j( H6 K, d8 j; e
3 N  s% F  Z1 N3 H& u    Listeningonlocalhost:85451 }8 q/ Z" A- x; {, a4 p2 v' J7 c

7 M8 e0 b# C1 O2 O# p    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。- o& C8 [3 r3 P' M# {/ h! n
4 D1 o+ v$ _! ~
    MacOS
2 r% @( o+ M  w3 g! x7 T" E; R
4 i/ v2 V( B2 P. r2 F    如果你还没有安装homebrew,请按照https://brew.sh/的指示安装homebrew。homebrew是一个包管理器,它可以帮助我们安装开发所需的所有其他软件。按照下面的指示安装所有其他所需的包。
  o: K' K7 D9 a! X5 k
3 J  d+ c; q  J0 ?& I    $brewupdate1 O% B8 P  {; Y- a6 L
9 k4 o4 [+ M- ]+ W0 A
    $brewinstallnodejs: r* f, Q. G# p4 I' L, t* o

" C0 L! k9 h8 ~' [7 h    $node--version
; E; z3 {& K' N* T" @: ?) o5 ~; n% v% ?7 }1 e
    v7.10.0
* o- ~+ Z8 ^! q* w( b$ |" Q( Q8 J+ d: _/ T1 ?8 r
    $npm--version, w7 f: \% e# _& W

& W+ B9 F/ ?7 ^( b# X/ K, i! I    4.2.08 C: a# z; d7 [& M- E; K; k  ?# Y$ c

8 D# |+ O- Y8 J, F" F    $mkdir-pethereum_voting_dapp/chapter1
# f. Z: A# f6 x! ^* o0 n, j& n: }0 m( i$ F) I
    $cdethereum_voting_dapp/chapter1
0 P& p1 q4 c  L5 F9 A
6 W) k4 `, Q* s* A    $npminstallganache-cliweb3@0.20.1solc
& ~! }. M8 @# I0 X
( A. U0 E- O' O: \9 M    $node_modules/.bin/ganache-cli. @* c7 N$ w: H  a' H

2 t& m* \+ D4 ^7 K1 {0 t3 f$ Q% X    我们通过npm安装ganache和web3包。我们也需要安装solc来编译合约。! ?6 x+ o1 F" d; J& r
, T! E1 Q' R2 k# s
    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到右图所示的输出。  p( ^/ O  t2 [, g
0 s: m0 T2 u: n/ B9 p
    GanacheCLIv6.0.3(ganache-core:2.0.2)
- g/ X4 X; {/ X% k# c1 A0 _* v. s) Q+ [$ F5 S0 D
    AvailableAccounts8 `: Q8 V4 x7 @- G
' E9 C( f2 k& u0 \9 Q+ J  \, |
    ==================, U/ ^& `; v4 k/ i9 I5 ]6 P) J

  P! M3 V1 V5 q* n: l    (0)0x5c252a0c0475f9711b56ab160a1999729eccce97, r' y8 v+ E( z5 n
  R# G: ^% H0 j" k
    (1)0x353d310bed379b2d1df3b727645e200997016ba3
5 {4 y0 K. ]2 T8 _
2 x- Z* u- @5 c# j1 u    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23# a3 |5 A. w4 i" Q& S( w8 t1 b* h2 y

5 q- c6 C% {- {! u& |9 C    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5
# F' g+ \4 n% T: D( P$ y
1 @! u4 a2 s' b7 L) v. p) H    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd27985 g+ b2 T  u# k; y

6 b3 D" N: K! o    (5)0xda695959ff85f0581ca924e549567390a0034058
2 Q$ P* Y6 ^2 T  _, O; i4 n, Q% E) s+ E: U( C
    (6)0xd4ee63452555a87048dcfe2a039208d113323790
) j4 g% |, L! z1 ~1 g! h2 U* g" C' B* h; o8 S$ G$ w* G  A) q
    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14
% b; n( v# K: F, s# K; c- v$ G" X* W+ v3 D/ c/ l
    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42
7 }( y; C, ]" k$ j& W3 |" H( d/ W3 `& D2 X4 w) J+ p" B3 c4 L
    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36
5 C3 s( l$ h# y  I2 r8 o2 r, P- g; t; C' R2 {8 `
    PrivateKeys
# l2 X$ g3 |/ p" j
5 X0 a) D' P! a$ @1 H    ==================$ c4 `1 I0 `) Z

/ ?! T: |- ]8 V' n8 L6 d5 g    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b+ T, L) q, e& L+ {# y( H

3 \9 c! n3 \4 A1 _, ?) S    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603
& r3 L* w, j7 J" v1 h4 l* @
2 [0 O; ?, ?  Z2 d) z& O    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99
* r, l3 e( ^% C; D( d" B0 Y8 K3 U- Z& k
    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430
2 S0 B8 `7 l% E# [% U- @+ J" Y
* ]/ S4 I0 R" _. U    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a85 f8 ]; w# b, `/ m  L: k

! c4 b- k& x2 |    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc
% v7 E, [! w9 {8 f, }6 y; v& |; s) J. u4 o2 R9 u! r* j' a
    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a97 z8 [% I2 g: [  g1 |
1 Q) D4 G. i4 p4 G8 }
    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d2 j4 c% e! y) F8 E, i# @
. I; _( [7 O4 J
    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a+ }. h& y5 t. u  d: h
) @1 `/ f2 a! T& u; M3 n" O8 u8 Y
    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0
" `! Z7 b- ?7 \
$ W% b$ l& W8 V: {/ {    HDWallet
7 r2 M* |$ A, Q# ]* l& r& V
; s9 A+ R3 X1 H, N1 X9 U    ==================
" h2 Z1 j! W- d3 `; a
# V' A9 ?. j. z, T/ m4 u) ]7 g    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella: G9 o% D) _8 E+ x+ q* S1 e, p  Q
7 t% A, a5 B$ I% [/ z
    BaseHDPath:m/44'/60'/0'/0/{account_index}% v" _& _1 X& D9 {7 T0 O+ Q

& h2 z* s. a+ e7 |    Listeningonlocalhost:8545
+ ~7 C+ p  ?2 M! {
. g& ?+ u: {) O" o    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是以太坊账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。" Q& \1 R8 N3 v6 g6 G, x3 ?

" o- ^* G# @% ?- b/ C    Windows: C+ {3 m: g9 A5 b: `

* l: t( W& B2 x+ X0 F: j$ P    安装VisualStudioCommunityEdition。如果你选择定制安装,那么至少应该安装VisualC++(目前的版本是VS2017)' d4 Q$ ?9 m" i3 }; g+ \& y) t
/ {+ O. k" B7 O+ o( S) w* W* I; h7 p
    安装WindowsSDKforWindows
- M4 u7 K* M7 M4 s$ s" F2 J- d9 g3 V4 U
    安装Python2.7如果你还没有安装的话,并且确保将它加入到环境变量PATH! [2 v1 P% r! J3 f- q+ [. ~0 e
1 B; L& Q6 i4 N* e6 l$ p! U
    安装git如果你还没有安装并加入到PATH
5 Q, G( p( s: x) b# U8 Y3 {2 B; X: J3 n& ?: s0 }! _" b& m# N, W
    安装OpenSSL。确保选择了正确的安装包,并且只安装完整版(而不是轻装版)。你必须将OpenSSL安装到推荐安装的位置–不要改变安装路径
7 A0 N5 T7 g" h( t0 M( b
& E0 q/ s) R7 n: Z7 F; A. a    下载和安装nodev8.1.2。不推荐使用版本v6.11.0搭配VS2017
/ k, j5 L( }  x# q) t2 R! a8 D, G4 v0 Y0 S
    执行命令npminstallganache-cliweb3@0.20.1solc9 X3 C( X; l/ H

, {2 o& W+ t. G    SolidityContracts
, G7 _4 C1 @+ r3 R8 p
( r/ Y3 t4 ]+ R2 ^    现在已经安装好ganache并运行,我们将会开始编写第一个以太坊智能合约。
  Z$ Z$ I- s: m' P; K: X, ]& M; Q' `9 S
    我们会使用solidity编程语言来编写合约。如果你熟悉面向对象编程,学习用solidity写合约应该非常简单。我们会写一个叫做Voting的合约(可以把合约看成是面对对象编程语言的一个类),这个合约有以下内容:9 Z. n: i* _( y0 q  N& z
) k$ B$ L/ }3 `
    一个构造函数,用来初始化一些候选者。+ X( C, l2 M8 o. F

) m3 t; C! L$ e( w& s    一个用来投票的方法(对投票数加1)
& W: p5 M; a/ M$ e  I$ K; m6 q, i4 A' P, N$ p
    一个返回候选者所获得的总票数的方法* w% q. M. d) j2 z1 I  Q. k

* g- ]  W3 y& [( k2 a    当你把合约部署到区块链的时候,就会调用构造函数,并只调用一次。与web世界里每次部署代码都会覆盖旧代码不同,在区块链上部署的合约是不可改变的,也就是说,如果你更新合约并再次部署,旧的合约仍然会在区块链上存在,并且数据仍在。新的部署将会创建合约的一个新的实例。
% L% A; E4 H3 z" t0 s) G; D6 G- M9 T" l
    pragmasolidity^0.4.18;
" ^1 s( {  N2 c
+ o" J" [# y( N/ T& X0 C    contractVoting{' S- a; j. z! o

5 J. f! D9 }! A4 B; ^! j    mapping(bytes32=>uint8)publicvotesReceived;: ~6 V: e+ t0 i) N- O

/ \$ c1 X! u7 N9 z4 f    bytes32[]publiccandidateList;
0 V5 L  L% k' q; F( Y# y0 N" K. C1 X; f) |2 |7 k
    functionVoting(bytes32[]candidateNames)public{' i3 B4 s7 Y/ S. k$ E$ E

6 ^# |' a/ b6 r/ v) k    candidateList=candidateNames;
# r+ m# V9 D5 s! D. _( Z! l2 u, L' {; _: V( b2 y
    }
% }$ z# p4 j* s! Z  l, g4 k. n- N
; P& R2 ~8 Z4 [/ L" t    functiontotalVotesFor(bytes32candidate)viewpublicreturns(uint8){
. U3 Q% T* Y* {2 o9 M- @: j  A( k" w, d8 v) c9 f
    require(validCandidate(candidate));
2 `. w$ B. H5 l' C3 h6 f5 R7 ^9 G
! R( F* ~% z, r0 _0 }9 R9 [! q    returnvotesReceived[candidate];5 ]) C5 z) r& u4 q2 u& W3 y8 W& D
5 j* N% n2 Z4 q0 [$ F. E
    }
+ b/ X' ^$ `  ]- F
* B' u$ n' D% R( X! s5 K1 S$ Q5 I( T    functionvoteForCandidate(bytes32candidate)public{
% Y0 |" R1 n! d$ }7 z
6 U  d2 H3 h5 s$ y1 Q8 I' r    require(validCandidate(candidate));
2 \9 w  N, N4 R1 Y" @/ X: f
  P! E3 B6 n+ ^% k! B    votesReceived[candidate]+=1;1 q1 X" a6 a6 ]; j; Y

! F* u% Y4 l; m' {9 d    }% n3 s( `" z0 h- g# X0 b9 }
. f& ]# J! ?9 L1 _2 r6 q( C( s; ?8 N
    functionvalidCandidate(bytes32candidate)viewpublicreturns(bool){, }! [9 k: J3 `' m& F% Z: S
: C2 c# z4 L4 C/ C. N% g+ k
    for(uinti=0;i
- p/ V9 X% [, b5 [4 q( ?% |3 H- L; a1 U+ ~  U7 e$ P
    将右侧代码拷贝到一个叫做Voting.sol的文件中,并保存到chapter1目录下面。
/ C0 ~; A$ L0 C, j$ |5 v" T3 [( D
7 G5 U  b8 e% ?0 f% E6 v" V    代码和解释
6 O2 O3 {8 w: i
3 w; ]3 Z: ~3 Q8 ]4 G# u    Line1.我们必须指定代码将会哪个版本的编译器进行编译
% s5 j: H+ Z8 M3 D) O2 |
4 U$ U0 |0 n0 [2 W4 H9 `3 i    Line3.mapping相当于一个关联数组或者是字典,是一个键值对。mappingvotesReceived的键是候选者的名字,类型为bytes32。mapping的值是一个未赋值的整型,存储的是投票数。
% Q. s! ~  X4 `% x
0 i1 V) }- ?. T7 @" O: j    Line4.在很多编程语言中,仅仅通过votesReceived.keys就可以获取所有的候选者姓名。但是,但是在solidity中没有这样的方法,所以我们必须单独管理一个候选者数组candidateList。
5 M) Z7 F2 {$ m. V4 r4 r5 k. t0 [. N+ P
    Line14.注意到votesReceived[key]有一个默认值0,所以你不需要将其初始化为0,直接加1即可。
9 z  D  y! S* |; c1 q& f7 G7 A& X* C2 d! S% {3 G, j& N8 g; J
    你也会注意到每个函数有个可见性说明符(visibilityspecifier)(比如本例中的public)。这意味着,函数可以从合约外调用。如果你不想要其他任何人调用这个函数,你可以把它设置为私有(private)函数。如果你不指定可见性,编译器会抛出一个警告。最近solidity编译器进行了一些改进,如果用户忘记了对私有函数进行标记导致了外部可以调用私有函数,编译器会捕获这个问题。这里可以看到所有的可见性说明符。2 }' ]/ C2 R. i  X+ C
) P2 m+ X. O0 Y. O3 Q! y6 S8 U
    你也会在一些函数上看到一个修饰符view。它通常用来告诉编译器函数是只读的(也就是说,调用该函数,区块链状态并不会更新)。所有的修饰符都可以在这里看到。
" h) R! m" h/ j/ o# v0 U3 H
2 E. V, w% E% i; E: `9 w    编译智能合约$ x! c4 Y7 e) A

0 H8 N- p5 i( A/ X    我们将会使用上一节安装的solc库来编译代码。如果你还记得的话,之前我们提到过web3js是一个库,它能够让你通过RPC与区块链进行交互。我们将会在node控制台里用这个库部署合约,并与区块链进行交互。
7 U( ^9 q- ?. ]4 K0 X" O/ k  c2 F+ @! j1 A
    首先,在终端中运行node进入node控制台,初始化web3对象,并向区块链查询获取所有的账户。4 A1 u- N. R. I9 D

7 o6 d7 U* `! x1 o$ |9 S3 }+ r    确保与此同时ganache已经在另一个窗口中运行" D6 T% }! y! B0 G
: j6 f7 w2 d, z" i5 E! q9 N
    为了编译合约,先从Voting.sol中加载代码并绑定到一个string类型的变量,然后像下边这样对合约进行编译。
8 W6 m- h6 O) \7 b0 y, K) |9 R. O' ]' e. {. N9 s/ U9 I( ?( t! j2 d) }! a
    $node( b) o% {& a# ]7 M
, }8 w$ I' e* \7 a+ t; I) Y
    Inthenodeconsole% ]) E$ Q1 W* l* c; q: j: g) ~

* e$ n2 r) S; f  o& W    >Web3=require('web3'); U* k8 n- @/ d2 [4 E
9 f2 T, U3 C& J$ }) w
    >web3=newWeb3(newWeb3.providers.HttpProvider("http://localhost:8545"));
* ?$ \  c$ s& a% m# A# n; _5 w" ]7 M( Y% J! D& g
    >web3.eth.accounts
( R9 Z4 g# b- m2 B2 B% W2 e: x" M( `1 T$ v) o8 k* j& O! Z  a
    ['0x5c252a0c0475f9711b56ab160a1999729eccce97'- p% z6 h/ K& m( n
5 V- J4 f1 \; d2 {1 H
    '0x353d310bed379b2d1df3b727645e200997016ba3': x7 Z5 @# P1 H- x' ~# s0 b  C- K

* a1 I$ k4 I" J( a! R; r2 z    '0xa3ddc09b5e49d654a43e161cae3f865261cabd23'6 H( J( O* s; V/ j2 h
6 Z' v( x1 P( j- Z/ e' B
    '0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5'% n$ K9 X4 Y$ h% {

* h+ @' \. E+ X: a9 h5 D1 h    '0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798'7 ?9 w" F: ?! o+ G/ I- O# O& f
, [/ d( U' e( M9 W% C, _2 p4 O
    '0xda695959ff85f0581ca924e549567390a0034058'; ~" h& A* I* t4 X3 a

; x/ O) c" M) h4 O2 ?    '0xd4ee63452555a87048dcfe2a039208d113323790'; k! e! E; H/ z1 @
( Q! [& S* ^6 m% M* U
    '0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14'" [6 a  x/ p$ H2 ]

2 g/ I- r/ U1 Y: R, E' @3 u0 \( i, a    '0xba7ec95286334e8634e89760fab8d2ec1226bf42'
; b' x# K1 f" @. T" I3 \- D! g" F6 s+ [1 ~# a) f
    '0x208e02303fe29be3698732e92ca32b88d80a2d36']
- r! z1 T3 w2 i" @; l% \( l' R  ?$ g6 k5 J8 O  c* U  n
    >code=fs.readFileSync('Voting.sol').toString()
% V# m2 E2 d3 d4 D8 `- D  L) p1 u  r
    >solc=require('solc')
0 _6 V' ~+ r7 S8 g6 Z  s6 r
. }; y* |' S3 y: r: V# U2 B    >compiledCode=solc.compile(code)  k- f7 y/ E2 b0 v' m$ x

8 Z( P! B" @/ w    当你成功地编译好合约,打印compiledCode对象(直接在node控制台输入compiledCode就可以看到内容),你会注意到有两个重要的字段,它们很重要,你必须要理解:
0 b/ I9 o; N( ?
5 H$ ]1 \. B8 p% R    1.compiledCode.contracts[’:Voting’].bytecode:这就是Voting.sol编译好后的字节码。也是要部署到区块链上的代码。# u3 m4 h8 @" L1 @. D3 J

  M7 u4 D( r  o1 f  q; u' p6 ^: G    2.compiledCode.contracts[’:Voting’].interface:这是一个合约的接口或者说模板(叫做abi定义),它告诉了用户在这个合约里有哪些方法。在未来无论何时你想要跟任意一个合约进行交互,你都会需要这个abi定义。你可以在这里看到ABI的更多内容。$ m* b7 o  U' [" J

7 E, i% z. V/ f1 `2 r0 j    教程参考汇智网的DAPP开发入门教程,如果大家等不及博客更新,也可以直接访问这个以太坊教程。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

dancing520 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    1