Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
本以太坊教程主要是介绍:搭建一个开发环境、编写编译一个智能合约。
  j: g3 l5 o- E8 z* I5 |
; R8 I3 Z; u' X/ \! L    以太坊是什么
& l) Y+ T( W! s  e5 p- _
+ k' E" D1 T0 Q4 k$ ]) e) M    以太坊(Ethereum)是一个开源的有智能合约功能的公共区块链平台。通过其专用加密货币以太币(Ether)提供去中心化的虚拟机(“以太虚拟机”EthereumVirtualMachine)来处理点对点合约。! m- Y- M, Z1 I

5 ~6 K/ I8 k5 Z. o* O* ?& H    以太坊的概念首次在2013至2014年间由程序员VitalikButerin,受比特币启发后提出,大意为“下一代加密货币与去中心化应用平台”,在2014年通过ICO众筹得以开始发展。目前以太币是市值第二高的加密货币,仅次于比特币。
! J( T* o6 h2 g; F  b7 @: d. I' j5 G0 P5 K% a" E" o7 J
    以太坊区块链是什么?
/ W8 _: X* K3 X/ V3 W5 I0 ~! P/ g: z7 ^2 Q4 `
    以太坊区块链有2个主要组件:* c$ I/ Q0 \. p7 ?4 W- P3 q
( n5 y3 }# @3 M
    数据存储:网络中每笔交易都存储在区块链上。当你部署合约时,就是一笔交易。当你执行合约功能时,也是另一笔交易。所有的这些交易都是公开的,每个人都可以看到并进行验证。这个数据永远也无法篡改。为了确保网络中的所有节点都有着同一份数据拷贝,并且没有向区块链中写入任何的无效数据,以太坊使用一个叫做工作量证明的算法来保证网络安全。
, V4 P5 c- {  Y2 }& d9 n! e* W4 d* F: r" |' E8 B/ }* W8 L+ m
    代码:就数据的层面而言,区块链就是存储交易。在以太坊的世界里,你可以通过一个叫Solidity的语言编写逻辑/应用代码(也就是智能合约)。然后用solidity编译器将代码编译为以太坊字节码,并将字节码部署到区块链上(也有一些其他的语言可以写合约,不过solidity是到目前为止用得最多也是相对更容易的选择)。所以,以太坊不仅仅会存储交易数据,它还会存储和执行智能合约代码。) Y% o7 y( |# V* t6 N( p# j
2 n( E4 m0 S  D: |
    可以简单的理解以太坊区块链的作用就是存储数据和代码,并在EVM(EthereumVirtualMachine,以太坊虚拟机)中执行代码。* V% X% }2 @/ G2 s1 t3 o
' c$ c) ?9 n, g! H# x3 L) J
    要准备的基础知识
; O6 R; J, {- F5 F( }$ W5 m! b' p# B' A5 {0 \0 R% ^: L+ D  I" F
    为了进行以太坊开发,你应该对以下语言/技术有基本了解:+ V; h- T: `8 a
0 _  V1 h+ z( t! ^$ a
    熟悉某种面向对象语言(如Python,Java,go)
8 E5 B- m  E0 l( o+ X
8 G5 r- N* l5 d$ z: |5 a8 l    HTML/CSS/Javascript" j& Y- v7 M) e+ w. M

% m3 {. M- G" N/ R" a) o    基本的命令行交互如Linuxshell命令9 U8 I) K& Y3 }6 m* T
! s7 t6 ~- Q8 S  ]
    理解数据库的基本概念% }: Q2 R7 H# P* t! C9 F$ E2 T

