Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文
本以太坊教程主要是介绍:搭建一个开发环境、编写编译一个智能合约。
  t9 H5 O; u% a! k) C# S+ _% T% Z; s" O
    以太坊是什么6 u  w' k% F$ e$ L4 L6 [# J

# r2 i: F* }2 ^/ ?# _2 P    以太坊(Ethereum)是一个开源的有智能合约功能的公共区块链平台。通过其专用加密货币以太币(Ether)提供去中心化的虚拟机(“以太虚拟机”EthereumVirtualMachine)来处理点对点合约。) R$ _" B! ?# w* F

4 L/ b; i; P& K3 }' c( v1 y    以太坊的概念首次在2013至2014年间由程序员VitalikButerin,受比特币启发后提出,大意为“下一代加密货币与去中心化应用平台”,在2014年通过ICO众筹得以开始发展。目前以太币是市值第二高的加密货币,仅次于比特币。
' l& `! F7 J" `- K( q
: K/ p& ^( W; i* Z. w0 k0 @    以太坊区块链是什么?9 y! L5 x0 |/ V1 d* \5 I
) M$ l5 J% X$ L/ v
    以太坊区块链有2个主要组件:
7 q. d1 r, Z; ]" F' Q* |. V( F" A$ k" d; T* \
    数据存储:网络中每笔交易都存储在区块链上。当你部署合约时,就是一笔交易。当你执行合约功能时,也是另一笔交易。所有的这些交易都是公开的,每个人都可以看到并进行验证。这个数据永远也无法篡改。为了确保网络中的所有节点都有着同一份数据拷贝,并且没有向区块链中写入任何的无效数据,以太坊使用一个叫做工作量证明的算法来保证网络安全。
/ X& u# ^3 r, X2 T+ \* i) w  c9 s/ J( H" i7 G3 v5 R
    代码:就数据的层面而言,区块链就是存储交易。在以太坊的世界里,你可以通过一个叫Solidity的语言编写逻辑/应用代码(也就是智能合约)。然后用solidity编译器将代码编译为以太坊字节码,并将字节码部署到区块链上(也有一些其他的语言可以写合约,不过solidity是到目前为止用得最多也是相对更容易的选择)。所以,以太坊不仅仅会存储交易数据,它还会存储和执行智能合约代码。' T9 Q& g7 P6 u) ?% U0 J
9 {7 n1 w  ?: P) ?* ~2 P( G
    可以简单的理解以太坊区块链的作用就是存储数据和代码,并在EVM(EthereumVirtualMachine,以太坊虚拟机)中执行代码。1 w0 ]- ^: D) p9 ]4 y

