Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
本以太坊教程主要是介绍:搭建一个开发环境、编写编译一个智能合约。6 f4 ~- P0 ?' s2 H( \! Q& ^! Y
. r, W! W& Y4 q" P4 ~# p; u( k. @) U
    以太坊是什么  X# |! o* v6 b# N2 ?* Z% X
4 u2 W# P. V* |
    以太坊(Ethereum)是一个开源的有智能合约功能的公共区块链平台。通过其专用加密货币以太币(Ether)提供去中心化的虚拟机(“以太虚拟机”EthereumVirtualMachine)来处理点对点合约。# o" Q0 [3 f9 w2 U3 E* W
8 e# [$ f' y! A# s, W& `% W( M
    以太坊的概念首次在2013至2014年间由程序员VitalikButerin,受比特币启发后提出,大意为“下一代加密货币与去中心化应用平台”,在2014年通过ICO众筹得以开始发展。目前以太币是市值第二高的加密货币,仅次于比特币。( W7 A2 f% J. \3 _# q6 F
. o1 E  f* f2 K! i5 V4 z" D! y6 \* `
    以太坊区块链是什么?
  \  V$ z+ s! t* y* f1 x# p/ Q3 h: _2 R# d
    以太坊区块链有2个主要组件:7 |( q% W; \. Y4 V4 ]4 x
* _/ S  |* `: @, z; t, _
    数据存储:网络中每笔交易都存储在区块链上。当你部署合约时,就是一笔交易。当你执行合约功能时,也是另一笔交易。所有的这些交易都是公开的,每个人都可以看到并进行验证。这个数据永远也无法篡改。为了确保网络中的所有节点都有着同一份数据拷贝,并且没有向区块链中写入任何的无效数据,以太坊使用一个叫做工作量证明的算法来保证网络安全。# o- F" b/ w! ?0 Y
; q* B0 u: a0 I& ~4 T4 J
    代码:就数据的层面而言,区块链就是存储交易。在以太坊的世界里,你可以通过一个叫Solidity的语言编写逻辑/应用代码(也就是智能合约)。然后用solidity编译器将代码编译为以太坊字节码,并将字节码部署到区块链上(也有一些其他的语言可以写合约,不过solidity是到目前为止用得最多也是相对更容易的选择)。所以,以太坊不仅仅会存储交易数据,它还会存储和执行智能合约代码。
4 ]1 O  v" c+ u) ]) Z5 r" ~, _% Q: O) m
    可以简单的理解以太坊区块链的作用就是存储数据和代码,并在EVM(EthereumVirtualMachine,以太坊虚拟机)中执行代码。
# ]! I. x. m. z; K. [
& o5 n1 _. N% N$ K% ?0 E; v( r, `* U    要准备的基础知识
. P. I% h8 n+ n* a: H
" x) w) e: `9 O& Z3 S( a6 @    为了进行以太坊开发,你应该对以下语言/技术有基本了解:
9 m1 ]: a) S" k! ^: C% [- y" `" e8 @, V8 {& Z: \
    熟悉某种面向对象语言(如Python,Java,go)
) w: l( [# h; d- C6 Q' V$ O6 E0 K: T3 i" X- |  H
    HTML/CSS/Javascript3 i5 P: @" K: R7 V. J3 `; t3 K2 M

