Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
本以太坊教程主要是介绍:搭建一个开发环境、编写编译一个智能合约。
' P. c& i! Z! g$ l2 D. V& L* X! p' m) x0 N) ^2 ~2 k1 W
    以太坊是什么
" d9 k( L; O6 N0 a8 b- ]6 u' G, i* i1 u6 D* l7 l* x" g# r5 \
    以太坊(Ethereum)是一个开源的有智能合约功能的公共区块链平台。通过其专用加密货币以太币(Ether)提供去中心化的虚拟机(“以太虚拟机”EthereumVirtualMachine)来处理点对点合约。) M0 [* h4 T0 P; [5 O
) `3 k. T7 A' ]3 l" M
    以太坊的概念首次在2013至2014年间由程序员VitalikButerin,受比特币启发后提出,大意为“下一代加密货币与去中心化应用平台”,在2014年通过ICO众筹得以开始发展。目前以太币是市值第二高的加密货币,仅次于比特币。/ b; h- o4 x& J. j0 z& f

" i" f) o% `* u" R+ b" G    以太坊区块链是什么?! {2 l. q. [/ C4 i/ R/ S. S4 j7 C  k
% z+ S* {& z9 V! M
    以太坊区块链有2个主要组件:
8 X; Y# }* _4 |; x9 B. S2 Y; c
    数据存储:网络中每笔交易都存储在区块链上。当你部署合约时,就是一笔交易。当你执行合约功能时,也是另一笔交易。所有的这些交易都是公开的,每个人都可以看到并进行验证。这个数据永远也无法篡改。为了确保网络中的所有节点都有着同一份数据拷贝,并且没有向区块链中写入任何的无效数据,以太坊使用一个叫做工作量证明的算法来保证网络安全。! q2 T* G6 ?. A; [
) _+ s, C" ^* o4 N0 c2 R
    代码:就数据的层面而言,区块链就是存储交易。在以太坊的世界里,你可以通过一个叫Solidity的语言编写逻辑/应用代码(也就是智能合约)。然后用solidity编译器将代码编译为以太坊字节码,并将字节码部署到区块链上(也有一些其他的语言可以写合约,不过solidity是到目前为止用得最多也是相对更容易的选择)。所以,以太坊不仅仅会存储交易数据,它还会存储和执行智能合约代码。* x* s! R7 l+ n+ q/ [0 R

: c& {; e  X, J' P    可以简单的理解以太坊区块链的作用就是存储数据和代码,并在EVM(EthereumVirtualMachine,以太坊虚拟机)中执行代码。& b0 u8 d) v' _

4 F6 T. ~1 c$ r5 B1 s3 a" n. |! }* |    要准备的基础知识
# i' Z$ X# V3 t8 @4 g  E- P1 V  h" o% [: w4 }
    为了进行以太坊开发,你应该对以下语言/技术有基本了解:* A) f8 z7 I+ c- _5 R

1 ^# q* N" m# n    熟悉某种面向对象语言(如Python,Java,go); `4 Q. u. H* a* I

9 F/ z! i) H  T    HTML/CSS/Javascript5 k+ `: F3 @1 x' Z; E
& ^' f% Q* O. o/ S
    基本的命令行交互如Linuxshell命令
% \+ @) {2 C" [; ^- R8 R
( R8 `, b- ^  r; _" D0 J( v( b/ l" D    理解数据库的基本概念4 M6 C/ _1 U8 A5 j% p
. }* y* `2 h% ^( E, v
    为了构建以太坊去中心化应用即Dapp(Decentralizedapplication),以太坊有一个非常方便的JavaScript库即web3.js,你也可以在一些js框架中直接引入该库构建应用,比如react,angular,vue等。& z9 |" l& ?9 U' z( X

( w+ `, u3 Q8 e# `! m; m    示例:一个以太坊投票应用7 G5 e# L( O5 O+ {2 k# D

& L! G# h! e( d/ V$ {    以太坊教程示例中,我们将会构建一个简单的去中心化投票应用。所谓去中心化应用,就是一个不只存在于某一中心化服务器上的应用。在网络中成百上千的电脑上,会运行着非常多的应用副本,这使得它几乎不可能出现宕机的情况。你将会构建一个投票应用,在这个应用中,你可以初始化参与选举的候选者,并对候选者投票,而这些投票将会被记录在区块链上。你将会经历编写投票合约,部署到区块链并与之交互的整个过程。你将会了解什么是一个合约,将合约部署到区块链上并与之交互意味着什么。
% F2 M( Y0 k& r9 v# M
4 w! i  i. d# L    本质上,区块链就像是一个分布式数据库,这个数据库维护了一个不断增长的记录链表。如果熟悉关系型数据库,你应该知道一张表里有很多行的数据。现在,对数据进行批(batch)量处理(比如每批100行),并将每个处理的批次相连。就可以形成一个区块链了!在区块链里,每个批次的数据就叫一个块(block),块里的每一行就叫一笔交易(transaction)。& x8 ?7 K: m# Y8 Y- a
- L4 d  k5 p) P. d1 k! C
    现在,你对以太坊已经有了基本了解,我们可以开始构建投票的dapp了。这将会加强你对以太坊的认识,并且初略了解以太坊的功能。
0 J# t8 S5 H' N! Q
. {( x, h/ _- ~, X    以太坊开发环境搭建
; n/ y, I# @/ G0 X1 Y3 {& ^6 H3 ]! J
    Linux6 H- K  W1 H2 ^# ^4 w( X
; B. ]. ?, Q% K* `+ k
    示例是Ubuntu16.04下的学习环境搭建,你只需要成功安装了nodejs和npm,就可以继续项目的下一步了。2 u1 O" ~9 e) S# u
6 m" L, J9 b# m0 K( ^9 h) C
    我们通过npm安装ganache和web3包来为以太坊教程提供支撑。我们也需要安装solc来编译合约。! s  d' j8 X/ m3 j* S) ?+ Q, v& z
# X# N. l& p9 V8 ?! z
    下面是安装过程:& I7 L4 n0 v1 O  v) R2 d$ Z
4 ^- \- [+ b$ k5 c% |, w9 H
    $sudoapt-getupdate6 B  j4 {4 H1 E4 @4 m% J, O

* r4 D) o- h* e/ x    $curl-sLhttps://deb.nodesource.com/setup_7.x-onodesource_setup.sh
( A5 Y: t8 ?" D* B
; j( T  Q7 b& x( l7 ~    $sudobashnodesource_setup.sh2 y) p& @! @% q7 p! l+ j

8 B8 n) E( U0 d2 k# K    $sudoapt-getinstallnodejs1 S+ F7 v. }# j
: J. [. P+ V. i
    $node--version& @  [4 V! k! a9 C
4 x$ p0 W4 ]5 b0 F' E; z
    v7.4.0
1 W7 z: K6 }! D  |2 o3 h9 G" V* x  @$ J' J
    $npm--version
# l  G/ H/ a3 ~( P0 @6 I5 h
- X4 s  `  Z0 o/ M    4.0.5! {3 I: A1 l  n/ Z, V7 }: l

) M8 k" r5 Z$ M& O, |# A    $mkdir-pethereum_voting_dapp/chapter1
7 @' `9 }: m3 \& k# E1 A2 u# ]$ [9 Q2 _; L& D, F1 b- v
    $cdethereum_voting_dapp/chapter1% ~4 H# l) I, Q
5 r" z$ x1 y2 \6 e
    $npminstallganache-cliweb3@0.20.1solc4 i4 m8 U  M# e7 E

9 D5 k8 ]! I! Q# D9 Z    $node_modules/.bin/ganache-cli4 O% m: y% t( c

7 r6 t$ q$ e3 T/ f    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到下面的输出。
7 u4 u' |" {' i+ O8 P& p. ?& a$ g9 B
    GanacheCLIv6.0.3(ganache-core:2.0.2)  o4 A+ i; R2 M' F0 v* U# b
8 t! N/ I; D6 I  K
    AvailableAccounts
; K6 u/ a3 o# W3 H
1 K7 ~, f! X+ x    ==================
. {' n2 Z, ~5 O' z% e& J1 V# x: o! E4 v; L
    (0)0x5c252a0c0475f9711b56ab160a1999729eccce971 S: w- _3 H3 V4 \

1 `3 u  F+ s  O0 w    (1)0x353d310bed379b2d1df3b727645e200997016ba3
( ^9 Z+ W, Z1 u) ~- P7 w# n8 K1 ]8 _1 q9 d8 L8 M
    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23  s5 X$ G. x% B5 {# R+ H

/ Y" C0 w/ J; V6 M& V2 x    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5
9 |; K( N0 F" i' @, m' G; x+ N9 x# |# P4 p8 d6 y+ w' m
    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798* ?( y9 g' L+ |2 [

9 w' c& X$ p" b    (5)0xda695959ff85f0581ca924e549567390a00340588 s1 E/ a3 O  Q. Q( r

/ S+ u9 i( k8 Y2 @    (6)0xd4ee63452555a87048dcfe2a039208d113323790
6 v# T' Y. @; T5 U' E; d4 I6 x/ B8 z! J2 ^; t3 I4 r8 J7 i
    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14
# M8 I( c* Z& p; F  l% S
9 J" v0 C7 H; @. y& O) `- A  ?) M    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42
& \; d1 b: o/ E8 w  |% k8 E3 p+ V$ d# }$ d& x
    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36& v2 k6 h6 B. N' y

5 A* Q8 X! ], \    PrivateKeys
7 q; y9 a3 g' V* k( b9 |# o- o% Y. {6 G" D. P$ J0 x
    ==================
: T; `5 H' t1 _$ ?
4 V  w% r$ ]! V' o' Y7 s; H, w: W    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b
! Q( d$ C, `7 K. t* k8 n& ^9 {5 D) W5 p5 w1 ]0 @
    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603  D) E- x0 a1 w% W* X