$ B8 j& ^5 M0 d+ `/ e0 V* }    为了构建以太坊去中心化应用即Dapp(Decentralizedapplication),以太坊有一个非常方便的JavaScript库即web3.js,你也可以在一些js框架中直接引入该库构建应用,比如react,angular,vue等。4 n- n3 o& i/ y7 H7 X
3 ?. f0 j; g7 f7 J
    示例:一个以太坊投票应用9 s. V& k/ h5 @$ n$ k/ z
0 P; g; c$ g( J, u0 `
    以太坊教程示例中,我们将会构建一个简单的去中心化投票应用。所谓去中心化应用,就是一个不只存在于某一中心化服务器上的应用。在网络中成百上千的电脑上,会运行着非常多的应用副本,这使得它几乎不可能出现宕机的情况。你将会构建一个投票应用,在这个应用中,你可以初始化参与选举的候选者,并对候选者投票,而这些投票将会被记录在区块链上。你将会经历编写投票合约,部署到区块链并与之交互的整个过程。你将会了解什么是一个合约,将合约部署到区块链上并与之交互意味着什么。# e" ~* @; u' u& Q8 y4 i; y
- I& X$ O1 a* Y5 u
    本质上,区块链就像是一个分布式数据库,这个数据库维护了一个不断增长的记录链表。如果熟悉关系型数据库,你应该知道一张表里有很多行的数据。现在,对数据进行批(batch)量处理(比如每批100行),并将每个处理的批次相连。就可以形成一个区块链了!在区块链里,每个批次的数据就叫一个块(block),块里的每一行就叫一笔交易(transaction)。  c! C5 Y$ t( x- h; X, ]7 i