" P1 Y4 g2 T  X& m    基本的命令行交互如Linuxshell命令' W& n. z) d: ]) k8 i, H

) ~0 w+ m6 Z  Q  }( y    理解数据库的基本概念9 \2 j# w7 {7 r6 a" ]

9 B1 C2 `) e2 L( G( j5 ^1 y4 M# R+ A0 c    为了构建以太坊去中心化应用即Dapp(Decentralizedapplication),以太坊有一个非常方便的JavaScript库即web3.js,你也可以在一些js框架中直接引入该库构建应用,比如react,angular,vue等。7 t. G& m1 K9 @; o/ k6 u7 D* J

. C) M# o" \% k1 s2 G" _    示例:一个以太坊投票应用1 R0 e9 p  P9 U, \
" j& p4 I( h3 A1 d: C
    以太坊教程示例中,我们将会构建一个简单的去中心化投票应用。所谓去中心化应用,就是一个不只存在于某一中心化服务器上的应用。在网络中成百上千的电脑上,会运行着非常多的应用副本,这使得它几乎不可能出现宕机的情况。你将会构建一个投票应用,在这个应用中,你可以初始化参与选举的候选者,并对候选者投票,而这些投票将会被记录在区块链上。你将会经历编写投票合约,部署到区块链并与之交互的整个过程。你将会了解什么是一个合约,将合约部署到区块链上并与之交互意味着什么。
7 U% Q0 A" s' ?5 _8 G
7 U( `0 }) e8 {9 O7 l1 _% m    本质上,区块链就像是一个分布式数据库,这个数据库维护了一个不断增长的记录链表。如果熟悉关系型数据库,你应该知道一张表里有很多行的数据。现在,对数据进行批(batch)量处理(比如每批100行),并将每个处理的批次相连。就可以形成一个区块链了!在区块链里,每个批次的数据就叫一个块(block),块里的每一行就叫一笔交易(transaction)。
$ t! H; x6 M/ `7 R3 @8 _
% K) h( R% R4 `    现在,你对以太坊已经有了基本了解,我们可以开始构建投票的dapp了。这将会加强你对以太坊的认识,并且初略了解以太坊的功能。
% k# _" r5 p+ g7 T) P' S1 N  f6 n) _
    以太坊开发环境搭建' }6 L8 b! S, ]% }' \

$ F+ Y1 i, L5 U2 [& Z3 l# S    Linux# u+ J* K. X2 o. A9 o
; v8 v6 k, A( D% W
    示例是Ubuntu16.04下的学习环境搭建,你只需要成功安装了nodejs和npm,就可以继续项目的下一步了。& [( f; h5 Y2 S8 X; C$ Q
7 l5 T$ F- J( s5 n
    我们通过npm安装ganache和web3包来为以太坊教程提供支撑。我们也需要安装solc来编译合约。
) }9 I+ C' V' w9 A' J6 G' [. X
9 h5 T" Z! p1 F- B- a: y( U    下面是安装过程:
9 ^& c6 p5 r. o* H1 a- o4 w" w$ Y- ?3 d% Q3 a
    $sudoapt-getupdate
/ t- \( q& @! m  A) ]
3 S: L) O; E5 E, K7 H3 [    $curl-sLhttps://deb.nodesource.com/setup_7.x-onodesource_setup.sh1 n1 C2 v/ r7 l
# F4 n" S" S/ o& @
    $sudobashnodesource_setup.sh; {# G: H1 c% \7 Z3 t. h+ `) X5 |

: u1 H% Q9 M% j    $sudoapt-getinstallnodejs
. |; f" h1 ?2 k* p; p' `  T) v7 U5 P3 t+ H" y# ?( {& `
    $node--version' R: u8 T& w1 j5 t
& [# `3 \7 J' F
    v7.4.06 o( g* V6 F8 w
: l2 B8 C6 a2 s" W% U
    $npm--version# H5 f$ [# J1 g- K" P# m! N
8 i2 j6 s9 w/ C' Q) |" M/ N
    4.0.58 D5 H& _# m# u* q9 r: Z

. k$ O0 k) Y. A1 p. ~3 F" _    $mkdir-pethereum_voting_dapp/chapter12 V& c8 X8 o) B

* d4 v% Y/ V1 B8 Q5 _3 o* L    $cdethereum_voting_dapp/chapter1/ F0 x7 B. o& Y# v! b7 `  R& c
4 L+ I' F( n; Z/ K
    $npminstallganache-cliweb3@0.20.1solc6 g; a0 F+ Q8 K0 L

* M. Z+ A8 M: ]    $node_modules/.bin/ganache-cli
. n& X6 s3 h4 G  o: t. _! [
, F+ H8 z: f1 b' a& o: e6 [    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到下面的输出。
; b. G% E- W) f/ V- Y+ d- ^+ J. i# A1 Z7 O3 q1 p" B
    GanacheCLIv6.0.3(ganache-core:2.0.2)
. d7 K- g6 w4 g' a+ N  G. Q
( j5 k" z: H4 H1 w1 W3 r    AvailableAccounts' t/ l: H" O6 I
  f5 g$ t4 r2 o- a1 _
    ==================
1 S0 N, R8 {  d; _5 Z4 n5 U& M
& O$ F6 a0 [$ i- n- x, f& y! q    (0)0x5c252a0c0475f9711b56ab160a1999729eccce97
, |# o/ o$ R$ o/ s+ k, V. `" p# p8 V3 e4 ?2 f$ O& D& W
    (1)0x353d310bed379b2d1df3b727645e200997016ba34 i5 M+ F) n1 \: ]" L

/ K: \* [6 ]( g7 w0 ^    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23
, L+ \$ X2 \0 |  ?- @. P2 H+ l# w! [
; F8 t8 _* Q. v7 Y9 d2 n6 S5 f" f    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5! ?" S3 I/ ]5 L" h3 q4 |

. U5 C" v& `! Q) a    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd27987 l1 W" f- t+ G' d7 v

% g# v3 z. r2 A/ f    (5)0xda695959ff85f0581ca924e549567390a0034058
* O/ W& E/ y) }; w" b( v& Y! R" j" L6 Y8 d5 c5 V
    (6)0xd4ee63452555a87048dcfe2a039208d113323790
- j5 H- s, p' y% N" I- c) C6 q  H0 O
    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14
. ]0 ^6 }6 P- m6 p: ?1 N. H0 C  X; w+ y, q7 J0 l
    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42
7 b# ]0 R$ F; r) U1 t8 V9 H2 k
! F7 D2 n- Q) p+ x+ D$ G5 ~3 h( C; W- H    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36: Q5 @1 h# B" W* r" k1 H4 v+ T

' t. b$ K, v3 v$ ^, P7 x- g& w1 X6 R    PrivateKeys
2 ^, D* \; q, W$ ^
$ Z0 ~+ r# a9 ?. C' Y    ==================" b$ b+ m/ z+ ]% Z! X( V
# b. `( Z: B. c
    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b9 L; H: G# V  l7 I
2 h4 m/ X  Y( z% a) d
    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603
! Z: s, X1 M, o  v" d/ L1 u) ^
) X/ ^' @6 i: W0 u    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99
# @# Q# G* I$ o8 D
" S& Q4 E, S0 h  R$ g    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f354306 a1 r% }+ ^4 o# d( ]( v
, u9 T9 ?! x( n
    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8
9 N+ U' q# u4 p# Y' @! d
6 K6 l& s2 d# ?; D0 p3 m: `    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc
" E9 T7 y9 _( d4 L5 p- @/ E9 l9 ?0 L
    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9% H/ W7 ~0 V( |* @5 o" d

; ~% F+ V) r! Z4 @9 S# U" a    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d
% p: W( ]' X) t" d. Z: i' o3 k# N
. n7 x# H. h2 C    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a1 i; Y6 W. L7 i/ Y3 Y' N( B

* S1 d$ `" ?* p- ~. P$ n    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0
+ z6 u) K9 U; e9 j; Y% X; V8 `8 z" k/ T; `) t5 F% V9 s. x
    HDWallet
& C. b3 S) P! O7 ~( A: w2 f5 @& B" `" a2 h) H; t
    ==================
4 K7 y& R: t/ z' C& R, l! F
2 H7 K9 T0 v2 u; U% ~) W+ p    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella
0 a: D6 P. m* q, ~% Y& D& Q3 o, n% Z# F5 f
    BaseHDPath:m/44'/60'/0'/0/{account_index}' j' @3 y: i) S6 D. G

