Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
本以太坊教程主要是介绍:搭建一个开发环境、编写编译一个智能合约。2 c! [6 j2 k7 o) {, k, f
6 r; Y, S' A7 G0 Q, q
    以太坊是什么7 A) C3 l! x" u" f+ x

; c5 f; f( W$ C4 t    以太坊(Ethereum)是一个开源的有智能合约功能的公共区块链平台。通过其专用加密货币以太币(Ether)提供去中心化的虚拟机(“以太虚拟机”EthereumVirtualMachine)来处理点对点合约。+ X# v# A+ o3 c: Q( g
6 k9 i& u  i9 t: \
    以太坊的概念首次在2013至2014年间由程序员VitalikButerin,受比特币启发后提出,大意为“下一代加密货币与去中心化应用平台”,在2014年通过ICO众筹得以开始发展。目前以太币是市值第二高的加密货币,仅次于比特币。) s* `- X8 e- G9 a
- t3 `" `5 j; h) P+ x1 Y0 t4 c0 O2 }1 ~
    以太坊区块链是什么?
8 D1 J( k5 S3 Q0 B9 x' g' f( l1 z# p! W+ ^
    以太坊区块链有2个主要组件:- \5 E% P6 R+ e1 ?) ]8 }/ @4 v
6 x* H: x/ f7 P. k9 B  t
    数据存储:网络中每笔交易都存储在区块链上。当你部署合约时,就是一笔交易。当你执行合约功能时,也是另一笔交易。所有的这些交易都是公开的,每个人都可以看到并进行验证。这个数据永远也无法篡改。为了确保网络中的所有节点都有着同一份数据拷贝,并且没有向区块链中写入任何的无效数据,以太坊使用一个叫做工作量证明的算法来保证网络安全。7 W0 B( l1 z# E+ l5 P  [8 U" s! X
1 k# N# U0 U) l" J: p) M* t0 V% i
    代码:就数据的层面而言,区块链就是存储交易。在以太坊的世界里,你可以通过一个叫Solidity的语言编写逻辑/应用代码(也就是智能合约)。然后用solidity编译器将代码编译为以太坊字节码,并将字节码部署到区块链上(也有一些其他的语言可以写合约,不过solidity是到目前为止用得最多也是相对更容易的选择)。所以,以太坊不仅仅会存储交易数据,它还会存储和执行智能合约代码。
" m  a( q- ]3 U$ G! Y; m! o0 H1 Z3 b
# X  a& a) v* T* @& B% Z& A' q( M    可以简单的理解以太坊区块链的作用就是存储数据和代码,并在EVM(EthereumVirtualMachine,以太坊虚拟机)中执行代码。( P6 @; E, V6 D

! Z' A7 l" S  m$ p! _) ?; ?+ C    要准备的基础知识" ], d, j/ f. H- d8 S# Y

/ y" _& ]1 q0 K9 g    为了进行以太坊开发,你应该对以下语言/技术有基本了解:
1 y- i8 [) b; f. o8 C4 ~9 {, [# X0 v% _! w5 u7 v8 V* R+ u8 B
    熟悉某种面向对象语言(如Python,Java,go)
3 e0 q8 R' N2 O& ]; t
; o: S3 U* a5 ?! r/ J  P8 F    HTML/CSS/Javascript2 X0 n  v0 ]7 X! d1 o
7 C; M3 ^. j" A9 d, K/ h( K
    基本的命令行交互如Linuxshell命令
. S" S) ^- M- i+ D1 R
  u5 x( e8 s: D8 f, q! s7 X' n    理解数据库的基本概念
! ]/ q0 b1 d* J( S7 a2 W
5 X& Z9 D' z* \& ?; p8 h& T. Y    为了构建以太坊去中心化应用即Dapp(Decentralizedapplication),以太坊有一个非常方便的JavaScript库即web3.js,你也可以在一些js框架中直接引入该库构建应用,比如react,angular,vue等。! T$ j4 G+ A5 u# r' {
3 w7 M% i, [7 j, W
    示例:一个以太坊投票应用
8 y# _" Z1 ^3 y+ D$ S3 T$ P7 w- A* E5 D- f; T
    以太坊教程示例中,我们将会构建一个简单的去中心化投票应用。所谓去中心化应用,就是一个不只存在于某一中心化服务器上的应用。在网络中成百上千的电脑上,会运行着非常多的应用副本,这使得它几乎不可能出现宕机的情况。你将会构建一个投票应用,在这个应用中,你可以初始化参与选举的候选者,并对候选者投票,而这些投票将会被记录在区块链上。你将会经历编写投票合约,部署到区块链并与之交互的整个过程。你将会了解什么是一个合约,将合约部署到区块链上并与之交互意味着什么。8 C/ X' \5 C4 p3 c" C7 T
9 x& H( B5 W  b+ Y3 j
    本质上,区块链就像是一个分布式数据库,这个数据库维护了一个不断增长的记录链表。如果熟悉关系型数据库,你应该知道一张表里有很多行的数据。现在,对数据进行批(batch)量处理(比如每批100行),并将每个处理的批次相连。就可以形成一个区块链了!在区块链里,每个批次的数据就叫一个块(block),块里的每一行就叫一笔交易(transaction)。
$ W! R8 h% \" q3 P* [9 Q; ^) d# f9 E/ z, o9 [- a2 p4 z' ^
    现在,你对以太坊已经有了基本了解,我们可以开始构建投票的dapp了。这将会加强你对以太坊的认识,并且初略了解以太坊的功能。
; }, O, E6 ^, w! B1 ^
7 r! z: x* t9 T) x, y: `5 D& S0 v    以太坊开发环境搭建
# k% M5 ~, Z3 V: T) O; w' s
- Z/ s& u* w5 T    Linux
) e/ E& b7 M7 q5 P8 @7 B' ]4 A. H+ z* L9 q5 ^( [  p0 X. c+ f  l
    示例是Ubuntu16.04下的学习环境搭建,你只需要成功安装了nodejs和npm,就可以继续项目的下一步了。
2 S( o- Y2 C% c" e2 b( }. i' r2 }1 D& g4 d
    我们通过npm安装ganache和web3包来为以太坊教程提供支撑。我们也需要安装solc来编译合约。
. k5 u) c2 G. W3 G& m- V& D4 m; q' l, D4 |( b' C$ U
    下面是安装过程:# H4 h) j$ H' R

" z; C: v& P0 t8 g) W& V$ c4 l    $sudoapt-getupdate
4 o. R% k1 M! o1 a" C9 z5 ^* h" g2 i$ h5 U5 M
    $curl-sLhttps://deb.nodesource.com/setup_7.x-onodesource_setup.sh
6 S& ~" s4 L6 `' v& _8 R
) U- O7 k5 W$ o4 T    $sudobashnodesource_setup.sh/ r- R. G/ m+ \7 e
9 `. B! e; r- l0 W' X
    $sudoapt-getinstallnodejs& H3 T6 k- d1 Z7 [( O
. K5 I' Z( V9 O1 j' T: H+ B7 }- J
    $node--version
0 J( T) N- p" W8 b' _  V
0 L: K  H& `6 j; x8 ~$ f5 x; g1 l3 t1 x    v7.4.0
1 K, W: l& [6 S# ?: o  m
$ K) Z# g& \7 K3 }# {, F    $npm--version
0 @( ~# T* P% }; |) Q7 O' c) f
5 k/ m7 ~1 [- f4 E! }# \; X% P    4.0.5& E+ M/ o9 E( W0 R8 f5 T

- r  `. q. D3 X7 n    $mkdir-pethereum_voting_dapp/chapter1
4 a) E5 f% n- v* G# L# R8 l0 t3 R7 o7 A. T' f
    $cdethereum_voting_dapp/chapter16 x) M$ J5 g# \9 v8 @* T0 s

4 R; G& Q, e8 D! p: _  N4 S    $npminstallganache-cliweb3@0.20.1solc
! }1 i0 n  Y" @5 W+ v8 x/ ^& N. @3 K  X4 L- u2 w
    $node_modules/.bin/ganache-cli3 @: \: o) ~. E0 |0 K5 L$ d. o. q

" V5 |' N4 m' G+ I4 l    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到下面的输出。# t3 n2 f" ^+ g$ g, j/ _
9 t8 a9 r, S& {' D
    GanacheCLIv6.0.3(ganache-core:2.0.2)) a3 Y4 u3 t: k0 b
; S9 W6 b. f* |5 t' x$ K
    AvailableAccounts
3 F6 I- k' A  C- c; M; h/ f
! K5 f4 Z, v7 D2 g$ m    ==================  s# R9 J/ e9 X+ K

2 `* J  A! P' `    (0)0x5c252a0c0475f9711b56ab160a1999729eccce97
5 b0 w9 w0 ?9 T4 Z+ d# m$ x2 _, m6 R/ x) E
    (1)0x353d310bed379b2d1df3b727645e200997016ba3
# D/ t  O  ^1 J2 B2 c  }4 w8 `9 O$ R7 M
    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23* K5 A# _6 \: m% h6 d
; f' F+ p# A9 G8 C1 K% b
    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5
" D: @' V8 }; e0 E( P4 J
: K/ p. `0 `6 ]( ^/ p    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798' {/ a8 k4 Z$ ^% r

$ D, Z& A& k7 I  H    (5)0xda695959ff85f0581ca924e549567390a0034058, ~7 N; L. l# Z4 s
* @  @, y$ b: A# G6 W5 r" Y
    (6)0xd4ee63452555a87048dcfe2a039208d113323790/ t! p- f5 o% f( E
9 Q- Z4 ^! T, u( u( l
    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d145 E& \0 G+ ]# o- e! i* P: r
4 h, z" N6 I" R5 _
    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42# u  g7 ~. N9 K3 J8 t; b  Q0 k) x

% O5 H. |! O1 Z0 K" c    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36
  g% W4 a, E9 p9 ~& d3 `1 f* ?1 W
    PrivateKeys% [- H8 E. b! B% Y0 f+ W5 \- M
: Q3 V$ T6 z& x' }% x2 o
    ==================! S7 i8 e& E, d7 x6 M) K( v

, d/ ^! V0 V4 |* Q& e    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b
7 K- n6 p! x7 |8 Q; U4 Y5 \6 I2 T1 Q
    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603
) E  O& ^0 ~$ X0 W- ~9 V9 _3 Z) d' |' D8 `
    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99
$ V- ^$ G/ m4 Z6 Q
5 |4 ~0 F' {  G) \    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430, _, g! f; Z, ^: P

" ?: c) O0 z1 p! u    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a89 j! {. q. i; r# G8 J
" U. E: k. G% b  x& g+ ~& q
    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc/ ]; Z5 l7 N& C7 m! o" Z

4 c( `! j$ n- \. a    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9
9 }  q$ L; f; ~! @, {8 R$ P/ H
0 i, e, F0 f: n" Q; @6 c0 a# L    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d% p1 ?: \7 t, G% d
' Z+ ^& A! H4 S' J. G
    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
, [; H$ f! h+ T. c9 `- s/ @3 c+ n* T) y# x. D1 i# r9 J) S7 h/ g
    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0/ r* j7 A7 C: l6 ^8 v& R1 a/ I! N
3 G2 B( G" ~' q% v+ V2 [
    HDWallet; _' J5 [$ Y- w* I4 F0 S. j' F

4 r% e% G7 b+ d8 n3 D    ==================9 m) o' |/ f$ h
" u/ d1 E$ L7 l% A4 O
    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella- G+ t# M0 V" g7 S5 v

& v: {; p6 F/ w, g# @1 B; j' X4 h    BaseHDPath:m/44'/60'/0'/0/{account_index}/ C8 M: P  [" _6 T: E, j0 X

' v! U4 a( V+ A# l% e    Listeningonlocalhost:8545
1 g$ z! c* w  W3 m+ m* q1 [. e/ k% E, S  g/ {) h0 F& m
    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。
3 m) \% W+ q4 l0 O: @( A7 v8 m6 Q8 i" Z9 v. x0 g/ S0 X" z6 e) h+ [
    MacOS! f  O* ]8 V, I0 M
: h0 d3 L$ n$ {& O
    如果你还没有安装homebrew,请按照https://brew.sh/的指示安装homebrew。homebrew是一个包管理器,它可以帮助我们安装开发所需的所有其他软件。按照下面的指示安装所有其他所需的包。
' n0 a5 _/ ]0 s6 k, E8 F3 Q* z# m7 m: ^, W9 a1 H& w
    $brewupdate; v# S  ~2 [! Q' I, a
% a2 A# X9 T; Y+ e* A9 D
    $brewinstallnodejs/ r& q1 @& n5 `+ N

/ I; F9 h+ P5 V, [3 i; @1 P    $node--version0 Q( {: e1 @: o

5 c  K5 ~+ j8 J# m    v7.10.08 p1 }) M" E) q
8 p3 ^- ?6 E. @2 e: l( r: i
    $npm--version
* e- H$ {( N3 p* u
8 Q) u0 T9 w1 }/ n    4.2.0/ Z% A3 y& j5 m1 K$ e; {
6 s: ]  J0 o0 P9 ^$ o
    $mkdir-pethereum_voting_dapp/chapter1
+ j* T9 g( l1 Q  t" A' ~, D0 |% ]  w0 o2 ?  J! m& V
    $cdethereum_voting_dapp/chapter18 k3 L& X% {6 c2 X, I' W1 {: `

$ a! S8 s" u3 D. w1 \    $npminstallganache-cliweb3@0.20.1solc& v0 [" ^% @( d: B% Y! H& |1 u$ L

$ N0 x( k& _# H( Q2 {. X5 N9 y    $node_modules/.bin/ganache-cli( M. ~+ X6 \% `0 i
% t( x# ~4 u3 V5 ]. j1 z( K( v% c
    我们通过npm安装ganache和web3包。我们也需要安装solc来编译合约。
) G. z9 d5 Y( A5 F7 k& x2 s% V
! H! J- P/ h2 m* K* ~    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到右图所示的输出。( B' d( M) g% [
& Z, j5 a8 U  S" A
    GanacheCLIv6.0.3(ganache-core:2.0.2)4 y% b3 |* g; `/ R3 E

* j( j" i& B. X" v, U2 x# y& w( T    AvailableAccounts
2 s. x" P! T' |4 u, l2 l1 D- w) @7 b# h; U. X
    ==================
! i  q" Z, K$ S) X" D
3 Q0 I# p9 `$ O: R8 Z    (0)0x5c252a0c0475f9711b56ab160a1999729eccce97
) U" {6 Y# ~5 }3 F% r! @: G: L0 U) J- F; r
    (1)0x353d310bed379b2d1df3b727645e200997016ba3, {! E$ S1 c1 e( ~$ Y4 `
7 Y1 h7 L  Q" F& E% A
    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd238 v3 Q. G4 }' j) @2 n* n

- W, Z$ K0 g! G9 ]( p8 h    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec58 `/ v! h0 S' F# G
! P" C$ ~! w1 f! c
    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798' _9 J8 O. S( e/ w. E4 [
; Q7 H, c/ z' e- x) w
    (5)0xda695959ff85f0581ca924e549567390a00340584 v7 }; P# p  J  U: \) s: t+ Z
# n# n* ~4 H: W! \
    (6)0xd4ee63452555a87048dcfe2a039208d113323790
4 a$ M7 x. Y' ?: I/ E7 y4 A
6 K- j( W8 {5 X, X2 T& _. ^2 D    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d143 i1 L; @7 ^6 u/ ?& s
0 b; {, b( T% f
    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42
  H0 W: D/ G* X/ W5 D0 E! ]6 J% X
    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36/ {# j& a  R: q0 ?/ W
" K8 M4 ^2 G9 S. `
    PrivateKeys
2 `2 H5 ]) K) _4 Z6 A1 G% Q$ g; V, @/ A1 l/ t, e7 w2 Q
    ==================. @% }6 p& v% `9 [. B1 V6 I
) q3 R% p% ~9 D
    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b: v+ S6 A$ y% ?. i: `

* U* F8 L  h$ w, s& o: B+ j' |    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d6032 N$ e9 o6 m9 m$ N* B" [, G

, Q- G* {3 \' C  x: V- w    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce997 D6 ?8 a: W' M; A5 j9 ]
: s5 J' u& Q( e# I
    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430; ^, R& q' N" o+ Z" p7 J- b% J

% P/ ^6 X( V7 r8 s' G2 m    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8
. w" X7 ^5 M7 E3 A* F$ S
% k5 }' b% j: R1 q    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc
4 ?; G# r& `" g: S' e
, j1 ?% F2 X$ K: o8 s    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9$ l; U1 B% [  _+ p, n
$ [# Y7 n% ]! O$ ]9 s# _: y- m
    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d
4 d; T- ?; {$ }  q1 R2 h# _
: S  K2 u4 a/ a/ l    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
8 a9 E! _! x  M, I- x' }
2 w) z' j9 N& }% ^3 Z% R  V# u, I    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0
/ o- l  _, F- f+ C; X* j  e) \2 ^6 V
    HDWallet
' W+ F2 b( j+ b5 m9 O1 |3 D& ~
$ B% t% a: w& S. h4 H    ==================4 Y$ q3 j* }4 T0 l5 r  B% s

9 F- K# N4 F* U    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella
" e1 y/ @# q2 O9 Z" }0 T
) \' t" K5 y& ]    BaseHDPath:m/44'/60'/0'/0/{account_index}# z: h* W! d  r4 M' U4 W4 \

8 m! e: G3 ^9 p8 ^. W. `    Listeningonlocalhost:8545
2 Z" q; E9 u" h% m; D  F) G3 _0 Z5 R% \+ S* e3 V
    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是以太坊账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。
% ?9 x# B1 i3 _& d. a6 A: q( a8 u( x$ _' a* f1 T* ?* K
    Windows
* X; Z$ A8 P  v+ R) m' p  ^4 ?2 [4 y4 X' ]
    安装VisualStudioCommunityEdition。如果你选择定制安装,那么至少应该安装VisualC++(目前的版本是VS2017)
6 n  M$ Q' I) {2 z% e6 ?% G/ Q8 ~2 E
    安装WindowsSDKforWindows
( ?1 u" I5 |. p9 K( d) {+ Q  Q4 \2 e
    安装Python2.7如果你还没有安装的话,并且确保将它加入到环境变量PATH0 P3 c1 `2 i6 N1 D6 D% d
$ [- d: E& p. w, B, O$ t  p6 {
    安装git如果你还没有安装并加入到PATH! N/ J/ s2 s6 p# z8 y9 C7 T
, S7 [$ B- B1 g; c$ N) D
    安装OpenSSL。确保选择了正确的安装包,并且只安装完整版(而不是轻装版)。你必须将OpenSSL安装到推荐安装的位置–不要改变安装路径! G! f* M  ^* L

, k# v* P/ z5 r# ?7 e' z  Z    下载和安装nodev8.1.2。不推荐使用版本v6.11.0搭配VS2017& m7 H4 y5 x& k' E; `; i' i
. {; T/ h# L  v4 l9 }7 Y. C/ P
    执行命令npminstallganache-cliweb3@0.20.1solc
/ p0 a- x; c& u, p3 D+ b
( y& h4 Q" R+ j9 V3 `% `: m# c    SolidityContracts% w* [/ Z& U$ |" U7 O

& ^" g' P7 k$ G8 \    现在已经安装好ganache并运行,我们将会开始编写第一个以太坊智能合约。
# L4 u6 h( `0 P6 M' G2 S" ?; r, |/ N( X
    我们会使用solidity编程语言来编写合约。如果你熟悉面向对象编程,学习用solidity写合约应该非常简单。我们会写一个叫做Voting的合约(可以把合约看成是面对对象编程语言的一个类),这个合约有以下内容:
3 V; c& R8 r& w3 c( [) L1 P4 u% K% ~# \5 I. k) g. ^
    一个构造函数,用来初始化一些候选者。, Q$ A( w- n+ K  N

" p" O( `* p. e( D    一个用来投票的方法(对投票数加1); m: Q6 f4 I9 L. Q+ v- P

$ f" Y2 ?- ]3 [/ u* s( p+ h; K    一个返回候选者所获得的总票数的方法
0 a0 e( L5 H4 m9 C* g5 W# ~5 T7 s4 X
    当你把合约部署到区块链的时候,就会调用构造函数,并只调用一次。与web世界里每次部署代码都会覆盖旧代码不同,在区块链上部署的合约是不可改变的,也就是说,如果你更新合约并再次部署,旧的合约仍然会在区块链上存在,并且数据仍在。新的部署将会创建合约的一个新的实例。! ]* d4 y' K0 W/ E# V

5 y* t9 \9 R# [    pragmasolidity^0.4.18;( j. ?, h( M1 P  J
5 _7 H% z  v: b; u, i
    contractVoting{
+ d) G, v9 }( v9 \
, M+ J5 [, A* A, {, ~    mapping(bytes32=>uint8)publicvotesReceived;9 @3 P) k3 Q$ w2 I& `7 s" s9 X
9 `( a$ z2 U# R6 E* I3 Q( a6 p
    bytes32[]publiccandidateList;4 Z& h( s, G  ~. b* Q

  u) g/ m6 b% D4 X6 Y" P: \* w    functionVoting(bytes32[]candidateNames)public{: S  {% D( S7 b; d/ A
$ E. E- [4 v' U) l0 S$ f
    candidateList=candidateNames;* I5 D# v" n2 J8 ^1 i" R* Z

: s9 \, F! K4 G+ a$ R  c, m    }$ M6 `* V" A1 O9 V1 ]( x/ Q
  y) @& b; D9 f9 W. H$ x1 q/ j  i
    functiontotalVotesFor(bytes32candidate)viewpublicreturns(uint8){
6 u/ ^' t# h2 U/ R- n! M
& r9 R) H3 Z' j0 ?8 u- U    require(validCandidate(candidate));1 `  T! w, A5 O; y

7 }( b3 G- N+ J    returnvotesReceived[candidate];
9 V' G8 \0 C5 e+ E8 L! W$ D9 ^( @% y
    }
7 `0 G1 r  N; {4 a; N6 ^: Y+ q4 z6 K( t4 h7 V$ {
    functionvoteForCandidate(bytes32candidate)public{
' s1 r% t9 e' p1 M6 G8 Q6 N" [' w; K1 V0 d3 o: X  O
    require(validCandidate(candidate));
) e, t' m' ^; n: O5 M
; c7 o  F: |/ b+ y/ e& b" N/ F    votesReceived[candidate]+=1;
' ?) g# u1 w* o. x- N( R% M1 q2 U9 B  v5 D1 F! B7 w8 J: m* D: }( O
    }* h/ H% x9 [2 P+ y* ^
, q3 \: X% }3 _6 p
    functionvalidCandidate(bytes32candidate)viewpublicreturns(bool){
) {5 K  c: y: M$ u4 e# ]$ y
+ C2 `' I2 T3 A- q# q    for(uinti=0;i6 P3 T4 x/ `0 U9 N) u. J
/ `2 G4 h! H7 n3 H5 R( F9 s2 r; C
    将右侧代码拷贝到一个叫做Voting.sol的文件中,并保存到chapter1目录下面。9 i) F% s8 y" Y

  }2 e0 a  M3 z5 J2 G1 A& U    代码和解释* T& M3 W5 R9 h, M: [4 N
5 A2 }, L) R+ r( ]
    Line1.我们必须指定代码将会哪个版本的编译器进行编译& Y8 R0 L* l/ J0 L

6 s( z  v' \) c7 v% X    Line3.mapping相当于一个关联数组或者是字典,是一个键值对。mappingvotesReceived的键是候选者的名字,类型为bytes32。mapping的值是一个未赋值的整型,存储的是投票数。
& Q, o& M5 M& b0 u3 D2 `+ Y1 E! s. c) X
    Line4.在很多编程语言中,仅仅通过votesReceived.keys就可以获取所有的候选者姓名。但是,但是在solidity中没有这样的方法,所以我们必须单独管理一个候选者数组candidateList。
* G* e+ L% ^0 ^4 |+ h" P1 Q9 k2 @; V5 J! d, |" x$ @6 h, m/ Z+ a
    Line14.注意到votesReceived[key]有一个默认值0,所以你不需要将其初始化为0,直接加1即可。
  c- f+ R+ ?. ]/ R/ ?4 \7 A) D
% w- Q) |' Q0 M! A' A% P    你也会注意到每个函数有个可见性说明符(visibilityspecifier)(比如本例中的public)。这意味着,函数可以从合约外调用。如果你不想要其他任何人调用这个函数,你可以把它设置为私有(private)函数。如果你不指定可见性,编译器会抛出一个警告。最近solidity编译器进行了一些改进,如果用户忘记了对私有函数进行标记导致了外部可以调用私有函数,编译器会捕获这个问题。这里可以看到所有的可见性说明符。0 y' Y- l' h  S2 C
) [: z6 ?; T' ~  X8 F
    你也会在一些函数上看到一个修饰符view。它通常用来告诉编译器函数是只读的(也就是说,调用该函数,区块链状态并不会更新)。所有的修饰符都可以在这里看到。
  B4 a4 T- F1 q# s; M% ^& b1 \7 M* m& j7 H5 c: ~( g! X7 w
    编译智能合约
0 @/ J5 B! S# j% \  h+ ^+ n: c3 [" G7 S; I% r( w2 }. D. E
    我们将会使用上一节安装的solc库来编译代码。如果你还记得的话,之前我们提到过web3js是一个库,它能够让你通过RPC与区块链进行交互。我们将会在node控制台里用这个库部署合约,并与区块链进行交互。4 l  P  o0 K0 E% |) c
5 L: O: j# W3 A9 O( ~7 d; ^
    首先,在终端中运行node进入node控制台,初始化web3对象,并向区块链查询获取所有的账户。0 {; |* `& |  V1 p! O

4 A( q8 O/ B. y/ u    确保与此同时ganache已经在另一个窗口中运行
8 R) Q0 g+ E* B$ g% e$ I4 w, I0 Y# H; _/ t; G) y
    为了编译合约,先从Voting.sol中加载代码并绑定到一个string类型的变量,然后像下边这样对合约进行编译。' N0 x- @# T3 o, O4 t' b7 D% F
# @2 k) j: ^& S) T% b5 g
    $node
' [3 L6 N6 Q: J) b7 F; |3 S6 b: R# \6 p# E
    Inthenodeconsole( H- I6 O( `, H0 c5 q$ h5 M" d, J

# m) B% d4 {. C6 P9 q& x    >Web3=require('web3')( M* c! {5 y* |: G- e( T0 n9 c
' ~$ s$ k7 x8 M+ L
    >web3=newWeb3(newWeb3.providers.HttpProvider("http://localhost:8545"));
& ]% |! P) v5 q& ~# v; q
/ t) c8 C5 q: g& N6 {    >web3.eth.accounts
; ]% }: }4 {3 z6 n/ R; _
# p# B: ]1 D( h1 }3 Y& b    ['0x5c252a0c0475f9711b56ab160a1999729eccce97'; O, w' H" r# v! x7 s+ J" J

5 O. w. Z/ C* f$ f: L    '0x353d310bed379b2d1df3b727645e200997016ba3'3 a; E, ^( U- W8 W, _9 ]( X4 D
# [  Z8 C  `$ v* Q
    '0xa3ddc09b5e49d654a43e161cae3f865261cabd23'$ u5 E  E" l- Z5 z6 i6 @- \0 q( |

  u6 E$ u7 F/ `8 {+ Y$ W# }    '0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5'
7 i/ ~! M. c7 f( I6 X, i% ]! b1 ~
    '0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798'* ]; A- i: [3 e0 [- V! {2 O
/ K$ h: I, T) E0 K
    '0xda695959ff85f0581ca924e549567390a0034058'" ^  [: h8 J; b: j/ Z3 D

6 u3 ?5 E  B) k) c9 p2 e4 o: ~/ X    '0xd4ee63452555a87048dcfe2a039208d113323790'
) t2 o; O! O/ v( C2 p
# ]5 Z# e& u2 Q6 u4 Q' z: }    '0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14'6 d  Z# g1 |$ w2 `: Y* W0 |

3 y# K- u- W  w% ~    '0xba7ec95286334e8634e89760fab8d2ec1226bf42'+ o5 X: `9 u1 K/ e- n
" y: _7 S+ u8 p5 {+ @+ X/ \: C( D3 W
    '0x208e02303fe29be3698732e92ca32b88d80a2d36']
, g5 g# _- M" d% K3 R. |$ T7 \, G. T0 G- B4 D9 Z$ q* v) W1 [
    >code=fs.readFileSync('Voting.sol').toString()- t$ ~. ^$ M7 g, s3 M, m7 b2 b( Q

7 L/ }/ k2 \6 x' W    >solc=require('solc')
! M# j8 E+ U) z' ~: q  `* a5 V+ p
; A; j; Q$ F! G! z8 [+ [    >compiledCode=solc.compile(code)
: f; X- P5 s0 @. {7 h) y0 _$ b" j: [3 J$ m; E
    当你成功地编译好合约,打印compiledCode对象(直接在node控制台输入compiledCode就可以看到内容),你会注意到有两个重要的字段,它们很重要,你必须要理解:- g: t  G) o* K2 P
8 z6 `9 U' ^) B. z* F8 w* O
    1.compiledCode.contracts[’:Voting’].bytecode:这就是Voting.sol编译好后的字节码。也是要部署到区块链上的代码。
/ t, @6 K) t# |1 [( e5 ~
) T  s* @# g9 I7 ~  g1 I8 @    2.compiledCode.contracts[’:Voting’].interface:这是一个合约的接口或者说模板(叫做abi定义),它告诉了用户在这个合约里有哪些方法。在未来无论何时你想要跟任意一个合约进行交互,你都会需要这个abi定义。你可以在这里看到ABI的更多内容。
) V2 T$ U& H% R. K6 E# P* X
) z. y  s6 F6 c* B& _  l4 q, D# s& W    教程参考汇智网的DAPP开发入门教程,如果大家等不及博客更新,也可以直接访问这个以太坊教程。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

dancing520 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    1