, @$ k6 L# f6 m! ?' Z    现在,你对以太坊已经有了基本了解,我们可以开始构建投票的dapp了。这将会加强你对以太坊的认识,并且初略了解以太坊的功能。
+ \2 V+ f# ~1 w+ o3 U
4 |8 a& |6 `: [" `! T7 I    以太坊开发环境搭建
: J, K2 ?, }+ ^( v+ L% J
3 E9 m0 c' ?8 z7 n$ Y    Linux
2 `# g5 p3 E/ x7 a1 d( G* U3 r+ u7 I! D. ~, ?1 _
    示例是Ubuntu16.04下的学习环境搭建,你只需要成功安装了nodejs和npm,就可以继续项目的下一步了。
: @1 d4 D% t; r# C: F, R& n" T0 V9 n% B2 i
    我们通过npm安装ganache和web3包来为以太坊教程提供支撑。我们也需要安装solc来编译合约。4 W: m% x4 j$ I$ W" `
1 D) w) [* Z  m2 e3 X$ t4 r0 e
    下面是安装过程:# b( o" Q* h" x' ]' f! v
' h1 y' `% E# V' T3 w- W
    $sudoapt-getupdate
/ {! V" Q7 X, D( g! ~* N" O" i8 V, m( {+ b, @6 t
    $curl-sLhttps://deb.nodesource.com/setup_7.x-onodesource_setup.sh
2 l5 T( k0 o( V% r
3 N  e: V9 ?. x" Q    $sudobashnodesource_setup.sh9 \" @, E) O+ h( S% {
: @9 Z, b5 \. L: s' f. D0 c
    $sudoapt-getinstallnodejs- Y) A' L4 F" u# t
; e7 r% `2 {, s( w! C0 K- v
    $node--version
$ M7 T: V5 ~7 a" d0 T" v# {6 T4 W
' z" `3 Z; D8 _$ U" N8 _) |    v7.4.09 s1 K( x# \, C) ?" l! a
# K" M  ]& i, e+ ~; R
    $npm--version
# G& a( @! w$ g+ ^8 A2 Z5 G  M" F
    4.0.5' t4 \( S) f. Z

/ X* V0 U2 I8 Q/ S8 `' T3 P    $mkdir-pethereum_voting_dapp/chapter1& i' Y! ]; s( T* N# U3 l3 Q
" i* @( |2 r" F+ ^: l+ f
    $cdethereum_voting_dapp/chapter1
# F- p: v/ W8 d/ v2 Y6 z! A& J1 {7 V5 x9 w' I# {
    $npminstallganache-cliweb3@0.20.1solc
  A0 N  E+ k# [3 {( C9 B; l
2 k) b! W* O+ p! B: I8 S# O3 w    $node_modules/.bin/ganache-cli# C/ z+ A. t& E

2 r: F9 m9 Y& R8 Y    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到下面的输出。$ I+ G9 b. A5 d8 N3 ]1 L  C+ w% Z, f
; h% D# q( q7 }8 O4 ~) J6 T
    GanacheCLIv6.0.3(ganache-core:2.0.2)
: l' D, i. }9 h" j/ \- R1 I! w% b0 j7 J( x/ m
    AvailableAccounts! R* }5 ~; m8 F. Y7 i. K' a6 [5 ]. K

4 K$ l2 {* e/ l5 ?7 X4 ^9 O  {    ==================7 i, @& L: Y& H3 {7 H% a, A/ c
# u% B* S" V7 ^+ B) O
    (0)0x5c252a0c0475f9711b56ab160a1999729eccce973 s- i1 F! d- k, N( ]! r( G
* n8 S3 `; ~+ V& [- ?7 ?) B, g
    (1)0x353d310bed379b2d1df3b727645e200997016ba3
4 ~4 c, M- i9 s# w- Q
8 a7 g8 i$ t& L% R; x" t8 q: i    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23
  o4 _" \& `6 t4 h/ W
% ~' a1 Z2 @9 z( T    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5$ F9 n- X! t/ ~
$ I# X/ {  }  j/ G" W6 Y* `, ^
    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798
- n7 s, ?0 U% b& \' ~
# R, |, d6 ^; v- Q/ r4 G* A  z    (5)0xda695959ff85f0581ca924e549567390a0034058  Z% @6 e! C9 G5 e% @8 w4 c2 b

, J+ y3 n0 C% ?$ m    (6)0xd4ee63452555a87048dcfe2a039208d1133237908 W1 s6 `0 @; j+ v2 @

# h, H7 f. j# B$ m    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14: P( C# d' }! W% }
6 e9 N% {. k$ t5 `
    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42% v% Q0 {0 i7 O

9 ]4 W. c; O& b% o    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36" }9 G/ j( N# G* o7 K2 [+ M
* d) n5 H: ^# Q
    PrivateKeys
$ w, r' a6 F1 ~3 p+ u
( b: N0 S/ k" \5 z* U    ==================
' F. p8 O. R0 f$ B' S" [) ^
' P7 V( i1 Q3 _( p    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b# T) z: q( M: a3 d1 I' H

* J( E1 M+ @6 q7 U7 Q- A% q    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603
: S1 ^- s* C; O: y) H9 I1 I% i4 n0 |, G
    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99/ G4 ^& K) k% k' @

* r4 m; S3 E% A4 e! ^- ~* x- T, \7 }    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430
* Z3 @& n, y) k, M" \5 y- u, a1 t0 F% U2 f# a! Y
    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8
: }$ t: `$ q  n) u5 Z  Y; |2 _5 K  `/ h+ W- y) k
    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc, [! u2 k% L+ W0 r, V

' b; [4 s6 j4 a    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9
4 g; S7 g  W# F- z, A: ?/ ]$ H1 U1 D, B( D* q$ @1 T3 S8 i/ s
    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d
/ d6 q" ~9 o: J5 ]7 Q4 l
, u  a0 V9 k& e% y    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
- c) E$ U: |4 A! G
/ w7 J+ t$ f2 M! S    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0
7 t9 d- T4 k! i) y' h- `: f- n0 F
# J7 T9 u5 s* P9 X& ~    HDWallet! z$ y4 X5 X& s# b0 H# r
8 i3 s0 k1 d/ V+ b* a
    ==================. e3 k9 e; }- _( U: Q5 d5 w

0 W3 E! x/ }, A3 n* B! v& i    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella
6 r( m0 Y" P, S0 F( r2 ]' C. @+ D4 E# ]0 N" y/ S! y* f8 a2 d# _
    BaseHDPath:m/44'/60'/0'/0/{account_index}
& |. D/ I5 K% K. K: \
) S. A4 k8 C5 P0 R    Listeningonlocalhost:8545
9 p! i3 f8 l& y
  @$ n  r+ ~! L7 y; E/ v% h) @8 R# a    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。