7 n" U+ V  O" [9 P5 n/ M$ d
    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99! v9 ?% e  y% q" m
4 y9 ?; B% Y* X2 n  Z! n4 A
    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f354309 Z  o; Y/ G  S( s+ ?

2 J. N7 z2 _9 ]0 s- R% D" I    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8
; a0 m7 S) W; f6 E: b. ~. F; o& _' n7 J" E+ h1 q: Q
    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc
4 L' k$ |# p" w$ M
, S% X' J& P# `" k: P/ l1 u" g    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a99 M; [+ t% ^1 A  X$ U; H

! o5 w3 E  ^% D1 O$ o: ?# D    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d0 l+ S! ^! P( I

1 d, k) d2 k7 w! ]) B$ x    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
1 q; G* M* x6 q- J" S/ }/ {' [# I9 |6 Q9 o
    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0' F" Q" f- k5 Y- B2 @

. `2 j/ n+ v0 w$ n0 o* h* M    HDWallet% I. X7 x% r+ ~/ E; F% o$ u1 b# Q

0 k- Y  t# ~" S9 D, u  h    ==================1 Y& }' F/ N$ d4 a( X

0 ~& }; |3 T. [! b, Z2 }    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella7 Y/ P; r0 K: H" m: `
% v3 s5 A! C) F* Y% B; f" f
    BaseHDPath:m/44'/60'/0'/0/{account_index}% Q# d9 J7 E9 A) m