; q  A  D' y: |3 S8 i* S    Listeningonlocalhost:85450 n1 e+ P* v: E

0 B( }0 Y* E4 l: A    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。- i& j3 N" l  L/ G( U9 V' R7 f( t

% V' A8 |3 }4 _) e2 I    MacOS3 B! a5 O2 U, x0 H6 {; U
: @# Z2 C: b) _
    如果你还没有安装homebrew,请按照https://brew.sh/的指示安装homebrew。homebrew是一个包管理器,它可以帮助我们安装开发所需的所有其他软件。按照下面的指示安装所有其他所需的包。
$ V4 e/ e- v) [6 t$ k$ P& D
# g9 T& }; `. Z: i! `    $brewupdate  i8 e. O! e  @) `$ h5 u2 z

; ?- P( g: ?$ n# n. p8 z6 q    $brewinstallnodejs
. e& [+ q/ Z2 k& M4 a/ |3 E4 X9 m( P& {7 O/ G& e
    $node--version0 N( b- Z& t5 x1 j' \; `# Q
: c0 H4 S' ~# l! b
    v7.10.0
/ [9 q8 o# Y! H1 {. T3 M4 K4 {$ H5 ^) W) d
    $npm--version
, }& e% b0 w6 r
3 B  b# s" E, c+ C& x    4.2.0- q* x9 n; Y/ Z! P- X& {

8 U( ]: Y) g7 K) ~7 k    $mkdir-pethereum_voting_dapp/chapter10 M# [6 j4 z: N! y
$ ]. V% A, g& Z: N6 E# J3 r) D
    $cdethereum_voting_dapp/chapter16 i. P2 u2 Z8 T% l6 l

$ T/ E" l7 F( I' a- j% F6 c2 R* M, o    $npminstallganache-cliweb3@0.20.1solc/ ~! S3 A- o: }" B4 q
5 M/ N2 p4 R, s4 L, w6 b
    $node_modules/.bin/ganache-cli; p( X/ }5 ]6 Z0 @2 ~) Z) ^