9 z6 _- \- K* U# R    要准备的基础知识
4 P. p( i! q/ g( n+ H' k
8 A3 P( ]9 |% l6 [4 [6 S. E4 @    为了进行以太坊开发,你应该对以下语言/技术有基本了解:
# o+ p4 O$ L' v9 ]" E: [8 D6 a6 g# K
    熟悉某种面向对象语言(如Python,Java,go)% u6 X9 X$ r0 X

6 c4 T! p- t% r    HTML/CSS/Javascript
4 ?& j: z. W' \
- `1 A/ d9 P3 ^' [    基本的命令行交互如Linuxshell命令& M7 d6 s) ]3 M' M
" o$ S% R5 f/ R$ F7 d* K/ ~- u+ e
    理解数据库的基本概念
: e# c, E, N0 p6 `: h, G( j8 C" W6 A
0 R0 U/ R) k7 d/ ?    为了构建以太坊去中心化应用即Dapp(Decentralizedapplication),以太坊有一个非常方便的JavaScript库即web3.js,你也可以在一些js框架中直接引入该库构建应用,比如react,angular,vue等。8 H! T* |1 O  Z. t

+ c  F4 }2 R9 h2 J/ K+ q& l' X    示例:一个以太坊投票应用
, u) d' _) c( L- D2 j
: F' i" i/ D9 l: x0 B) D    以太坊教程示例中,我们将会构建一个简单的去中心化投票应用。所谓去中心化应用,就是一个不只存在于某一中心化服务器上的应用。在网络中成百上千的电脑上,会运行着非常多的应用副本,这使得它几乎不可能出现宕机的情况。你将会构建一个投票应用,在这个应用中,你可以初始化参与选举的候选者,并对候选者投票,而这些投票将会被记录在区块链上。你将会经历编写投票合约,部署到区块链并与之交互的整个过程。你将会了解什么是一个合约,将合约部署到区块链上并与之交互意味着什么。& y0 z2 g, \: b) w
8 ?& m, [$ [) r  [/ s$ E' N- z
    本质上,区块链就像是一个分布式数据库,这个数据库维护了一个不断增长的记录链表。如果熟悉关系型数据库,你应该知道一张表里有很多行的数据。现在,对数据进行批(batch)量处理(比如每批100行),并将每个处理的批次相连。就可以形成一个区块链了!在区块链里,每个批次的数据就叫一个块(block),块里的每一行就叫一笔交易(transaction)。" J6 v+ r3 I+ L, p4 d
! L" h& k0 A& ^  ]: y3 ~1 T# D
    现在,你对以太坊已经有了基本了解,我们可以开始构建投票的dapp了。这将会加强你对以太坊的认识,并且初略了解以太坊的功能。. }4 g- K: ^' u0 {+ I" T" }/ e

" ^5 a3 _2 y, \7 `' M' E    以太坊开发环境搭建2 h- j' Z: T- t- k
1 m) v1 J; q- k  W4 D6 A  A! p
    Linux# c2 U, X% p/ A4 x8 R1 a* J
3 P9 ?  ~: B, U8 G& v5 U. ?- F  Z
    示例是Ubuntu16.04下的学习环境搭建,你只需要成功安装了nodejs和npm,就可以继续项目的下一步了。