8 w) m2 }- A  u6 D    Listeningonlocalhost:85452 F$ g$ Q' r5 q  a. Z, O. R. o

# g4 H  v2 N7 ~8 u' r    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。
) a: `7 h7 q* \+ M5 u6 ^! Y6 O
8 [0 _8 V6 U7 p. X' x9 B" f; ?    MacOS6 d$ P8 \8 }& ]) f( e3 f; l. T! J8 {

. H4 I, e& B0 c6 \( ?3 m# l    如果你还没有安装homebrew,请按照https://brew.sh/的指示安装homebrew。homebrew是一个包管理器,它可以帮助我们安装开发所需的所有其他软件。按照下面的指示安装所有其他所需的包。5 ^' b" w% Y* R4 H" F  x

( u+ Y) ^: [0 Z0 X8 X/ Q7 n" g6 `" [    $brewupdate8 F0 n/ T  }3 [6 a. S

! z% O  l7 ^) h    $brewinstallnodejs' f! d/ X" c, [6 ]

  g7 C# P  @% r5 a) X4 W, d  I    $node--version" w- v- l8 \, t8 \( _
5 R# c! h$ s" j  g: }9 Y
    v7.10.0) Q, z2 `5 i- z# n% \1 S
' g$ x( b$ f1 k+ z9 m8 M# H
    $npm--version
( v) e( ?+ n( Q1 _7 p" H7 |
! q! l' v( \4 A; s+ D# f; G! e    4.2.0) G% j3 I5 v& t8 d
4 n2 m. R8 a0 ]1 ?- X, H
    $mkdir-pethereum_voting_dapp/chapter1
1 `( i  x% D/ W6 N4 i- E& b" }7 Y' b* M& e; b0 L, a) I
    $cdethereum_voting_dapp/chapter1
; x$ A6 }. c( L0 A* ^% y- P! c4 h2 h3 I( _5 x
    $npminstallganache-cliweb3@0.20.1solc; y( g) e7 y; K6 }& _8 w
7 E2 k" }0 r0 Z/ f5 w
    $node_modules/.bin/ganache-cli
4 A3 ~1 O. v' k) q/ e: X
: [/ R$ C* K( d. M5 U; n& [    我们通过npm安装ganache和web3包。我们也需要安装solc来编译合约。; x% U( K! U4 V

1 y% P' V1 ^5 U0 w7 ^9 t    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到右图所示的输出。
" D9 b( _4 C" @$ w
4 F/ x) p9 a4 r: I- x! ~    GanacheCLIv6.0.3(ganache-core:2.0.2)* w8 _5 ^1 A; y3 l$ M) ]0 n
7 w+ P/ j6 Y+ N8 c! F* M
    AvailableAccounts7 l  K4 o" g2 {/ w' ]
( u- ?( u5 G/ v$ q; u/ l! [
    ==================
0 I& j/ U) R# p2 b+ W5 V
* [3 g- M9 `: j) N5 d    (0)0x5c252a0c0475f9711b56ab160a1999729eccce975 U( h4 t# d+ ^+ G, y; v
$ M1 c% s' h* R3 `
    (1)0x353d310bed379b2d1df3b727645e200997016ba3
  p" ]9 P% u% L- @: q' h
6 P# C" E1 T0 m; f% c5 b5 \    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23
  j# s" E/ Z+ \5 T* ^9 y* ~& S; p! h! p- D( S& V, I$ B: m
    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5
; T( }0 ?2 e0 |  z' x9 v6 H; _& ]4 f
, f8 e2 y: v" V    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798( ~) K9 L) G3 b! d; E1 h
9 h. n* L; Q. l
    (5)0xda695959ff85f0581ca924e549567390a0034058! M) k# I$ X, p" ]4 G7 N
- b  B; X! g0 `6 d; ?+ J8 U
    (6)0xd4ee63452555a87048dcfe2a039208d113323790
8 G: Y' L% u" w) p- V% f
2 A& ]* O  H9 c4 t; J    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14
! ~: m: \8 n+ r( K/ e/ p/ X
; |! X; q: J. L8 g* W( H# K    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42/ T# c9 ^" l" A; L) B; d; R; Z5 H
% {* m+ y. A' H
    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36+ d" ?; F, a, ?2 K- \( H: A
7 J2 B* {/ f! ~2 F) C
    PrivateKeys
8 D' F( }: M+ Q( w4 b/ f) B& G& E, R& ?  s' o- Q
    ==================" G& b2 ]- k- r( P

4 ~9 b! B2 q( j$ Y    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b% o# s7 `+ T7 U" S) r- ~

: I& n* y1 x% Y$ l6 R. K' j- _    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603
5 f& P! T$ s2 d# X" F$ q- N; L# _0 _
1 ~2 t5 {& \. M( b* C0 K5 F    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99
. n) Q% m/ U$ i3 {
/ V: {$ d, v' h3 T    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430
0 P. ?6 ]: l6 V/ w4 R0 m
. ?6 \; Z4 J$ D/ k    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8
: s' T6 L% N4 c  V2 F( V! O2 S1 N- `4 v: H3 P; p
    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc5 j. K. X: y/ X) L( {) t, F

6 z4 a& X- Y% l; Y    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a91 c: D- f: X2 b( ^" d6 k
# T! b- S' t1 ~. U4 v# ]
    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d
6 S, z, H( C0 {0 N. Q3 R" ]4 }. K
9 `  N) Q. r- O( U    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a' v4 C% b8 n$ S/ C
# G: L6 C0 j! P% U& g, T
    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0
% Q1 A1 L: Z. ?6 `3 R, O" P4 `: Y  U) s/ [, V1 r- x/ T* z
    HDWallet+ _* K5 V; M" ~7 c3 |7 p
; X+ l. p  Y1 T, V5 o- r- k
    ==================# r+ L" c+ @  h6 z1 U
1 |2 t6 Q3 q/ E! a% R' w
    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella
; j1 Y2 u1 c6 S" r% b6 H: _0 {3 Z* ~8 c" ?# T  x( Z  j
    BaseHDPath:m/44'/60'/0'/0/{account_index}
2 q. s8 g0 x8 H4 n% f" \* \8 V1 ?1 r* `! B1 a4 W
    Listeningonlocalhost:8545
6 B1 J( v  J! `0 X
/ W, t9 X$ `/ F3 ?4 \    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是以太坊账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。
; i1 I5 ]0 P' N% E9 A& V% t+ y
( ]6 D# |% {7 G! Y1 D9 S+ `/ F* `    Windows9 f9 I9 ^5 J0 w4 r4 `
: `" h  M! b6 Z" F$ L
    安装VisualStudioCommunityEdition。如果你选择定制安装,那么至少应该安装VisualC++(目前的版本是VS2017)
- s" ?" N# x. r! D5 h" S2 F" Q( h. M& j; J8 {& Y
    安装WindowsSDKforWindows
- q" }1 P. `3 O5 M& ^5 G5 u5 Q
  z! H/ l  F' G3 z1 S& Z9 A    安装Python2.7如果你还没有安装的话,并且确保将它加入到环境变量PATH( `( ^( ?  K7 |' c# |! N
1 I3 w; R: R0 D; W- m& E" I
    安装git如果你还没有安装并加入到PATH
% G. u, ~8 M7 v. A
5 H1 _9 U" P4 S& d9 W& a' k    安装OpenSSL。确保选择了正确的安装包,并且只安装完整版(而不是轻装版)。你必须将OpenSSL安装到推荐安装的位置–不要改变安装路径
5 ]' c3 Y$ M; b# T5 u0 a/ t8 R  s: G9 ~. v" t+ a4 S
    下载和安装nodev8.1.2。不推荐使用版本v6.11.0搭配VS2017
/ N" H, B. m2 O7 }( r8 N* W6 X  N* T+ Q$ M; `- n
    执行命令npminstallganache-cliweb3@0.20.1solc9 i/ G5 h& |2 t: y; Z* T

7 }* E8 u& U+ o: g7 s6 D    SolidityContracts+ I- ?, s1 Z: m
; O, e: k% u  G$ x! }& f
    现在已经安装好ganache并运行,我们将会开始编写第一个以太坊智能合约。+ E5 `. ]" O( C) p7 b+ f

; Z. Q- S  S1 X% T% Q  A    我们会使用solidity编程语言来编写合约。如果你熟悉面向对象编程,学习用solidity写合约应该非常简单。我们会写一个叫做Voting的合约(可以把合约看成是面对对象编程语言的一个类),这个合约有以下内容:1 E8 E# r2 {2 q

& H  b& A* f/ }' ^    一个构造函数,用来初始化一些候选者。
6 m& P" M& A* j5 l: H( q& G1 _
    一个用来投票的方法(对投票数加1)
4 E* _: A$ r2 ~( S# l; b" H* w# n1 Z
0 x4 y+ I' h9 Z# a/ b) p    一个返回候选者所获得的总票数的方法5 ^- @- y, [" I8 T+ J

, P* j) ?  {7 P) }% A5 T/ G; o' ]    当你把合约部署到区块链的时候,就会调用构造函数,并只调用一次。与web世界里每次部署代码都会覆盖旧代码不同,在区块链上部署的合约是不可改变的,也就是说,如果你更新合约并再次部署,旧的合约仍然会在区块链上存在,并且数据仍在。新的部署将会创建合约的一个新的实例。+ W- h7 g  s/ [% J

0 ^$ i) }; J$ q    pragmasolidity^0.4.18;+ V1 u/ i2 U3 H! i
, B4 f5 W! c9 f8 u0 g4 R. U1 @
    contractVoting{1 |! M2 C% N# s! j

9 ]9 c! g* s# `% `    mapping(bytes32=>uint8)publicvotesReceived;1 m8 ~5 m7 U+ b0 |

# m3 m7 _2 L: J* O- b    bytes32[]publiccandidateList;% H  F- P% J$ j! a3 s
4 k( |& n3 X) w& q- n( \* O
    functionVoting(bytes32[]candidateNames)public{* u! m( H* \( B4 T
$ G4 Q& K) ~7 G2 v9 E) |  o
    candidateList=candidateNames;
( w. U: d" E) }6 m/ @
4 ?/ z' v( |+ W' `2 ]& H0 w# y    }" v2 O' A2 P; }: T% y* [4 _

5 \8 G5 ^, |! v, R9 ]: _4 {, _* _+ ~    functiontotalVotesFor(bytes32candidate)viewpublicreturns(uint8){
% F* }! h6 f& q$ l9 P* X1 g$ |. c1 T# h9 I% h
    require(validCandidate(candidate));- E( }  E; Z6 S. N5 f/ H! h- d

8 e9 R4 L9 `4 {. g1 C# @    returnvotesReceived[candidate];+ h8 Y; X. M/ h. ?8 B
+ H+ F. ]2 p- C
    }- |6 c( s: N1 j
4 e8 Q6 _4 P. q6 }+ j
    functionvoteForCandidate(bytes32candidate)public{6 @, t1 E: M; H5 |# q# C' n

; x) x2 N8 E0 L( I3 z0 g2 _5 r    require(validCandidate(candidate));
1 Y5 |/ k+ O2 _+ j  D2 X: N' c) n2 Y/ e, F9 H0 X8 d
    votesReceived[candidate]+=1;
' M  r2 U' [4 d- c; J( p, q; U. c- [1 v! Y/ w2 r/ v7 s3 d
    }7 ~5 L: H1 ]- Z  V3 G5 C5 X% u
: |$ O/ g' E$ ^& z$ e( W* }
    functionvalidCandidate(bytes32candidate)viewpublicreturns(bool){
( J, \8 F9 y/ s7 B) I( |1 S! r; G/ x, \9 k, u. L  |  ^5 l
    for(uinti=0;i( h( A) p; R6 s

, V7 H% {0 g0 M5 M+ a5 G9 r! v- r    将右侧代码拷贝到一个叫做Voting.sol的文件中,并保存到chapter1目录下面。
  T3 T8 X8 x- h4 I
8 U. C3 H7 R# ~8 E! k    代码和解释/ ?) I- H" \, V# r* J$ z

# ~' C+ h+ G+ w* V+ o/ i* l    Line1.我们必须指定代码将会哪个版本的编译器进行编译
% E9 y" O" V  Y1 Z' S
, f! ~; w7 l0 B+ q2 h    Line3.mapping相当于一个关联数组或者是字典,是一个键值对。mappingvotesReceived的键是候选者的名字,类型为bytes32。mapping的值是一个未赋值的整型,存储的是投票数。
4 z( S/ V( `. ~. a9 b$ d
7 M" l1 N) U+ i    Line4.在很多编程语言中,仅仅通过votesReceived.keys就可以获取所有的候选者姓名。但是,但是在solidity中没有这样的方法,所以我们必须单独管理一个候选者数组candidateList。
7 b3 F6 o7 s% C% Y# R$ y+ w! H) P$ F8 O% J/ v$ V1 \
    Line14.注意到votesReceived[key]有一个默认值0,所以你不需要将其初始化为0,直接加1即可。. U1 S: T, y0 Q, U9 E

6 @4 q- u9 `- V, o- H    你也会注意到每个函数有个可见性说明符(visibilityspecifier)(比如本例中的public)。这意味着,函数可以从合约外调用。如果你不想要其他任何人调用这个函数,你可以把它设置为私有(private)函数。如果你不指定可见性,编译器会抛出一个警告。最近solidity编译器进行了一些改进,如果用户忘记了对私有函数进行标记导致了外部可以调用私有函数,编译器会捕获这个问题。这里可以看到所有的可见性说明符。) x) F) D+ m0 O  y3 d+ z2 u9 L( M  G

- o9 ^# R0 F8 ~& H' x2 u: I4 _    你也会在一些函数上看到一个修饰符view。它通常用来告诉编译器函数是只读的(也就是说,调用该函数,区块链状态并不会更新)。所有的修饰符都可以在这里看到。
, o+ n7 W1 t% Y! _5 M
; A0 U5 b( W  |  h    编译智能合约1 o9 X! W5 [2 }" j+ K

9 b) c, V( H8 L7 f( l6 r$ _4 |& U    我们将会使用上一节安装的solc库来编译代码。如果你还记得的话,之前我们提到过web3js是一个库,它能够让你通过RPC与区块链进行交互。我们将会在node控制台里用这个库部署合约,并与区块链进行交互。' D* ?/ j/ [4 `- B% Q+ x
: n0 ?- m. @3 ^4 ?& C/ ~
    首先,在终端中运行node进入node控制台,初始化web3对象,并向区块链查询获取所有的账户。
% O) s+ [" y- e' D3 Z* f2 m% N# ~2 V. @3 _5 v  \; C
    确保与此同时ganache已经在另一个窗口中运行; @% B% \8 o4 {4 R
. ~6 `2 `$ g& W  T  E
    为了编译合约,先从Voting.sol中加载代码并绑定到一个string类型的变量,然后像下边这样对合约进行编译。6 ?+ X7 O8 H/ y6 ?
. E0 q* V" F" A9 V" {
    $node
, A/ B/ @3 f5 U8 ?- N# L, k* ^- @* Y2 k/ t: k
    Inthenodeconsole; g  X9 _" Q4 I/ b. U0 s# g' F

. V0 B) ?- j. z. M& g* E0 j    >Web3=require('web3')
6 k% V, ]4 s! p5 ], P$ W* i
$ ~* |! i% E$ `* l* A! n* j1 {    >web3=newWeb3(newWeb3.providers.HttpProvider("http://localhost:8545"));
. |5 _- ?, \1 a, T9 f
6 i& K8 t: ]& n8 ~& D4 b8 _- b3 B    >web3.eth.accounts0 J: `; b& U# t- T6 A& v" s- F

$ U7 ^# k9 H  C& J# v    ['0x5c252a0c0475f9711b56ab160a1999729eccce97'
0 u3 T- X1 F4 t8 o3 v0 d* d) F, ^$ f, i' o
    '0x353d310bed379b2d1df3b727645e200997016ba3'. q, `0 z  ?" G

' N8 d7 u4 [9 S+ X* ^3 E    '0xa3ddc09b5e49d654a43e161cae3f865261cabd23'
( Q: x; s: m, E8 J& H
9 n& G: B; i$ v) z' L. u) m    '0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5'
) }1 H4 C  Z. f3 g( H' r( V9 }' T2 h" g. v: ]
    '0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798'
; d. c3 e" z: f/ }
! r+ L, s2 R( y! u. h2 R    '0xda695959ff85f0581ca924e549567390a0034058'' Z; ^% O4 d+ w

  Y, {# g6 w/ T5 h" l  p    '0xd4ee63452555a87048dcfe2a039208d113323790'% C. R# J# a& u/ f2 L2 i' C6 {6 C
0 Q# B+ x1 F0 q
    '0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14'
; T; V( L- ^4 M6 c, S- F
! z2 d0 U+ M1 ?5 z0 J* _- \2 o3 z2 f    '0xba7ec95286334e8634e89760fab8d2ec1226bf42'
$ x( N$ r# j& p/ ~9 j6 W, _) w" O' N/ s
    '0x208e02303fe29be3698732e92ca32b88d80a2d36']7 K' V5 s) ]/ B' x
8 E3 Q- q6 r4 C4 e. _. r7 [
    >code=fs.readFileSync('Voting.sol').toString()' l) |! f6 v+ \' ^, }6 ?9 W0 {

/ |% ^2 N! v1 ?8 w( R0 U    >solc=require('solc')
: U- B  B0 k# j; q. @2 `
+ @4 _6 B% U0 c' f3 }3 ]    >compiledCode=solc.compile(code)7 T: x1 Q" I7 u  n
. L( q5 N2 U+ `  Y7 @+ Y
    当你成功地编译好合约,打印compiledCode对象(直接在node控制台输入compiledCode就可以看到内容),你会注意到有两个重要的字段,它们很重要,你必须要理解:% m4 a# c$ q( V" S
* z& y" A/ D9 Z3 S: @4 o; ^% e* l
    1.compiledCode.contracts[’:Voting’].bytecode:这就是Voting.sol编译好后的字节码。也是要部署到区块链上的代码。1 h4 n: q. k$ H, h

# C7 ~' L- \. f    2.compiledCode.contracts[’:Voting’].interface:这是一个合约的接口或者说模板(叫做abi定义),它告诉了用户在这个合约里有哪些方法。在未来无论何时你想要跟任意一个合约进行交互,你都会需要这个abi定义。你可以在这里看到ABI的更多内容。
& b; f; j; w) b6 t5 \) p4 k/ f
" f# |* L  Z- R0 `    教程参考汇智网的DAPP开发入门教程,如果大家等不及博客更新,也可以直接访问这个以太坊教程。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

dancing520 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    1