Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
本以太坊教程主要是介绍:搭建一个开发环境、编写编译一个智能合约。
$ t, W5 y  B4 u( g$ {+ m
% c8 W+ C6 n/ X( X* Q9 ]. Q    以太坊是什么
* o: ^# I& Y8 `
: F# x/ X/ F+ B/ U1 N3 \    以太坊(Ethereum)是一个开源的有智能合约功能的公共区块链平台。通过其专用加密货币以太币(Ether)提供去中心化的虚拟机(“以太虚拟机”EthereumVirtualMachine)来处理点对点合约。
: {/ P" q& X0 Y9 h- A. y& b
5 K' ~3 c) d+ T6 D) b4 Y9 H    以太坊的概念首次在2013至2014年间由程序员VitalikButerin,受比特币启发后提出,大意为“下一代加密货币与去中心化应用平台”,在2014年通过ICO众筹得以开始发展。目前以太币是市值第二高的加密货币,仅次于比特币。6 f( |& f/ h5 d

. E$ p0 ~3 r; Y0 T    以太坊区块链是什么?
3 m% n* F+ @- S9 B6 E
( T, {4 E' S0 a% [" |& N# b0 R    以太坊区块链有2个主要组件:
, E8 x. ?! Z, U' l5 c) f3 J5 N3 `  Q& H
    数据存储:网络中每笔交易都存储在区块链上。当你部署合约时,就是一笔交易。当你执行合约功能时,也是另一笔交易。所有的这些交易都是公开的,每个人都可以看到并进行验证。这个数据永远也无法篡改。为了确保网络中的所有节点都有着同一份数据拷贝,并且没有向区块链中写入任何的无效数据,以太坊使用一个叫做工作量证明的算法来保证网络安全。- J+ n  i% Q7 v3 C& a$ ]) `5 f

0 J4 C2 L# E* E* V' w3 O, u    代码:就数据的层面而言,区块链就是存储交易。在以太坊的世界里,你可以通过一个叫Solidity的语言编写逻辑/应用代码(也就是智能合约)。然后用solidity编译器将代码编译为以太坊字节码,并将字节码部署到区块链上(也有一些其他的语言可以写合约,不过solidity是到目前为止用得最多也是相对更容易的选择)。所以,以太坊不仅仅会存储交易数据,它还会存储和执行智能合约代码。: q5 E' z- [5 S* i* G: i8 u0 P0 T4 @

$ a! v: c/ C+ S. X0 R* T    可以简单的理解以太坊区块链的作用就是存储数据和代码,并在EVM(EthereumVirtualMachine,以太坊虚拟机)中执行代码。
8 [  a" P4 z- g0 S5 {. \  P1 L# W1 Y# ]9 J0 f- x5 k# e& }
    要准备的基础知识
+ s" k3 u& o! q
( |/ I! d* o7 p+ P6 D7 Q. B    为了进行以太坊开发,你应该对以下语言/技术有基本了解:
0 p& s, c# b$ i8 w% e7 \: n
8 w, Y: f0 R3 F5 t& w9 @" E    熟悉某种面向对象语言(如Python,Java,go)
8 A) b' P+ w( x! |7 r& w
+ _+ [1 u1 G8 p7 |, E& A- M    HTML/CSS/Javascript
$ V! q+ A- p6 l/ P" T0 X/ L# G; F( x
    基本的命令行交互如Linuxshell命令
1 k( |9 j/ ^* V; J
. z  w  H2 {+ H    理解数据库的基本概念- J1 Z9 }" M6 ^( Y% [
" g2 `, Z9 {: E) a
    为了构建以太坊去中心化应用即Dapp(Decentralizedapplication),以太坊有一个非常方便的JavaScript库即web3.js,你也可以在一些js框架中直接引入该库构建应用,比如react,angular,vue等。. Z. F  Z4 |3 o7 V. x
" C9 T% N9 D, W1 P$ I  A
    示例:一个以太坊投票应用; C6 ~1 @+ i: R5 X" |
, I& Y3 I; b$ `% W& p3 d
    以太坊教程示例中,我们将会构建一个简单的去中心化投票应用。所谓去中心化应用,就是一个不只存在于某一中心化服务器上的应用。在网络中成百上千的电脑上,会运行着非常多的应用副本,这使得它几乎不可能出现宕机的情况。你将会构建一个投票应用,在这个应用中,你可以初始化参与选举的候选者,并对候选者投票,而这些投票将会被记录在区块链上。你将会经历编写投票合约,部署到区块链并与之交互的整个过程。你将会了解什么是一个合约,将合约部署到区块链上并与之交互意味着什么。/ W, t2 d/ N7 Y: V0 x

' L: |! a$ u, @7 a  I" P3 Y    本质上,区块链就像是一个分布式数据库,这个数据库维护了一个不断增长的记录链表。如果熟悉关系型数据库,你应该知道一张表里有很多行的数据。现在,对数据进行批(batch)量处理(比如每批100行),并将每个处理的批次相连。就可以形成一个区块链了!在区块链里,每个批次的数据就叫一个块(block),块里的每一行就叫一笔交易(transaction)。
7 I3 }9 U) q! c, r! T1 g# a" K5 N  K
- `5 O: U! n" X    现在,你对以太坊已经有了基本了解,我们可以开始构建投票的dapp了。这将会加强你对以太坊的认识,并且初略了解以太坊的功能。
8 {8 B# P* z( }2 m- H
* r7 w& ?9 K4 N# A, E5 j; V    以太坊开发环境搭建$ p( p4 l- g' z$ H8 {
; T9 i# [6 T: l$ J5 ^  _5 {( ]
    Linux
3 L: q  f) N1 @; T  B
7 M0 N/ v! P! E  ]; O) }: l    示例是Ubuntu16.04下的学习环境搭建,你只需要成功安装了nodejs和npm,就可以继续项目的下一步了。" F1 M9 V! @4 ]; e
* x5 ^  j0 V$ J0 B! ^
    我们通过npm安装ganache和web3包来为以太坊教程提供支撑。我们也需要安装solc来编译合约。