5 Z$ f9 O8 c1 W7 U( S    我们通过npm安装ganache和web3包。我们也需要安装solc来编译合约。
- p1 m/ O+ t6 {' Y5 o/ C+ `0 H& e7 x4 r4 L, f
    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到右图所示的输出。
! }. X) Y/ X! m) J" i2 g5 X; z$ j2 u  r! W1 o
    GanacheCLIv6.0.3(ganache-core:2.0.2)' M6 t) F6 }) \' w

! F; w2 D( i! U/ s+ J; P' K    AvailableAccounts
5 v0 A0 I3 Y) M5 _( C- {/ M4 G& f5 b' y+ i. P  Z9 R  C2 u1 R
    ==================+ h/ `! ~: F& J; @; N/ e

0 M1 R# p0 H! H    (0)0x5c252a0c0475f9711b56ab160a1999729eccce97
% B1 ?7 i2 w3 M2 p/ @9 X9 [2 M7 q" E
    (1)0x353d310bed379b2d1df3b727645e200997016ba3& v6 }! V0 K* Q& V: O6 }
% H- u; D4 s9 w; e& [0 l+ g
    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23
# {/ ?, s2 X4 i& X
5 T$ I1 S2 c$ E% _& m9 D& Q    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5
$ D1 f2 B+ E. j/ T" z7 o6 P/ y  [) s
    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798
4 k/ `, p& b+ z
% ^5 c3 x1 O2 O+ f    (5)0xda695959ff85f0581ca924e549567390a00340582 b6 b, ^5 _3 A" e2 U+ C

) r2 e: O* }, Z' S7 M    (6)0xd4ee63452555a87048dcfe2a039208d113323790
; h; P0 ]) ?6 M' \' `0 }
9 v5 u$ g0 Y. k% F+ b    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14* T  n0 \: C% z5 d0 F' m* r5 L3 ~0 K) J