$ m9 I! W; P" B8 [
, w* G2 b0 t0 N+ K" E    我们通过npm安装ganache和web3包来为以太坊教程提供支撑。我们也需要安装solc来编译合约。5 x$ S5 K  z( ^/ a6 s8 C
* ]: G5 f( _# S8 B: o) b
    下面是安装过程:3 _, X2 y5 l' X9 \0 e

8 ~- E% ?7 Z8 b( B    $sudoapt-getupdate- x8 P2 U! d& E5 L8 u

+ b9 q7 {4 b  E7 |1 I6 R    $curl-sLhttps://deb.nodesource.com/setup_7.x-onodesource_setup.sh
. n7 J2 @& ~" [. e6 Z  b
: @# c' [2 Q1 X2 |& ]    $sudobashnodesource_setup.sh: w5 g9 K" Z; d, _/ C
% ]" j' g! d& p/ f0 }
    $sudoapt-getinstallnodejs  y( H6 d8 z2 z  B7 s9 |- V9 M8 W

* P" M. C1 \$ L+ w9 T, v& ?- p    $node--version
: N4 {! D' l6 u' y4 H; d6 [) W  R8 [+ ~7 j8 {1 ~1 v
    v7.4.0  w6 T/ J- \  x" X$ U" [) a
' `& ]7 f; J) `$ P6 A$ r  a
    $npm--version
- d) p9 d, V( Z$ W0 V9 C  A5 D
( r" T" }8 R4 [! u1 F    4.0.5$ p  t& |: ~. E3 \, F
- X9 Q& ?! [( Z1 X
    $mkdir-pethereum_voting_dapp/chapter15 h, u4 ?+ |8 `8 I5 U5 P8 G

/ M9 w" T1 |5 O% l# {3 G4 I- J    $cdethereum_voting_dapp/chapter11 R% z1 {- a. D( R$ f! _. n, D7 P

* E# E! `  }& b5 ^0 b6 z1 W' D5 c    $npminstallganache-cliweb3@0.20.1solc
( c. o* O2 l5 y! Y3 I) a: a7 ~8 {& V% n" ]  b6 a( k. j
    $node_modules/.bin/ganache-cli7 S- e6 H. T0 A+ ], N; l
5 [* i* r7 K5 I2 q
    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到下面的输出。: r5 ^( Q7 ^% v+ D4 A9 A
, o+ u8 e& W  y; g$ y/ u) ^5 q
    GanacheCLIv6.0.3(ganache-core:2.0.2)
# A4 [  |% B, t- e& O; I' K9 Q
0 a5 l) J  ]. G4 s9 w    AvailableAccounts
6 T) g6 u3 A5 Z( a' D& S3 d1 @) m
1 D8 ]3 R* y8 W+ H8 F    ==================
5 w* V5 G: K2 U1 [2 x* A! a  s& ~7 R; U% f- I7 u
    (0)0x5c252a0c0475f9711b56ab160a1999729eccce97% m  Z9 F7 x6 }3 A. H6 j% n

0 A5 U* p, \  q0 y1 j# O3 {% C    (1)0x353d310bed379b2d1df3b727645e200997016ba3, [: S2 S/ z. G0 @/ Y% F! N
4 E$ R5 c2 o# F
    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23
3 ]7 z# p5 n8 ?# r2 ?
. E. C8 a* ~* X: J+ {8 I/ l) x    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec50 Z+ s) e  A8 b4 ]  g4 U  I

  E! f: m8 ^) x$ ]$ d+ h    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798! q, k4 ^1 P' e8 S; O/ a# }
# e) m# t" R- ]% L  X) Y. W
    (5)0xda695959ff85f0581ca924e549567390a0034058
1 d0 G. _5 o+ ]' m$ h+ A  w; r; S  z9 J9 N# f6 b# Z  n
    (6)0xd4ee63452555a87048dcfe2a039208d113323790) |2 D2 {, @" h, u

' L6 \- j: f% ]  }% m" P4 H( ?8 G8 E    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14
& |! c9 s; u; V; A& h/ a5 j' K2 E+ }+ ]0 R2 X
    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42, i# b. {6 Y2 c/ T' D
0 g/ j, q1 f3 H) B
    (9)0x208e02303fe29be3698732e92ca32b88d80a2d365 G3 P" {5 _  w' Z
; y% t9 {+ r; @9 a, `0 Z
    PrivateKeys
  R! B; m# Q! y- f/ }
1 |- X1 u- `1 n" f7 m4 |    ==================* l" l7 l. `9 l7 z) N$ @

1 {3 x5 i/ S, ^; a3 S; [. \    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b2 S; v+ W  \: q- D6 t

$ Y' {5 Q7 C$ A* B( M    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603
. O4 u- I; D! H8 y( R) L. U9 d1 ~9 K+ y6 u% U
    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99
( P) Z" {: k& c* G
8 i+ t" Z& l: d/ T3 Z& }$ G. ]    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430
5 d+ v: J9 o8 d* V
( g: g( i) \0 z5 n5 R; y" I    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8
) X5 o' U5 o: X  y
( v- e0 p/ u& a7 `    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc$ I& d( V- @* V7 M
( g3 f1 A2 }. M1 Z  p& T
    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a95 K/ ?/ X; t/ G2 F2 S& k
6 k, s% Q* q1 K6 Z# T
    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d' D) H( ]6 {9 B: R+ I" H, E+ U
* x) T6 Z$ k6 v7 k( p- o% t
    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
4 Q3 y' ]: ]) a8 t7 j9 K4 ?) Q2 e0 I' E! m
    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0
# B" w. ~  `( c
3 k+ I9 `5 b1 A  e& K    HDWallet  t( ]) _! `; G. _) j( }8 @5 s# I  D

, _7 j0 Y, ~& q' V    ==================
; Z! A; |+ V) i
' p# u8 v' i. X1 A. N    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella5 t# t; _' h4 \8 E3 e3 |/ {0 W

) k3 ]  R, M* {1 J# W5 ?    BaseHDPath:m/44'/60'/0'/0/{account_index}
; }3 e6 G) O& t0 C, E  U* |4 n
, V  ~% U8 v, h7 X    Listeningonlocalhost:85456 y+ i' M! v; Q