% D% h* L) s" _+ K! h& |" |: T. n: M+ o) k) p' X6 R  m
    下面是安装过程:! b( m4 h5 [) _0 o5 F$ q
. x3 N+ H- |4 c
    $sudoapt-getupdate
5 i1 Y% X/ W3 A: v' d  F2 d2 Q3 R$ l
    $curl-sLhttps://deb.nodesource.com/setup_7.x-onodesource_setup.sh6 i& i) Q6 d$ z( H. ^9 ^

# V  I7 F0 ~! H" p. s* U    $sudobashnodesource_setup.sh
( P3 J3 I; L5 `8 c/ ~  a/ F5 A, A1 ~5 D& Q
    $sudoapt-getinstallnodejs/ }7 d. h5 c0 ^  ^
- l# Y1 |* @4 V/ C2 w! [' m0 g
    $node--version
& f! \6 r, E) @- U( k$ V# ^. p  ~5 E( z3 k: l
    v7.4.0' N4 M, }# V8 J' Z

4 N( O6 t; z" Y( t    $npm--version( T  \/ K' Z9 x% u

8 o9 w" g7 P  c1 K; E+ j& ]5 f    4.0.5
& [" }  _- b; x7 k2 I+ r! a* I$ t8 o
    $mkdir-pethereum_voting_dapp/chapter1  j5 p9 s# c5 A) q0 ^5 J
% ?0 E% _9 J  l1 K
    $cdethereum_voting_dapp/chapter1, Q( Y% u: a, c: A
1 F5 h" r& M+ s: r8 M, g: v% f
    $npminstallganache-cliweb3@0.20.1solc
5 f- Y  n+ a: a0 N# n1 R- v( L  W9 s6 h3 ]' O" T6 i
    $node_modules/.bin/ganache-cli* j# y* l9 f: G9 t  U' c; H3 e

3 G8 V6 n+ ^" d: C+ S& @5 q4 ?    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到下面的输出。
/ v; j4 [1 V! g5 C: B! ^  I7 e; A7 y
3 y; a# T" y5 Q; z3 J* e( N. m+ z: a    GanacheCLIv6.0.3(ganache-core:2.0.2). g: n: N5 }  F. a2 R

8 p' ~, Q$ k8 W/ d, P7 d    AvailableAccounts
7 P) p- s  L3 ]
" K7 _4 D; m# j, r+ Z    ==================
  y5 ?- z# ^! D0 ^5 L7 l* {* R! @  n
    (0)0x5c252a0c0475f9711b56ab160a1999729eccce97
# m; n4 B1 w% r9 Z' h; m( J; n( @' z1 T: z" d; Q% a' W
    (1)0x353d310bed379b2d1df3b727645e200997016ba3" c! {  v, G8 `/ C: {# Y

# {% U0 q) e% B+ P    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23
8 h/ E( S& _: B+ }6 `4 E
* u5 \5 F: X9 M1 g# C    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec58 p% d  M; ^; i. `2 \' G

8 m  I, G# P: p% F5 F) a. M    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd27986 [) D! u4 A, j8 Y0 }3 }1 s8 E

1 p- p1 e' ^. Z: \    (5)0xda695959ff85f0581ca924e549567390a0034058# z+ P% D+ ^9 V, ~4 x3 Q
1 o4 X- N/ B  m4 l( ?& S
    (6)0xd4ee63452555a87048dcfe2a039208d113323790
+ _; r6 Y( A3 @' z; {* C
& k- Y/ h, A5 Z0 ~6 I7 ?$ A. ~8 v    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d141 ]( T, }) |. ]  A! s3 k% ~
4 P+ v1 u6 x1 R* s1 g3 p4 r
    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42: [/ D6 Q% N1 Q9 K7 C! {
  K2 g. I3 T7 ?+ ~$ T9 R2 M
    (9)0x208e02303fe29be3698732e92ca32b88d80a2d362 ^* O2 f' H2 m( k* M

# o1 |, E8 {/ p    PrivateKeys
- }* l2 ^! p- q' \! q  J- d# @
. Y! t' e& V6 J( S! q    ==================5 F- w- }& t- ^7 _" y
9 g3 f) l2 R# H/ p& Y5 s
    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b
9 ]$ x! b( @9 u" o4 `5 B- T8 B4 u$ t: C5 l
    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603
% Y. I& l' e: B# z
7 A8 R8 u- R5 d: C    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99
! W1 X( X! J( x6 v7 ], {! X+ `* N: m$ z& u* D# W4 X  K1 Q# h
    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f354300 j( c- h. s; t- N# d, F
6 K% I2 O/ D; ?# \
    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8, e( A9 ~9 P. z( O9 Y7 m2 x
+ A! K/ x+ y( l, p
    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc7 A$ C. Y" G: ~, A3 a8 Y

0 ^5 V' r& X9 d8 h0 @    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9; Z+ I6 c7 }3 o$ D8 z8 b+ J  j; L1 D

) [# r( }# p' ^! e+ J2 }    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d/ Y% X5 W) m1 r, g
- N+ _- o' H) b5 B( m, i, b
    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
8 s3 z' }- r3 h) r) Q% `8 M% d  W6 Y" b7 Y7 L
    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0
8 o5 @( q+ R7 Q- V4 B! P1 x
# m0 {- B) _; G, [    HDWallet
9 e. ]. H7 Q. n/ S
5 ?5 J0 t% A% R- N3 U6 b3 R& |    ==================
. k" S6 y) m1 S& H! M* X- y# P: @: H" i* |  h
    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella
  A1 L& I  {6 E; A# @! z( Z
" @7 F8 `# _- S% W: U; }; M    BaseHDPath:m/44'/60'/0'/0/{account_index}
8 P+ [( e1 l) W( O; m. Y2 Q7 B7 I4 t4 a% ^2 v, [
    Listeningonlocalhost:8545. m2 n0 \! N5 n( Y

3 o( X1 y5 j. I# S    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。
  q% \7 i/ v* ]6 D+ c( x3 u+ D1 S* ^# L2 F
    MacOS3 k6 o* }- g$ L+ ^! u

% f2 k% S9 D. w! H    如果你还没有安装homebrew,请按照https://brew.sh/的指示安装homebrew。homebrew是一个包管理器,它可以帮助我们安装开发所需的所有其他软件。按照下面的指示安装所有其他所需的包。% g/ w$ a' l$ `! Q( {

3 Q$ O" w" E/ a! `- `    $brewupdate( g9 ~# k; l" i1 {" x
. e: c# `% P+ ~8 o* Y, w( R
    $brewinstallnodejs8 p8 w5 b( U8 Z

, v8 v4 X& C5 g' Q3 T. L- q: j    $node--version; Q9 k# I1 u$ ?  X

4 T+ j+ p& E7 ]# A4 H' `    v7.10.0& x! k' t2 {9 C  z0 I
- J9 }- q. X5 S" F) V' h8 O
    $npm--version
: x' C1 r( S7 t" ?; _! q& H: ^
8 @2 {! M( Y8 @: M* C8 L    4.2.0
6 A& R6 n  ?1 V) S
$ Z! V* d# r0 e# r. f: r    $mkdir-pethereum_voting_dapp/chapter18 T! ^$ q9 V1 I& K
' F# O, Q5 D: F' X# p* Z
    $cdethereum_voting_dapp/chapter1% a0 n8 S( N' o" ]; X3 O

% y; Q1 g, q+ P+ s% F# j4 e    $npminstallganache-cliweb3@0.20.1solc
, T* I" v7 u9 O1 v5 t/ K; M( b- _
! `- E7 e4 ~5 |4 u5 z    $node_modules/.bin/ganache-cli4 H3 m# `  R* \

3 k5 V! K# W# i# \( G* b* v1 ]    我们通过npm安装ganache和web3包。我们也需要安装solc来编译合约。+ x; h6 w5 k/ |% Y5 r/ U0 h; Q

  T6 q7 ?7 w8 b    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到右图所示的输出。. x! ?: w' O6 X5 w; T) R5 u
- {1 W' O* P+ D1 H* T2 [4 A
    GanacheCLIv6.0.3(ganache-core:2.0.2)
! K5 L+ _) V/ F# j) {7 i4 W$ L, h
, S7 ]! @( R3 y& Z    AvailableAccounts. T' {. q. ^  g* i& X- B5 f

& j9 x0 R0 h' y! }9 N  g* X    ==================+ @! B4 ?( m: X8 B& N0 _: J
: d! @$ u% Z( V. k" g; b- }, Q
    (0)0x5c252a0c0475f9711b56ab160a1999729eccce97
( ^. }$ S5 ^% K" i+ M- P6 E& B0 O4 J- n6 w! {; G
    (1)0x353d310bed379b2d1df3b727645e200997016ba3
, V8 E: @* \( K% R8 G; }6 q( y' ?8 S, a$ ]
    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd233 Y( y5 c' _; ?7 G
* P1 {- ?8 Z: E
    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec55 e7 m) Y) @: |0 w2 q5 ^
0 w9 {3 H1 s+ u4 x
    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798
5 R+ N6 V. `4 d6 t0 F: Q! c- y4 n# Z* x. e
    (5)0xda695959ff85f0581ca924e549567390a0034058) [- a* N) C( i( v0 e4 j

8 t- J5 Q1 ]( i, n6 I4 J- A4 i    (6)0xd4ee63452555a87048dcfe2a039208d113323790
& M; P5 D3 O) H1 x7 M
, y, f; w0 i$ ?( G4 K( }    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14
* ~9 A" B! n+ c. W$ i$ v6 }0 b1 v3 z0 {' Q5 m, P0 g8 Q7 U
    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42
: ~0 t8 t/ [9 U$ }  L- L3 M
7 T. ?4 M$ n5 S" P+ f$ ]    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36
! k7 Z; H2 Q) x) _+ b  @9 O$ Y# T8 \; A! e/ @
    PrivateKeys/ o( ?2 B: u9 u; J

2 B! M2 X) Z7 X* Y  l0 }    ==================, }& f5 `2 R+ h

( ~6 A  d% U; K4 Y; L- _- W! q; o    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b
  T- w8 D3 s0 w. I( H. J3 r  d. a8 E4 h7 [
    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603
3 ^$ G0 d) _$ z1 ~  {  m, R1 v' o, _! b
9 m# L9 p3 t3 K. ^/ Z1 {7 c    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99. X, `7 Q# V4 I" b* V$ @" B: T$ p

# n2 Z7 H9 L. a, Z# L! z" W6 v# @    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430) i0 y3 I7 f- J7 K

- m  t/ ~8 A. c0 e    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8/ U2 E" R* ?4 u) ~0 H1 F  c+ u
+ b$ p% b" n, q+ \8 a, w! U
    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc
! s- O4 l# r% `( H5 c0 w9 J8 u* Z  U* l- `
    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9
' Y5 f. [; H5 J) p% e5 C5 G  Y. E' ]0 ?  o4 e% P
    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d
& t4 t2 U' n8 h  D. f1 ^& L" ~% |
2 V! h3 K/ s# P# J    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
* K- Z7 n0 n/ f+ U. c" e9 N
; S# \7 I/ Z$ M( i/ t: s+ u1 Q5 ^, A    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0
1 L) w( a; ]: S, Z% Z- s+ X
& L8 M' w% m: v6 Q' |6 W; b    HDWallet
7 W% ^$ ~: P7 r: }# w# S2 w( f: d" B# r/ G
    ==================
8 y: D! H3 O0 ]2 R% w# z6 g4 o, k$ z% Y
    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella
. w" o  A" ^0 R: I/ X7 d5 I! O4 s; g& p% z4 p
    BaseHDPath:m/44'/60'/0'/0/{account_index}
7 x  ]3 C5 [7 s8 M8 ~% u: I3 G% w
    Listeningonlocalhost:8545
$ R7 L% h' m4 m& j# @+ G% u2 N( i
1 l+ Q$ X4 Q3 }) X    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是以太坊账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。
3 H& T, Q  D$ R. k+ s" ?0 r- {' }' P9 T6 d* J5 U7 F
    Windows8 q0 V; B- O$ D9 Y9 X

. l5 @8 _" z5 H" S$ _" Y    安装VisualStudioCommunityEdition。如果你选择定制安装,那么至少应该安装VisualC++(目前的版本是VS2017)
* V% r& Q4 X  `, x9 T  W1 r0 g/ C8 Y+ |9 Y( t1 G
    安装WindowsSDKforWindows* f" s8 x% v( {. `, O" l

: z$ _+ `) m* [9 s5 x$ w% {' J, u, v    安装Python2.7如果你还没有安装的话,并且确保将它加入到环境变量PATH
( d% w' A# Y. R6 ]! ?6 ?+ _# O/ D8 v4 Q# I& }
    安装git如果你还没有安装并加入到PATH
- H9 _8 W! t4 c+ r5 _
. a% _( L/ X/ t. O    安装OpenSSL。确保选择了正确的安装包,并且只安装完整版(而不是轻装版)。你必须将OpenSSL安装到推荐安装的位置–不要改变安装路径, {* g% \/ B" N3 c4 y3 L4 [/ {
( u, l- e' L0 z' T$ {7 O5 ^
    下载和安装nodev8.1.2。不推荐使用版本v6.11.0搭配VS20173 y0 Q: S2 \/ g+ M$ [, m  r

, B  c7 ?% a9 p. D+ `) O# Z    执行命令npminstallganache-cliweb3@0.20.1solc
# y' C+ t( ^& a' T" r5 z3 t6 j; e6 x) Q# d& b+ G
    SolidityContracts$ r& Z/ |% \$ M

% H) T) `. n6 V. i! y0 F# U    现在已经安装好ganache并运行,我们将会开始编写第一个以太坊智能合约。& y" |" m8 d6 d% ], h9 f. g6 o5 Y

9 A! K* [9 C! s7 i1 U" c    我们会使用solidity编程语言来编写合约。如果你熟悉面向对象编程,学习用solidity写合约应该非常简单。我们会写一个叫做Voting的合约(可以把合约看成是面对对象编程语言的一个类),这个合约有以下内容:6 e. p" Q  C7 Q) @+ O

- z2 ]4 {: w, u# w+ Y    一个构造函数,用来初始化一些候选者。
7 E' e/ Z& \2 f( ^2 {. T
2 A% v# `5 O/ t9 [. _! V    一个用来投票的方法(对投票数加1)
! {6 o$ f% Z; G9 N' V
+ X! b3 W1 M" {# s5 Q' }    一个返回候选者所获得的总票数的方法! {7 [3 C' n+ c( l3 F" h

% n8 J0 W7 y& g( \    当你把合约部署到区块链的时候,就会调用构造函数,并只调用一次。与web世界里每次部署代码都会覆盖旧代码不同,在区块链上部署的合约是不可改变的,也就是说,如果你更新合约并再次部署,旧的合约仍然会在区块链上存在,并且数据仍在。新的部署将会创建合约的一个新的实例。
, v( c/ ]. E, K& ~8 u5 a! P& B
  E) j. M8 I% m1 A, f5 X. V1 j    pragmasolidity^0.4.18;
4 m+ n' e/ @9 I8 f3 {/ k3 g  D6 A$ j$ ]) H2 U7 o; @
    contractVoting{5 |* Q8 m& R$ n! ~
0 K0 M# ^' ~/ c4 g% h8 y( P- R9 V
    mapping(bytes32=>uint8)publicvotesReceived;- k/ V% u' i. q5 R. P
4 I. C8 W& J) l/ h* D# C5 k
    bytes32[]publiccandidateList;
( J# i2 C" y" `( M+ A# f, K9 F; f
) i/ I9 t: ?3 Q+ X* o    functionVoting(bytes32[]candidateNames)public{
! ~& J. |. f; z" n- q# F! N' i+ `% E+ T; d; z( B! f% f
    candidateList=candidateNames;/ y$ W' s: i/ t

6 ?6 o7 @2 F/ G+ Y0 `/ ?- M    }, G! l# t1 N6 O

3 u$ a8 l0 l0 a8 u( K    functiontotalVotesFor(bytes32candidate)viewpublicreturns(uint8){" I0 k! R+ h1 P* c# e
0 L: C# r% U$ y
    require(validCandidate(candidate));. B$ s" G9 D3 x5 p, @
7 k" S% X7 Z+ |$ L( t
    returnvotesReceived[candidate];
9 {  {$ D: ]7 V6 O/ y. z: s$ T1 Q& A6 {1 a/ W! S5 C
    }3 E* p' [4 G. U& u0 u7 J/ w, x. t
8 ~( B; g) z  Q3 }1 a8 L1 ?9 ?. |
    functionvoteForCandidate(bytes32candidate)public{
- o# |, X! B- F/ t) y/ Q) Q, b  ]( T5 J' c$ F2 W& I, A- t2 ~
    require(validCandidate(candidate));
* i3 ]/ F; @$ v, W$ _; w4 D6 O
$ `# f7 ^: ^. U2 U    votesReceived[candidate]+=1;- u  A, r; J: H5 T* X

7 _( ^) y4 q) e# p! G9 s8 D6 M2 v2 E) ^    }9 I/ O! t9 q2 o) v2 R$ h

6 G. V$ V% ~: k8 T. @    functionvalidCandidate(bytes32candidate)viewpublicreturns(bool){4 G1 R' K' m9 F" H0 m8 e! k

* Y& R. R+ _. ~+ u    for(uinti=0;i! r* a+ ^7 W/ b- h0 w
9 f* a/ A( B9 I) s0 R9 \
    将右侧代码拷贝到一个叫做Voting.sol的文件中,并保存到chapter1目录下面。9 H6 @7 W; @7 X9 r9 a+ {
+ ]% e6 P/ j" J5 J
    代码和解释
4 J* Z, h1 K* I. w* S# V$ c1 C
3 U0 E- F% s, z: o6 V8 J9 S    Line1.我们必须指定代码将会哪个版本的编译器进行编译
' e6 K5 ~6 c9 }' @9 {8 B# y* V. y& d* J; m
    Line3.mapping相当于一个关联数组或者是字典,是一个键值对。mappingvotesReceived的键是候选者的名字,类型为bytes32。mapping的值是一个未赋值的整型,存储的是投票数。
/ ]# J! Y- |3 Q- P/ P$ p3 }/ g5 f* R
    Line4.在很多编程语言中,仅仅通过votesReceived.keys就可以获取所有的候选者姓名。但是,但是在solidity中没有这样的方法,所以我们必须单独管理一个候选者数组candidateList。
" g7 Q. z( h9 n
; u! f' U( }2 H4 q1 D# |2 d! L! j    Line14.注意到votesReceived[key]有一个默认值0,所以你不需要将其初始化为0,直接加1即可。. ?# a9 }' k2 H: }  s) X
- f" O3 ]2 p5 o
    你也会注意到每个函数有个可见性说明符(visibilityspecifier)(比如本例中的public)。这意味着,函数可以从合约外调用。如果你不想要其他任何人调用这个函数,你可以把它设置为私有(private)函数。如果你不指定可见性,编译器会抛出一个警告。最近solidity编译器进行了一些改进,如果用户忘记了对私有函数进行标记导致了外部可以调用私有函数,编译器会捕获这个问题。这里可以看到所有的可见性说明符。
6 i7 w. G8 c7 e4 R/ y" N; P
* q2 A* d; D2 m1 l/ p# d* `0 T    你也会在一些函数上看到一个修饰符view。它通常用来告诉编译器函数是只读的(也就是说,调用该函数,区块链状态并不会更新)。所有的修饰符都可以在这里看到。
' Z4 M: j" {9 b1 \0 p# f( O& f
    编译智能合约
+ L' ^" s* I% N/ f2 t  g
* X1 U7 \- E. P4 v: h9 r    我们将会使用上一节安装的solc库来编译代码。如果你还记得的话,之前我们提到过web3js是一个库,它能够让你通过RPC与区块链进行交互。我们将会在node控制台里用这个库部署合约,并与区块链进行交互。2 S' k4 m. T* u
2 J9 ?' M/ h4 q$ X) d5 R
    首先,在终端中运行node进入node控制台,初始化web3对象,并向区块链查询获取所有的账户。
2 |+ Y5 q( y1 o7 G
. d: G0 T3 m# G2 P1 m! S    确保与此同时ganache已经在另一个窗口中运行% P3 l1 L& F7 C9 E) `3 f
, f0 b& W1 i# W* o+ Z6 w
    为了编译合约,先从Voting.sol中加载代码并绑定到一个string类型的变量,然后像下边这样对合约进行编译。
7 ~9 b/ t" L% j  k
9 @/ b+ g( I% G3 M) a$ r/ v2 ], E, P    $node
/ M, C: W9 f* M" x
- ~2 f8 |; F) J7 T/ `1 ]4 Z    Inthenodeconsole- ^" w/ {4 P. T  t

2 l, D  k: F/ R- G" K+ z* V    >Web3=require('web3')
1 t$ V8 U) _5 D- f0 |; Z5 E% L& d& }8 ~1 X
    >web3=newWeb3(newWeb3.providers.HttpProvider("http://localhost:8545"));
9 H2 C9 S5 `, Y3 |$ p" E' O0 n1 H) H5 i
    >web3.eth.accounts
" `' H6 b2 o% u# }  G0 s# F7 y
6 o& L: O  g* V2 M    ['0x5c252a0c0475f9711b56ab160a1999729eccce97'7 e5 Y4 N+ @# ^/ ^
# e4 p+ f( Y$ v- t$ g! t
    '0x353d310bed379b2d1df3b727645e200997016ba3'
$ k1 g/ b5 j1 S9 b3 P# M0 O4 _( W+ I& Q4 M
    '0xa3ddc09b5e49d654a43e161cae3f865261cabd23'
& H' X* t+ A$ a1 f% F9 Z) Q: R2 L
    '0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5'; n7 T  a6 @4 M
* k/ S( c# W5 y/ H) j3 r4 x+ u: {4 o
    '0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798'
# A, s1 @% E3 p$ ~3 S) {$ @( F$ y( Q' _$ B6 [% j% n# `# l6 X
    '0xda695959ff85f0581ca924e549567390a0034058'
9 u: e' @( A+ P+ H: ]5 J& |/ C% d% E- H
    '0xd4ee63452555a87048dcfe2a039208d113323790'+ U+ d9 _: n% d& E5 I5 _
& O/ R& y- |, y) d
    '0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14'0 ?* [" @4 E/ x

9 _) f3 j5 L# V" f. f6 C    '0xba7ec95286334e8634e89760fab8d2ec1226bf42'* ~! I7 ~( H7 A7 {0 y

( |( q7 A6 n2 ]/ e7 K, |    '0x208e02303fe29be3698732e92ca32b88d80a2d36']
- p" o- L* F; g2 E" f4 l/ }: ~" V
: J# ]4 v  X: U; X. c; Z" H" W    >code=fs.readFileSync('Voting.sol').toString()8 ^! s# n  c$ L. Q" P

/ t2 r: R7 ]3 o# b1 F8 X    >solc=require('solc')
* ?* f, h% {2 E, O
$ b: [$ O+ J) F3 a- f    >compiledCode=solc.compile(code)
+ f6 f5 M; b% f3 w. @6 i( Y2 \4 |) L# b/ P: s- d) E* _
    当你成功地编译好合约,打印compiledCode对象(直接在node控制台输入compiledCode就可以看到内容),你会注意到有两个重要的字段,它们很重要,你必须要理解:" F/ i$ V# {9 J8 a, g% I
) m# o" T: D4 M4 t4 W
    1.compiledCode.contracts[’:Voting’].bytecode:这就是Voting.sol编译好后的字节码。也是要部署到区块链上的代码。
: p4 l6 |0 F; x5 S9 Y  E- d5 X
9 N5 R( k! _' o5 y$ L: x    2.compiledCode.contracts[’:Voting’].interface:这是一个合约的接口或者说模板(叫做abi定义),它告诉了用户在这个合约里有哪些方法。在未来无论何时你想要跟任意一个合约进行交互,你都会需要这个abi定义。你可以在这里看到ABI的更多内容。) z9 N1 I5 V9 d: E
9 t+ g9 J3 z+ ]
    教程参考汇智网的DAPP开发入门教程,如果大家等不及博客更新,也可以直接访问这个以太坊教程。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

dancing520 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    1