. o8 t5 x8 V7 V8 [  @& ?# b9 C    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42
( ^2 B3 B2 `7 t% V* r: L9 a* W$ H- Z! f8 H7 }/ Q
    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36: E- v6 L1 \) P$ Y4 C7 U
3 n: f9 J% ^4 s2 z
    PrivateKeys$ }* m, O1 R3 `6 o% Z" |5 s6 J
( v4 B6 H. P5 F
    ==================" T  Q! Z: U, S* M4 Z
8 R. U2 y- d7 q! }3 u( N
    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b! b. L" u* B" s0 @2 m

# W" t( V9 O5 ~9 z& l& \9 v; L/ m    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603
  o& w" B& R4 i: Q2 O* ^" O- l" Y- r* `. z, J( v
    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99
/ ?# A/ U: v- r' b: v+ `
* X+ P' ]+ p$ a( n/ f& ?    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f354305 W; Z1 p& c/ M3 B( Q

4 |( N) R4 o6 o* ?9 y: X( ?. v  M    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8
9 i. w1 J; F8 y4 a4 U; [5 g% P  Y! Q- z; [, f
    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc
) _- K1 x6 }' ]6 a% u5 V0 U8 E+ W9 o+ D
    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9
4 N9 I2 a3 Z0 _! y0 q
8 [3 g  p9 w2 b/ a  M& Y% d2 f" L    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d
* I2 _( C- |; a+ s& b' X$ S+ l' g/ y: i+ N& z& S2 ]
    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a% _- E% I0 r' i! v. T/ H

% S$ B6 g' [; H/ R" m    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0
& d7 M- ?/ }' J6 F" T6 N5 D' d5 d/ k+ p
    HDWallet- M% `1 k4 x: w" k
# }, V/ X  g6 O7 S6 A7 M
    ==================1 \9 p# y! M$ P

/ {% A0 P$ R6 y7 D  X9 E2 G, g- }    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella
5 y3 y2 o* f& j! {1 j2 Y# v) ]* }1 l* J# ]. h& x
    BaseHDPath:m/44'/60'/0'/0/{account_index}
7 ]% Y" o- x) q3 T% D7 [% d% Y' |- Z; d: l1 f4 C5 x
    Listeningonlocalhost:8545
2 n6 u  x* T: z
+ \+ V7 W! C# ?    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是以太坊账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。
  ?4 s: r1 T; I- ~% m
3 J; }- _' _, r" [9 n& C3 `    Windows2 Z* e- o% C% o& h9 T

- S9 v& F4 i) U1 `4 ~    安装VisualStudioCommunityEdition。如果你选择定制安装,那么至少应该安装VisualC++(目前的版本是VS2017)" p* {1 C& {, _2 s9 G
0 z3 f6 a3 A5 V1 x
    安装WindowsSDKforWindows
  }/ t7 I  l' s, Z0 Y4 f* e8 F/ [* i' ~
    安装Python2.7如果你还没有安装的话,并且确保将它加入到环境变量PATH
% q8 ~! F- `3 Z' X- [) Z
: Q( J% h( L' [4 E5 H- P6 E    安装git如果你还没有安装并加入到PATH
/ T0 j4 a1 ^8 w. m' w) g9 X' e$ _3 e
+ k4 K3 D- b3 h7 r, d3 e4 ?$ z    安装OpenSSL。确保选择了正确的安装包,并且只安装完整版(而不是轻装版)。你必须将OpenSSL安装到推荐安装的位置–不要改变安装路径
4 v% J' D) ^/ H
$ E6 f9 X3 s0 t    下载和安装nodev8.1.2。不推荐使用版本v6.11.0搭配VS2017
. [! i+ V$ T# I. _' r  ]4 Y' v  I1 T; Y- }  Y; H
    执行命令npminstallganache-cliweb3@0.20.1solc/ g& A$ @5 R4 a9 `, I6 P8 i- w
$ ?; m3 F9 r$ L5 @  _
    SolidityContracts1 r" ^  t: H9 ~$ J, q6 x/ |

, I. ^- a9 l1 W) n% X+ _    现在已经安装好ganache并运行,我们将会开始编写第一个以太坊智能合约。' A3 I7 s  [) y( b" x
1 t, [" P5 b" ]1 Q8 b7 D. }7 @6 @3 O
    我们会使用solidity编程语言来编写合约。如果你熟悉面向对象编程,学习用solidity写合约应该非常简单。我们会写一个叫做Voting的合约(可以把合约看成是面对对象编程语言的一个类),这个合约有以下内容:
5 j4 g9 K4 o5 {/ U7 B8 H2 T; h1 e. r; g3 W* i
    一个构造函数,用来初始化一些候选者。
# O; M6 @! c; p$ K2 d- F0 ]6 f. ?$ Z7 v5 X5 `$ B; ~
    一个用来投票的方法(对投票数加1)* k9 @% s7 Y3 p. c! Q1 \0 ^
2 u1 Y, v% L! ^5 J& B
    一个返回候选者所获得的总票数的方法
) [8 e# G3 d: r
( \3 b0 S) B) U& A9 n    当你把合约部署到区块链的时候,就会调用构造函数,并只调用一次。与web世界里每次部署代码都会覆盖旧代码不同,在区块链上部署的合约是不可改变的,也就是说,如果你更新合约并再次部署,旧的合约仍然会在区块链上存在,并且数据仍在。新的部署将会创建合约的一个新的实例。* l, R! d; s+ s; F% G

+ d8 @9 h1 Y4 m% ^: h    pragmasolidity^0.4.18;* \3 P! s) Z# W1 y. g) J

  x: g2 ?+ `( x  N/ S    contractVoting{
; S# e. z5 }3 ]8 h& F5 G) ]4 |/ p) m1 \
    mapping(bytes32=>uint8)publicvotesReceived;) ]- G% U  x8 B& }
9 ?/ U0 A2 M5 [' [: b
    bytes32[]publiccandidateList;
9 A  ]  W4 P0 P* n  M/ S" M; `. X) _7 V9 D5 ^7 R: @) b
    functionVoting(bytes32[]candidateNames)public{% s& Q) ?. @; o$ f2 }
8 ?" O7 b2 [- T5 q$ E' n  J
    candidateList=candidateNames;" W2 K9 x9 n. m2 d7 a" f
( B  j2 E1 p+ f2 U0 F5 n
    }; M: d! o5 ?  \5 G2 g4 f4 ^9 N9 s
$ L  y# s/ ~5 E2 f, u/ I
    functiontotalVotesFor(bytes32candidate)viewpublicreturns(uint8){
1 s# O. [1 |3 n3 Q* E0 D# j- O" D# K$ R: z5 s: S& \% C; s, y
    require(validCandidate(candidate));
5 j. f" C$ O$ q3 [& z& s. X4 F; E7 n2 M/ K" N, H6 g* Y/ W
    returnvotesReceived[candidate];' O" |$ f3 M* x* f, V
, X  g1 q. y6 e; ~7 N: K& ]0 g
    }