9 u; }: U* Y- g) M$ G: ?    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。
; x( K: c' @0 L- D4 p! k7 C2 i2 l
5 S) ~+ Y( n3 J( n8 R, [# {    MacOS0 p% ^. `6 e# S3 d' I# ?2 T) j
) p2 x* |' D" {: l7 J, J4 K
    如果你还没有安装homebrew,请按照https://brew.sh/的指示安装homebrew。homebrew是一个包管理器,它可以帮助我们安装开发所需的所有其他软件。按照下面的指示安装所有其他所需的包。+ x* L) N$ V# H. b, O9 {1 Q4 g
# c$ u- o! A1 e" B# B5 w
    $brewupdate
  d6 d3 i  L- p1 F$ S! o3 z4 l" x8 q, M9 U( {- @* x% b% y( a
    $brewinstallnodejs
5 j" }8 P; N: N/ e: ]  c# W4 Y3 m! }; }$ X
    $node--version/ h4 Z; S& l* a7 ?7 L# D
6 `6 s( K$ Y: y
    v7.10.0) T" |/ E% Z) n  X. l
1 I5 ?( V; w6 ?
    $npm--version
* F$ ]8 O8 t4 F( Q& \8 ]( p+ }
& `8 T6 k8 \! G0 k) X; z6 I9 O    4.2.0* C* u4 s" a# i/ y5 [/ S
8 A: ~" j! |3 G- x) o- ~
    $mkdir-pethereum_voting_dapp/chapter1% D& K- X. t" H) U0 G3 t
& [3 N% O* X9 Z3 a
    $cdethereum_voting_dapp/chapter1
, l/ p. y! A1 B' e; s; h  {$ J" w; k5 i. E5 |
    $npminstallganache-cliweb3@0.20.1solc8 p7 F; C3 m3 f1 S5 y( A4 k

' W$ ^+ F" W  U/ ?. k% I: k5 j    $node_modules/.bin/ganache-cli
7 h. n% F5 {% d) |+ t# f* I% U7 W  {0 @5 [
    我们通过npm安装ganache和web3包。我们也需要安装solc来编译合约。
4 k+ z8 {" v  h+ m7 E8 R, j+ o7 F, A. I0 r0 c" l1 h
    如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到右图所示的输出。& ~( Y) @# o, d5 c/ l" ?4 v. O
2 v1 ^  b  T& s9 h7 O
    GanacheCLIv6.0.3(ganache-core:2.0.2)
1 \9 j+ l' ^5 Q, k9 g% ]! w
# q* j* c2 x, I; s    AvailableAccounts
5 b* `2 |) B  H" H0 T
0 i3 Q0 ?8 m+ ?4 l5 A    ==================
' g0 s: ]% b4 x4 L; ^
: f5 w1 Z7 b2 w: [6 J    (0)0x5c252a0c0475f9711b56ab160a1999729eccce97/ d+ U% w+ S0 M

8 q( z/ j. g5 S- O    (1)0x353d310bed379b2d1df3b727645e200997016ba3
) `- R$ J0 J0 q% ?! Q
2 L6 U% j; o  A- {, ?8 y    (2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23% ^% G  h+ h3 O4 x3 m: d) D
0 S. v5 m, ^- Y9 r. s. R
    (3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5$ D5 c9 p0 h8 F3 V* I8 W  i

/ d6 \4 V# d: R4 x! Q/ Z* K' ]    (4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd27984 m7 i1 x0 ^' d; b' O1 I' @# [8 X6 c/ f
) P/ K7 K( V; X# w. c3 L5 G& ~$ s9 T0 a
    (5)0xda695959ff85f0581ca924e549567390a00340586 q2 [0 I' g, k+ {

1 e! K$ W: s) y- F$ U    (6)0xd4ee63452555a87048dcfe2a039208d113323790
. ]* L( [6 A8 |7 [* V% @; q; t& G5 ?& y  }# T
    (7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d142 T& r0 S' l/ H" L, k1 P- ~
+ L# G$ `" S, ~, H' C
    (8)0xba7ec95286334e8634e89760fab8d2ec1226bf42
4 M' e, {  t( o4 H4 A, t" f; _, y: K" Y& F8 W
    (9)0x208e02303fe29be3698732e92ca32b88d80a2d36* v0 x' `; I( B  j: Z

2 r" ^1 x6 h% U) `! S9 {) v+ v4 V3 h    PrivateKeys) a+ S- X" f0 j! s. b& n: N9 Z( i
( \# P4 F1 x: {& d( G6 I
    ==================
# d  [- c+ e7 c; ]& R
. N" K- S/ k( }    (0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b) ]; h; c( q! g' O5 j5 i

3 H( M/ U. |, A; p% B$ i4 L4 V    (1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603
$ R; W& q1 C  h2 J, @( X& X6 C5 W% v( ^9 J# A8 `/ E0 ^! ~
    (2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99& M9 j: _& |* q, Y5 ~" N5 @
) |* D6 F7 n( P6 J5 c- ?- y& z+ }; v
    (3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430
% t+ B) i3 f7 k( x9 I% n4 m3 r( x. p/ I! T* o1 M# t
    (4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8: r- \& o' ^/ M: v# I7 f
) {5 k8 m# H5 J/ c
    (5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc( y: h2 |/ m: W# L% d8 p
  o' B: |% H: V
    (6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9
! Z7 p7 R, C- n4 w
, G! Q7 t8 r3 n    (7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d
' Y( \% L8 r. d$ k  ^- I/ @' H4 {, v+ v
    (8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
( |! D- V5 D  ^% ^- a$ G
( t! }4 d. _# N0 f/ Z2 e. m( A    (9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f05 f) _: O$ ]+ X% F* \; q

6 V; V9 V" o) N6 L. Z% w$ Y$ ?: M    HDWallet
2 I6 b. w: J% R. m0 k5 x+ @4 Q3 |& P8 U
    ==================# T  l6 m) h) D' G
9 Y% U, `: a, A/ _
    Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella
. {2 N, Y. d* {% {
# q# U. y2 |1 ?" \1 w6 }( f; K. n$ F    BaseHDPath:m/44'/60'/0'/0/{account_index}
, {  z; j0 p1 E# Q- {& a8 `' h( O* Y: [2 i1 l% |* Y+ Y& _9 H
    Listeningonlocalhost:8545/ l; @4 c* g7 n! E* B
0 C( r# `8 t5 o* u& }. |; Z0 r
    为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是以太坊账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。5 u8 @5 F: S4 C& J- n( m4 X1 b3 m1 [
& l7 ?; S0 y2 `% z5 J! X5 E
    Windows: D4 d5 m0 v9 P- }) N# p

1 z' F" }" g  H: h# A& H, _* o    安装VisualStudioCommunityEdition。如果你选择定制安装,那么至少应该安装VisualC++(目前的版本是VS2017)3 _. f. E: S( y$ f9 i) }
& B* B6 s8 D% P+ K  G( |. s
    安装WindowsSDKforWindows
6 l1 a6 ?: B8 w( ?% P  }# H
2 ?# W8 M  l8 |( E    安装Python2.7如果你还没有安装的话,并且确保将它加入到环境变量PATH
* h9 f0 i/ o: p/ v2 P, G. n% {9 f5 K2 r# O5 p
    安装git如果你还没有安装并加入到PATH" ~8 N7 Z% j- a4 S* S
: A8 R6 \! P. u' b0 {8 S
    安装OpenSSL。确保选择了正确的安装包,并且只安装完整版(而不是轻装版)。你必须将OpenSSL安装到推荐安装的位置–不要改变安装路径$ T7 a! r- H# T5 w0 ~8 M) g: o

* B! q7 t9 z! @    下载和安装nodev8.1.2。不推荐使用版本v6.11.0搭配VS20171 o! P, H$ ^  h! d7 \
, b+ T) F0 f" j) L! q
    执行命令npminstallganache-cliweb3@0.20.1solc
$ [7 Q8 P( u( T. e
. j/ Y$ U7 p4 N    SolidityContracts& X" W" c6 G' L5 }# O/ B
5 R; w: L) I( F4 V& O8 R
    现在已经安装好ganache并运行,我们将会开始编写第一个以太坊智能合约。
2 y; [2 L. {" \: k; W
# _; j% i: o; v6 D    我们会使用solidity编程语言来编写合约。如果你熟悉面向对象编程,学习用solidity写合约应该非常简单。我们会写一个叫做Voting的合约(可以把合约看成是面对对象编程语言的一个类),这个合约有以下内容:
% [3 @+ V6 n3 \  R# ^& Q  D  L) a* J
    一个构造函数,用来初始化一些候选者。
0 P- h1 M  I9 `8 f" ~: C" r% m, q0 a2 N9 x8 b) [, f, o
    一个用来投票的方法(对投票数加1)
0 x7 h$ L2 P  Z. D
: l6 @: @# m7 P) c4 [* E( n# {    一个返回候选者所获得的总票数的方法0 h& A* m6 U  X. Q" q' X1 G+ K

7 G: Z, U/ K3 G( h: F  m+ y    当你把合约部署到区块链的时候,就会调用构造函数,并只调用一次。与web世界里每次部署代码都会覆盖旧代码不同,在区块链上部署的合约是不可改变的,也就是说,如果你更新合约并再次部署,旧的合约仍然会在区块链上存在,并且数据仍在。新的部署将会创建合约的一个新的实例。* H6 O0 r: X1 o5 ~9 c
1 A2 d- B9 P  N# o% f* A
    pragmasolidity^0.4.18;" C' a  Y- i# r& G, v
  ]& }0 J1 I+ m7 p
    contractVoting{' [2 N3 @1 x+ p) \6 r" g
+ Z- _. m4 ^& T, P
    mapping(bytes32=>uint8)publicvotesReceived;
  c3 R5 w4 g+ H' B
4 \) x9 M9 I# E: E9 Q* i    bytes32[]publiccandidateList;. P  B% f4 {/ d+ T

8 M% q" \$ k2 k2 ~, k5 ^. a    functionVoting(bytes32[]candidateNames)public{
  i2 y* l+ ~0 s, R. X
- z) I8 g/ K+ _$ [0 a    candidateList=candidateNames;
4 q2 A8 O& S; h" y. b% [5 \$ A1 g9 A; l# k) S6 e, d: q3 ~4 b! h$ E8 O& U
    }
7 p% `! }  D7 `0 ]+ v- V: s6 l
8 `5 L9 a2 p1 ~. J/ g, o; k; x" H" q    functiontotalVotesFor(bytes32candidate)viewpublicreturns(uint8){
5 F* R( C" C( b5 Z4 E8 Q1 ?# U
( h# Y& r. \7 l* t    require(validCandidate(candidate));, T0 J7 N! N3 R1 A. @1 u
2 B4 F1 G5 _: y8 m$ g
    returnvotesReceived[candidate];& j+ S4 s: k& L3 r

5 F; I# z+ T) g7 y. U    }
# v! u0 s" O8 O. Q# T7 U3 @- w" U! c0 D  Y! g% {5 F# C! m
    functionvoteForCandidate(bytes32candidate)public{- p; m! X7 G  X9 f

' K9 q6 [& `0 w. h8 R9 ?    require(validCandidate(candidate));
5 Z& }8 C9 J' _
0 l' J. ?0 S2 B0 `, K    votesReceived[candidate]+=1;5 ^. h7 F  [4 h7 N+ e9 L

0 |: n, ~/ i" O+ f/ O9 j. E    }% a( X, S4 Z5 ~$ w

4 F: |. X% f& v: l$ R4 p0 Z; J    functionvalidCandidate(bytes32candidate)viewpublicreturns(bool){/ {0 R1 T  I- a5 |

- X1 a9 f) Q7 |6 C" B3 M4 H    for(uinti=0;i2 @9 m+ Y  u; M' k1 k

2 p; s5 h, F0 l& v2 B( d    将右侧代码拷贝到一个叫做Voting.sol的文件中,并保存到chapter1目录下面。# [# p. Z5 s* @

) D4 H/ q4 Z! s1 J1 J    代码和解释
, J2 ~4 A. A7 b+ p6 I9 m1 H  ^- |+ p' ~5 {* T" r4 A( Y; E
    Line1.我们必须指定代码将会哪个版本的编译器进行编译
& |9 ^$ L- o) T; Q6 [- r- g
  s6 T8 O3 [5 `    Line3.mapping相当于一个关联数组或者是字典,是一个键值对。mappingvotesReceived的键是候选者的名字,类型为bytes32。mapping的值是一个未赋值的整型,存储的是投票数。( t! W9 q& j  W& c( A

7 D) @8 t  ?- u; Y. D7 e+ ^2 d    Line4.在很多编程语言中,仅仅通过votesReceived.keys就可以获取所有的候选者姓名。但是,但是在solidity中没有这样的方法,所以我们必须单独管理一个候选者数组candidateList。
- a7 f7 K' a; w6 r; e' d; O- L) n& a
    Line14.注意到votesReceived[key]有一个默认值0,所以你不需要将其初始化为0,直接加1即可。
2 \! ^9 N# S/ m
: P' V$ i8 Q; ?2 {; l    你也会注意到每个函数有个可见性说明符(visibilityspecifier)(比如本例中的public)。这意味着,函数可以从合约外调用。如果你不想要其他任何人调用这个函数,你可以把它设置为私有(private)函数。如果你不指定可见性,编译器会抛出一个警告。最近solidity编译器进行了一些改进,如果用户忘记了对私有函数进行标记导致了外部可以调用私有函数,编译器会捕获这个问题。这里可以看到所有的可见性说明符。
" C! [+ Y5 C5 {" [) d( N* k1 `
( n9 b2 J$ v' K; r    你也会在一些函数上看到一个修饰符view。它通常用来告诉编译器函数是只读的(也就是说,调用该函数,区块链状态并不会更新)。所有的修饰符都可以在这里看到。
5 t, ~; ?4 P0 e4 u2 u) Q5 z5 j! [& D5 T- k' W( i" J/ O
    编译智能合约2 M5 t( G6 o3 h" ]6 c
- p$ w$ p& \; J: ~. ~5 t: i
    我们将会使用上一节安装的solc库来编译代码。如果你还记得的话,之前我们提到过web3js是一个库,它能够让你通过RPC与区块链进行交互。我们将会在node控制台里用这个库部署合约,并与区块链进行交互。$ r+ c, i' [8 L$ O& g

  ?5 {- W  c- N: }4 x2 f    首先,在终端中运行node进入node控制台,初始化web3对象,并向区块链查询获取所有的账户。; U+ N0 n/ E% M. U  o0 J( n8 E& l

# E# f2 u, u) F    确保与此同时ganache已经在另一个窗口中运行
( S* `: y4 k4 R% j
1 {( N  ?; q4 J; A    为了编译合约,先从Voting.sol中加载代码并绑定到一个string类型的变量,然后像下边这样对合约进行编译。
. v' y) r, _2 a1 g9 |4 f7 O: w* y% c# T! ]! E3 t3 V& Y8 y
    $node
- H. A3 J+ U6 v+ w$ C' v' ~
) L( I  V& w- o8 V+ v0 i' y    Inthenodeconsole
3 z! T# O; [5 V! h
5 k* O+ {$ g7 R; {; w8 `9 k    >Web3=require('web3')
, J& k, _! E" ]) w2 t2 Q1 y; q! H; W* S- J! C4 c! l$ @" Y8 q" O6 f% z
    >web3=newWeb3(newWeb3.providers.HttpProvider("http://localhost:8545"));
1 Z& V, ~. F6 `2 I3 S3 a" w: U3 ~8 [; _; w- b/ x
    >web3.eth.accounts
+ i+ B! D! R6 ]* _" S' e8 d- X" K" X5 R' p
    ['0x5c252a0c0475f9711b56ab160a1999729eccce97'% g  ?6 y! K' J: W9 C

- g% @  c; l+ i; S0 A* {5 i  M    '0x353d310bed379b2d1df3b727645e200997016ba3'1 Y+ q- Y' ~8 U

4 z& S3 I* N$ F7 C9 S    '0xa3ddc09b5e49d654a43e161cae3f865261cabd23'- O5 R& u+ m4 o/ J
; d. L, q4 a* I" U: @0 V! F; j. [. e
    '0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5'
2 S1 \) ]( w. }$ d) n
: g, h" r$ a4 V1 ]) j& M    '0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798'
% d' f' F# `  x3 g% h6 o
$ I% R+ X  x/ A/ t    '0xda695959ff85f0581ca924e549567390a0034058'
( \7 _/ E# _& w2 e3 ]* n+ t8 {( A! l9 x: d/ h
    '0xd4ee63452555a87048dcfe2a039208d113323790'
, Q3 I' ]. z1 o
( ]5 ~; ?" h1 R) n( Z2 u    '0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14'
1 S' W0 n: k; F* R8 |) \2 Z+ d/ n5 [6 G1 K5 o3 v
    '0xba7ec95286334e8634e89760fab8d2ec1226bf42'" o- L+ z) a$ O+ q6 L$ v
% Z; U4 ^9 U) P  J
    '0x208e02303fe29be3698732e92ca32b88d80a2d36']
1 ]2 u& K6 n6 j2 x+ s1 H% K- y* m$ ^% S; F- B- M5 k  M. n
    >code=fs.readFileSync('Voting.sol').toString()
- s9 M$ i6 M8 T. s5 P$ u  U3 \1 q( T1 x$ g5 p! h  D
    >solc=require('solc')
8 {3 d; B7 Z0 Z" }, Y7 o8 q+ _/ R' Y; ~% W5 N: i# X2 g7 S
    >compiledCode=solc.compile(code)& a5 ?+ i" {; k
5 V8 h6 Y' Y1 r$ v6 w2 r
    当你成功地编译好合约,打印compiledCode对象(直接在node控制台输入compiledCode就可以看到内容),你会注意到有两个重要的字段,它们很重要,你必须要理解:6 V. m6 g/ Y) w4 a4 Q
( R8 u9 a; P' R7 s8 @: ^
    1.compiledCode.contracts[’:Voting’].bytecode:这就是Voting.sol编译好后的字节码。也是要部署到区块链上的代码。( c4 S+ C! c  k, @4 V

( \' l5 b* H9 s    2.compiledCode.contracts[’:Voting’].interface:这是一个合约的接口或者说模板(叫做abi定义),它告诉了用户在这个合约里有哪些方法。在未来无论何时你想要跟任意一个合约进行交互,你都会需要这个abi定义。你可以在这里看到ABI的更多内容。) }. R( D, y" l- s% h& @

6 ?9 A/ z4 _. X$ ~; x% L    教程参考汇智网的DAPP开发入门教程,如果大家等不及博客更新,也可以直接访问这个以太坊教程。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

dancing520 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    1