* c( \3 \7 E% Z2 L9 {3 r
8 [4 K& Y, F$ @7 D- z7 s1 L    MacOS( A/ Y9 g5 |5 K: \7 |- m# T& p9 m2 m( D
* }5 k! G% I9 h" d6 }1 q+ J7 }
    如果你还没有安装homebrew,请按照https://brew.sh/的指示安装homebrew。homebrew是一个包管理器,它可以帮助我们安装开发所需的所有其他软件。按照下面的指示安装所有其他所需的包。* u1 Q8 `  ]& y) H

4 V3 x0 ~- ?* N    $brewupdate
/ M! ^( V  T2 @: T7 l9 s+ f
+ S2 X% b' P& [  k& N    $brewinstallnodejs3 M. f. X5 R) k$ h2 @! `$ q& s

8 I8 t; |  w, }# @. L    $node--version" f7 J. q& c& X# z8 l, S

# l4 [0 @2 F" Z% c, m    v7.10.0- V0 I  s, @1 Z9 y/ O: F. Z
- H8 p6 |$ m- P9 I- ~& ?0 o) c0 A* J
    $npm--version
" }& H/ q8 \1 p# _% O* N6 I% |6 |1 R( A' }8 Y
    4.2.09 {' t4 w  Q5 y0 W4 e* e9 s
( `, O& g( \' j2 c
    $mkdir-pethereum_voting_dapp/chapter1! k; ~$ K, b4 s# k6 w
7 }6 i4 E% T' ]0 K# `6 m) L3 I: y: z. y
    $cdethereum_voting_dapp/chapter17 C5 q# T1 n3 X3 M8 t
$ C) T, ^- M9 Q! C( @
    $npminstallganache-cliweb3@0.20.1solc
! h* [9 _/ ^' ?
% _, d1 ^: u; u$ @0 U+ ~6 E    $node_modules/.bin/ganache-cli- ]+ y  }' Y0 _0 M" }) T
/ \1 R5 x. {+ y5 X7 U' \
    我们通过npm安装ganache和web3包。我们也需要安装solc来编译合约。
- E. g: e6 S. R) H& j
# h1 n0 R: W! C. C5 m5 x    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到右图所示的输出。7 E& ^4 ?+ H: I0 V4 L3 g
( y! w' \4 G# F4 G, y* A6 N
    GanacheCLIv6.0.3(ganache-core:2.0.2)  I' [& i$ b" p! \: j$ _
# {5 E! s& j# m0 L8 }" X
    AvailableAccounts
, r& N9 a# s2 [, _7 J9 y, Z" O4 k5 ^8 L' U3 ?
    ==================
# b% S+ L  m5 D: Z! ?7 b
0 v% j: Y0 g& d    (0)0x5c252a0c0475f9711b56ab160a1999729eccce974 \: T# A3 m! y" G, M  n
* w7 K) X5 T6 D4 d- Q4 \" @5 u0 b5 ?
    (1)0x353d310bed379b2d1df3b727645e200997016ba38 K- z8 B: z6 a+ t

$ j' k8 E1 c: W, \6 W; I    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23
6 j6 ^5 Y* z* @7 m! {# T/ [- o2 R  R& F% e% M3 I" J: F" e) V( p
    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5
; W9 ?, S2 l4 r' j. s
; i) v9 p) e" i0 b    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798
, g. P# W8 I& f+ f$ b' N+ R8 P% \% H3 \' F" i9 Y. h1 D: B
    (5)0xda695959ff85f0581ca924e549567390a0034058
/ u9 ^3 J/ c8 d3 Y5 R7 k+ c& ]3 V" ]# ?& T
    (6)0xd4ee63452555a87048dcfe2a039208d113323790; l$ O/ m0 A% \! V4 f( g( ]

' x3 e/ S' h  g# H    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d147 e( |5 q3 h3 k* _7 E% X* j

$ F3 l, R, v! e" \2 Z& j    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf425 @( a; M* Z3 I
* W7 C9 H6 _0 {
    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36& ^* J* d8 v2 J# z5 W9 `/ V

3 g/ y" c+ s  A% R9 u    PrivateKeys# G. ~9 W5 z7 f2 [- z3 A) t: K/ f! \& G

4 o+ d5 {* D7 d$ l# s. A* C1 W    ==================, b0 w' Q; T  q2 b

% f7 M" M9 ]+ W9 C' [$ w7 \- U    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b
& Q8 b' m, n& M8 ^7 q1 V0 ^1 R* v  ]3 S3 _" \, B% F8 Q: Q
    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603
! a* q: Y4 o: g/ b: S. n/ b* o" D( u' [0 {$ e+ @3 [
    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99, `8 \/ b/ J, T" _  v

$ b! M9 O% G  x3 k" O1 p    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f354302 Q/ |; [, f, D' ~2 o6 J! j

/ g" |+ q9 k, t# l0 m    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a80 n  O) g( z# c7 S

4 I7 S& f" P' n& C( x7 p7 i9 L  y% X    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc
9 {0 ?* t+ b& v  ^6 e/ x, m1 Q2 d1 }& y6 G) n
    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9
3 k4 U/ l* ?5 }' B7 f: p" l2 }2 e! t7 [) Q( S# s
    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d1 w/ e, y/ w1 N: k5 I" ~* f, ~

* A  z% t* x) ~  H& G    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
) Z% _  X$ I' `3 [+ N. T
1 @9 V) T% l1 v2 L; N: R1 M    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0& k8 ^/ d9 j" p+ y8 w# x

: y: k; L( i4 Y- D    HDWallet0 M: W6 A- C4 ?# F

' i% [! B+ b% |7 n0 V# U    ==================" w1 L, Y; c2 L% l# Y" d2 s" C
, r9 R8 J. _2 m) Q9 ?  M0 X
    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella! l7 x" l) u2 J) H3 g9 n2 j3 \

+ ^) x, Z' m6 K/ K3 Q  u5 n8 X    BaseHDPath:m/44'/60'/0'/0/{account_index}
* D( V7 n+ B$ p- ?/ x5 C2 @$ ^
7 P. {1 y8 l6 ~  l    Listeningonlocalhost:8545
2 ?7 ?( e' w4 L3 F: R( A2 p/ e3 d6 s$ Q$ F9 ^# h
    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是以太坊账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。
( E( j! ~" _* A% J, \) \
! G8 j, [; ~3 K; ^% x9 E4 c6 v5 J    Windows, k+ ~: l# v, H" B
" {3 B8 z1 q7 I+ y8 w1 \- A% p
    安装VisualStudioCommunityEdition。如果你选择定制安装,那么至少应该安装VisualC++(目前的版本是VS2017)
) F1 b$ Y7 w3 z, x1 S& z( `+ r
    安装WindowsSDKforWindows5 r" p1 y4 p9 z+ _2 [$ k3 K% x

( g& c5 W7 s- j% u" ^9 b    安装Python2.7如果你还没有安装的话,并且确保将它加入到环境变量PATH
" S, m# e8 o1 ?( z) R. B- g4 ~3 q9 B- K' F0 r7 L+ O6 L1 Y, b, i1 d
    安装git如果你还没有安装并加入到PATH
4 T4 ]+ ^  ], C3 {: Z, A: ~& B" m8 Y9 I2 Q3 \4 {" L
    安装OpenSSL。确保选择了正确的安装包,并且只安装完整版(而不是轻装版)。你必须将OpenSSL安装到推荐安装的位置–不要改变安装路径- g7 R3 X, V, J8 j4 t+ p* d' r

! h- s3 t9 I9 H    下载和安装nodev8.1.2。不推荐使用版本v6.11.0搭配VS2017
( ^% _* x5 ^& o# u; S7 u! ]6 E7 D: Y- l; ^( X$ R0 ]
    执行命令npminstallganache-cliweb3@0.20.1solc
- z9 u9 D0 C' R" B  m) F- X. g: s* K* U
    SolidityContracts' R7 I) ~% ~% x6 S4 Z$ W. P6 b3 U

6 g- i5 Y2 |$ ?    现在已经安装好ganache并运行,我们将会开始编写第一个以太坊智能合约。
/ {! Q$ \. K5 A6 p8 m- _# e% c+ M+ o( H* A: c! ~$ x
    我们会使用solidity编程语言来编写合约。如果你熟悉面向对象编程,学习用solidity写合约应该非常简单。我们会写一个叫做Voting的合约(可以把合约看成是面对对象编程语言的一个类),这个合约有以下内容:# ^8 a. B+ d* H+ L

! D# t3 m" F/ Q: l    一个构造函数,用来初始化一些候选者。
0 x  H2 A) m" J* a; ]. K$ d4 E% H/ C  z/ v4 B
    一个用来投票的方法(对投票数加1)* p, d  ^2 b* L; Y8 N5 y8 v

7 u& z  H/ N' `) ~' l    一个返回候选者所获得的总票数的方法
8 f2 X" v' m0 R: c9 i! C2 ^6 x, D/ Z" B8 o# ?
    当你把合约部署到区块链的时候,就会调用构造函数,并只调用一次。与web世界里每次部署代码都会覆盖旧代码不同,在区块链上部署的合约是不可改变的,也就是说,如果你更新合约并再次部署,旧的合约仍然会在区块链上存在,并且数据仍在。新的部署将会创建合约的一个新的实例。
5 v8 `+ I# ^. ~; n+ ^1 C* J4 `6 E) t1 `( M
    pragmasolidity^0.4.18;2 C/ S# L$ |- Q3 w
/ o/ v0 ^' ~+ L: `; m6 ~, n
    contractVoting{
& _/ @" Q- Z+ I1 U) a. L, B) P
6 t5 N6 a, a0 s2 @, T) H+ S    mapping(bytes32=>uint8)publicvotesReceived;
- j, R: _( F3 S+ l% U4 a& d8 a5 [* L+ ~
    bytes32[]publiccandidateList;
4 |  e6 Q! T& |
' i4 z  _' _8 m9 d+ L, X    functionVoting(bytes32[]candidateNames)public{
# \( ~0 o$ w2 V) W. X) a( s" Q* E+ @4 u. v7 T$ t
    candidateList=candidateNames;2 Q/ \' L. g# C- q2 {: f

" w% p5 g* g! X' W' |3 h# q* x    }+ O4 l1 n9 Q5 Y  x+ D6 L
' I$ p/ }- Q3 U, j! y
    functiontotalVotesFor(bytes32candidate)viewpublicreturns(uint8){
' [. M( j8 u& B1 ~' v+ l* P6 U8 a2 v7 L+ f, z. G& h; o
    require(validCandidate(candidate));' n2 D0 d8 G/ T& T6 q" G# k

+ C( v- h( s0 b) f    returnvotesReceived[candidate];3 X# Q: v! X" N5 @1 a3 m' T. f4 c

- m' Z8 a+ U& a    }6 j7 Q  w# n8 F, N- D9 S( {4 M

" M1 g6 |8 E0 M1 }# e% a/ J    functionvoteForCandidate(bytes32candidate)public{1 S$ h" e0 a6 v
: D( B0 r6 W6 ]$ g
    require(validCandidate(candidate));* ^( b- X/ Z1 V) c& o* N( B

: g2 k, o4 ~* G# V* i    votesReceived[candidate]+=1;% p9 X: M0 V. V: V- Z
6 E) Z1 _$ w5 x8 J
    }8 _3 K* W  m8 ?' E* S% e) `  G$ e
7 o  O, ]8 x4 K8 F
    functionvalidCandidate(bytes32candidate)viewpublicreturns(bool){8 s0 f! ~# j: }
* T7 M! B8 L. I& N5 W
    for(uinti=0;i
0 [& L8 F4 v& X7 f
" v! `7 S1 i4 o3 t    将右侧代码拷贝到一个叫做Voting.sol的文件中,并保存到chapter1目录下面。
& s6 [- F1 P/ N3 |3 }3 z( k! G7 ]9 e3 t2 f
    代码和解释1 s, P; j, l: }: @5 }4 t1 b6 l

0 C9 m7 u+ h/ ]    Line1.我们必须指定代码将会哪个版本的编译器进行编译, K% ]; x+ }4 e$ a* d1 w4 B
0 ]  O  e- r7 K7 q
    Line3.mapping相当于一个关联数组或者是字典,是一个键值对。mappingvotesReceived的键是候选者的名字,类型为bytes32。mapping的值是一个未赋值的整型,存储的是投票数。( Q- O3 B: x5 O+ G; v; W( u' G
; [- O# I  Y& [# K4 Z% b( p
    Line4.在很多编程语言中,仅仅通过votesReceived.keys就可以获取所有的候选者姓名。但是,但是在solidity中没有这样的方法,所以我们必须单独管理一个候选者数组candidateList。
  S* R1 N9 q4 Q' V5 X5 J* S& D* R! m  p% E
    Line14.注意到votesReceived[key]有一个默认值0,所以你不需要将其初始化为0,直接加1即可。9 v% m" N, K2 T# j( K1 V. o$ G% q

5 S; ~4 v/ R% Y8 |    你也会注意到每个函数有个可见性说明符(visibilityspecifier)(比如本例中的public)。这意味着,函数可以从合约外调用。如果你不想要其他任何人调用这个函数,你可以把它设置为私有(private)函数。如果你不指定可见性,编译器会抛出一个警告。最近solidity编译器进行了一些改进,如果用户忘记了对私有函数进行标记导致了外部可以调用私有函数,编译器会捕获这个问题。这里可以看到所有的可见性说明符。
8 b' y; k' a6 c( d7 A2 b0 e2 X2 E, f/ F5 [) o6 z/ D
    你也会在一些函数上看到一个修饰符view。它通常用来告诉编译器函数是只读的(也就是说,调用该函数,区块链状态并不会更新)。所有的修饰符都可以在这里看到。
1 R" `- ?) _8 N+ ]5 H/ F' T2 |& H# X& y( h
    编译智能合约
5 c) P& @6 e7 R' @/ m# e4 t4 r( c, b" [6 w
    我们将会使用上一节安装的solc库来编译代码。如果你还记得的话,之前我们提到过web3js是一个库,它能够让你通过RPC与区块链进行交互。我们将会在node控制台里用这个库部署合约,并与区块链进行交互。; W( O" a7 y* r0 k" ?
, m- ?" \# u4 B2 u" B
    首先,在终端中运行node进入node控制台,初始化web3对象,并向区块链查询获取所有的账户。
- u9 h( b; ~0 y1 F4 T
8 X+ }- n1 ]0 ?! W4 \" U1 V    确保与此同时ganache已经在另一个窗口中运行# P3 B8 H, T9 G8 [" O
4 D5 x0 J' P, _1 B) Y/ Z
    为了编译合约,先从Voting.sol中加载代码并绑定到一个string类型的变量,然后像下边这样对合约进行编译。/ r* ^3 _  X' y
$ I% }0 }: U& D' \
    $node8 t  x' b* C+ z5 ?5 F/ P4 V# }
) p2 Q3 D6 W" @! A
    Inthenodeconsole
2 K% s' A, r. n/ P( E9 W
& X' K/ j2 p* K  W1 A  r$ ~    >Web3=require('web3'), l  ]- r# D+ i9 o8 P7 d. x

9 k+ h$ y0 }' q+ m5 ^& m  V    >web3=newWeb3(newWeb3.providers.HttpProvider("http://localhost:8545"));
; F' E0 g7 C3 E( n1 ?' |& W
9 h. @- t: V" c4 U    >web3.eth.accounts
! W0 G+ o0 M8 B! t8 A; `$ P* [) {/ U9 N4 s: l. l4 h3 x5 b3 c8 k
    ['0x5c252a0c0475f9711b56ab160a1999729eccce97'
/ g  u  X/ \) T7 S$ @( T) H
( t% ], R: d: O0 A. I% D. B$ @7 z, h    '0x353d310bed379b2d1df3b727645e200997016ba3'7 E7 i+ G  y) h) K  O; `. C

+ k. j  I! l$ G" h    '0xa3ddc09b5e49d654a43e161cae3f865261cabd23'
  t% \4 J/ j7 k0 }6 l: u
- v) {  M7 v6 O. W2 D    '0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5'
, k% W+ h$ Z% y4 _
, R6 P$ N0 @# ~- b% v    '0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798'
5 h: \9 a7 r# U! j; r4 r* [! d/ x1 p) m- n$ t
    '0xda695959ff85f0581ca924e549567390a0034058'
% ^' m0 G( W4 j5 ]3 G/ O7 K& k: R7 K4 S+ _3 H
    '0xd4ee63452555a87048dcfe2a039208d113323790'8 p+ E: W3 a  C- n" @4 |
) Y! p8 ~/ S8 p, E1 r
    '0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14'- b" J' s8 j" ?4 D7 N9 D, V& J+ c2 s

6 _& `& N6 S, K4 a1 U. Y% i    '0xba7ec95286334e8634e89760fab8d2ec1226bf42'' Z' t& L8 A+ v+ y( j5 d7 K
' f1 G# L9 X1 k, [8 t; n
    '0x208e02303fe29be3698732e92ca32b88d80a2d36']- O! ~1 o& a- G# [% l; Y

+ F. D* G; @( p" s    >code=fs.readFileSync('Voting.sol').toString()% G# ?+ M- B" U' M7 z
, ~" \& D: ^, h
    >solc=require('solc')$ ]! `8 o, x9 @7 z' T/ R3 l1 z

/ B7 m% F7 d+ e4 J% O) u2 A7 h- a    >compiledCode=solc.compile(code)
: Z' i9 U% m( D3 r
$ }$ `+ R% v5 A+ V- `    当你成功地编译好合约,打印compiledCode对象(直接在node控制台输入compiledCode就可以看到内容),你会注意到有两个重要的字段,它们很重要,你必须要理解:0 y; A. Y0 V& l
' h" E% Z$ Q9 G, m& d$ q
    1.compiledCode.contracts[’:Voting’].bytecode:这就是Voting.sol编译好后的字节码。也是要部署到区块链上的代码。
/ T) T& A+ g" c5 o3 B9 w1 H9 `; \( d' [3 z/ c
    2.compiledCode.contracts[’:Voting’].interface:这是一个合约的接口或者说模板(叫做abi定义),它告诉了用户在这个合约里有哪些方法。在未来无论何时你想要跟任意一个合约进行交互,你都会需要这个abi定义。你可以在这里看到ABI的更多内容。
: U4 U5 ^$ X* Z/ R& }; Q- X# E  X3 @- n3 U0 P6 ^# W
    教程参考汇智网的DAPP开发入门教程,如果大家等不及博客更新,也可以直接访问这个以太坊教程。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

dancing520 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    1