. h6 G/ p- o2 [  O: G6 d" A0 z# b. ^( [" c1 T, v3 X
    functionvoteForCandidate(bytes32candidate)public{: k" C' t7 m+ O9 a/ m3 Y& h3 m

3 J+ {3 b; c- E# z+ {/ G* ^    require(validCandidate(candidate));
$ j" W1 ]. G% S5 M
) i0 @' w! B9 N6 E5 P6 n    votesReceived[candidate]+=1;4 V6 O; L. N: P0 I& {
; g* s5 Q5 p2 h9 e4 A
    }
8 {( W" M5 z8 ~  u, B
, S7 |9 ^9 P2 `- e( N% S+ ?- z    functionvalidCandidate(bytes32candidate)viewpublicreturns(bool){& s( `$ y5 t' k: l& ~9 g

) N4 l( }5 g( t5 X) s( i' `, L    for(uinti=0;i
2 W- }) \$ z. ?- A  K% ^6 [2 ]* f5 |2 _4 ~* v
    将右侧代码拷贝到一个叫做Voting.sol的文件中,并保存到chapter1目录下面。: u& K# u/ V0 L: p9 G  K: F8 Z) ]3 C
( W, b' B. v4 T6 _/ R" Y' h( J
    代码和解释
0 J- K0 T# n/ V0 o6 e
/ N4 B% R# f- }: i    Line1.我们必须指定代码将会哪个版本的编译器进行编译
& q. O# q9 T: h8 V9 K* K' g& _9 D/ Y! w" u  n( F5 i
    Line3.mapping相当于一个关联数组或者是字典,是一个键值对。mappingvotesReceived的键是候选者的名字,类型为bytes32。mapping的值是一个未赋值的整型,存储的是投票数。* D3 j7 Q' J" o% ]: w3 ?

* q+ S$ P6 b  g5 ?+ f    Line4.在很多编程语言中,仅仅通过votesReceived.keys就可以获取所有的候选者姓名。但是,但是在solidity中没有这样的方法,所以我们必须单独管理一个候选者数组candidateList。9 R; G3 F( r' |; z) r( S3 T

. l9 u% X8 z9 h9 S    Line14.注意到votesReceived[key]有一个默认值0,所以你不需要将其初始化为0,直接加1即可。% j% q; L) l% T

. ]" N7 H! j2 y    你也会注意到每个函数有个可见性说明符(visibilityspecifier)(比如本例中的public)。这意味着,函数可以从合约外调用。如果你不想要其他任何人调用这个函数,你可以把它设置为私有(private)函数。如果你不指定可见性,编译器会抛出一个警告。最近solidity编译器进行了一些改进,如果用户忘记了对私有函数进行标记导致了外部可以调用私有函数,编译器会捕获这个问题。这里可以看到所有的可见性说明符。
8 W, S/ Q+ k6 W( E
6 G' P3 e3 J( j, ~' l    你也会在一些函数上看到一个修饰符view。它通常用来告诉编译器函数是只读的(也就是说,调用该函数,区块链状态并不会更新)。所有的修饰符都可以在这里看到。8 q3 P8 G/ ?4 G' E9 R2 ]
" b2 Q$ M( h- B) p
    编译智能合约
5 {7 x9 T: w6 c& s) B
0 n) W5 H  p. h; @    我们将会使用上一节安装的solc库来编译代码。如果你还记得的话,之前我们提到过web3js是一个库,它能够让你通过RPC与区块链进行交互。我们将会在node控制台里用这个库部署合约,并与区块链进行交互。
! s( ]! n# F9 P  f
+ L* a  x% C" I- y; a! ?! a0 {    首先,在终端中运行node进入node控制台,初始化web3对象,并向区块链查询获取所有的账户。
9 m1 s& R4 m5 P' T' ?: V
' P5 w% |# Z' l8 T) f    确保与此同时ganache已经在另一个窗口中运行. R0 G7 ?+ Z/ Z

/ i, d2 O( Y. y/ Z# U6 S' B5 @0 {    为了编译合约,先从Voting.sol中加载代码并绑定到一个string类型的变量,然后像下边这样对合约进行编译。
: j7 B  m! ]/ z* F) u5 t# I/ I' A3 B& [; j2 V1 p8 E6 W. A
    $node
2 b; H  {1 y! x8 E0 H
7 i; Y1 o; J+ M) R3 k% X2 o    Inthenodeconsole
9 B/ o' g" q! R/ L# q- t3 T& @
; o) v; Q9 m+ t' I/ G3 c, b    >Web3=require('web3')
% P& o# P+ u' Y, [" S
- C, M/ j6 g+ O* F$ v  q+ ^    >web3=newWeb3(newWeb3.providers.HttpProvider("http://localhost:8545"));% J' y3 y' N1 N
6 v- M3 J; C# o6 Z+ C. H
    >web3.eth.accounts% q5 E8 ^+ A8 l  @  w
) @7 d4 o' t6 o
    ['0x5c252a0c0475f9711b56ab160a1999729eccce97'
3 i, f/ P- Z, n; Y# r1 t- H
. \- b6 B1 S! }$ ^    '0x353d310bed379b2d1df3b727645e200997016ba3'
* p# r6 W$ I! t9 G0 A( N% U' M( \9 Q( w8 T1 T: e1 S4 b, E8 ]
    '0xa3ddc09b5e49d654a43e161cae3f865261cabd23'
0 P! x& F% B* Z( E
1 F% c, n' c" k: R% d8 |    '0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5'. T; @1 j; a0 ^2 Z$ O9 D
3 u( ^" r5 d! A5 e. O
    '0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798'' z) |: C$ g9 @2 D! O# z

9 v% K5 U& s8 \' I    '0xda695959ff85f0581ca924e549567390a0034058'
* n: Q' E8 [0 U. z7 \
) u+ G, P8 y! d: G    '0xd4ee63452555a87048dcfe2a039208d113323790'
$ ]+ y4 c4 A" @; T# D* Y  i" L. \( _* A4 E; m, X. O( [1 U7 H$ C
    '0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14'; F3 T7 v2 T. W3 Z/ ^$ ]

1 g4 G  a3 ]- o3 Y2 @  Z! x* U5 Y    '0xba7ec95286334e8634e89760fab8d2ec1226bf42'
! R& i' g6 a8 p# X# f
* m  v6 Q/ r+ ~- V% v    '0x208e02303fe29be3698732e92ca32b88d80a2d36']/ \- t1 R4 J( @+ Y
1 r2 j2 j5 q7 ?9 X8 H8 I
    >code=fs.readFileSync('Voting.sol').toString()
( M9 |' l/ p/ r3 S7 e4 j1 u1 U  I4 s7 z, n3 N
    >solc=require('solc')' I( Z2 J  z8 X8 d# S$ Z

. B0 K, L) @: H6 P/ |: I    >compiledCode=solc.compile(code)
" m  F! h& l* [  c. `
& _, o& ^: B; C    当你成功地编译好合约,打印compiledCode对象(直接在node控制台输入compiledCode就可以看到内容),你会注意到有两个重要的字段,它们很重要,你必须要理解:
9 k) z6 a1 j+ f6 w6 g' [
/ a  @: q' x6 T6 v* F& B2 L    1.compiledCode.contracts[’:Voting’].bytecode:这就是Voting.sol编译好后的字节码。也是要部署到区块链上的代码。
0 `+ W6 b; |) V4 R3 {7 {* {) F8 ?1 b0 Z) `5 Y, T
    2.compiledCode.contracts[’:Voting’].interface:这是一个合约的接口或者说模板(叫做abi定义),它告诉了用户在这个合约里有哪些方法。在未来无论何时你想要跟任意一个合约进行交互,你都会需要这个abi定义。你可以在这里看到ABI的更多内容。5 ]% Q0 d1 k+ k7 p

2 T" G. \. ]( x. B4 Z    教程参考汇智网的DAPP开发入门教程,如果大家等不及博客更新,也可以直接访问这个以太坊教程。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

dancing520 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    1