以太坊教程:搭建环境、编写编译一个智能合约
dancing520
发表于 2022-11-6 21:10:54
711
0
0
以太坊是什么
/ a: U- o, X" B* V, u' R! C$ t5 Q
以太坊(Ethereum)是一个开源的有智能合约功能的公共区块链平台。通过其专用加密货币以太币(Ether)提供去中心化的虚拟机(“以太虚拟机”EthereumVirtualMachine)来处理点对点合约。* s3 S7 f8 X% a; {; h6 ~
以太坊的概念首次在2013至2014年间由程序员VitalikButerin,受比特币启发后提出,大意为“下一代加密货币与去中心化应用平台”,在2014年通过ICO众筹得以开始发展。目前以太币是市值第二高的加密货币,仅次于比特币。
以太坊区块链是什么?
1 Z, z# P, }; w3 Q: h
以太坊区块链有2个主要组件:* y& p" G' x# Z: @9 e
( ]& q p& m* ]: t3 ?' X0 t
数据存储:网络中每笔交易都存储在区块链上。当你部署合约时,就是一笔交易。当你执行合约功能时,也是另一笔交易。所有的这些交易都是公开的,每个人都可以看到并进行验证。这个数据永远也无法篡改。为了确保网络中的所有节点都有着同一份数据拷贝,并且没有向区块链中写入任何的无效数据,以太坊使用一个叫做工作量证明的算法来保证网络安全。, x1 h9 I* c3 ^) u% M
代码:就数据的层面而言,区块链就是存储交易。在以太坊的世界里,你可以通过一个叫Solidity的语言编写逻辑/应用代码(也就是智能合约)。然后用solidity编译器将代码编译为以太坊字节码,并将字节码部署到区块链上(也有一些其他的语言可以写合约,不过solidity是到目前为止用得最多也是相对更容易的选择)。所以,以太坊不仅仅会存储交易数据,它还会存储和执行智能合约代码。; t7 _) Q m/ A3 G3 P F+ i
可以简单的理解以太坊区块链的作用就是存储数据和代码,并在EVM(EthereumVirtualMachine,以太坊虚拟机)中执行代码。
要准备的基础知识
为了进行以太坊开发,你应该对以下语言/技术有基本了解:
0 G1 }* Z) u, B6 p' b
熟悉某种面向对象语言(如Python,Java,go)
& B9 J1 M9 @6 }# ]
HTML/CSS/Javascript
基本的命令行交互如Linuxshell命令
理解数据库的基本概念
为了构建以太坊去中心化应用即Dapp(Decentralizedapplication),以太坊有一个非常方便的JavaScript库即web3.js,你也可以在一些js框架中直接引入该库构建应用,比如react,angular,vue等。4 Q& n1 Q3 F8 ?
; D. ]# k8 V+ v7 O: Y6 `
示例:一个以太坊投票应用
以太坊教程示例中,我们将会构建一个简单的去中心化投票应用。所谓去中心化应用,就是一个不只存在于某一中心化服务器上的应用。在网络中成百上千的电脑上,会运行着非常多的应用副本,这使得它几乎不可能出现宕机的情况。你将会构建一个投票应用,在这个应用中,你可以初始化参与选举的候选者,并对候选者投票,而这些投票将会被记录在区块链上。你将会经历编写投票合约,部署到区块链并与之交互的整个过程。你将会了解什么是一个合约,将合约部署到区块链上并与之交互意味着什么。
! M8 J- @1 W/ ~' w& e
本质上,区块链就像是一个分布式数据库,这个数据库维护了一个不断增长的记录链表。如果熟悉关系型数据库,你应该知道一张表里有很多行的数据。现在,对数据进行批(batch)量处理(比如每批100行),并将每个处理的批次相连。就可以形成一个区块链了!在区块链里,每个批次的数据就叫一个块(block),块里的每一行就叫一笔交易(transaction)。
现在,你对以太坊已经有了基本了解,我们可以开始构建投票的dapp了。这将会加强你对以太坊的认识,并且初略了解以太坊的功能。( I; J: p4 v. T% |
以太坊开发环境搭建
Linux# C/ ] m) {( t7 V
: ^6 r- E0 ~+ {2 U8 _3 M" c
示例是Ubuntu16.04下的学习环境搭建,你只需要成功安装了nodejs和npm,就可以继续项目的下一步了。4 t9 u5 N5 k3 R* d1 M, I; y a! C9 o/ w8 t
我们通过npm安装ganache和web3包来为以太坊教程提供支撑。我们也需要安装solc来编译合约。9 P5 A* p' Y, r
下面是安装过程:8 X. E+ \" `2 Y) R
$sudoapt-getupdate% W( b# w& K8 o* ]0 Z: t
$curl-sLhttps://deb.nodesource.com/setup_7.x-onodesource_setup.sh
$sudobashnodesource_setup.sh, m/ V0 X* {& h/ y
$sudoapt-getinstallnodejs
$node--version: R+ i b; x! h) m8 ~; @ Z
v7.4.0
1 }# ^0 g0 ?7 I, t
$npm--version
4.0.5
3 I0 | z7 E" S7 B+ ]( X
$mkdir-pethereum_voting_dapp/chapter1# f, b; z, y5 M
' k' w/ e2 z8 I
$cdethereum_voting_dapp/chapter1
- d# T( \$ `% I& m& g7 J
$npminstallganache-cliweb3@0.20.1solc7 k3 r( @: }4 z4 c$ B4 o% V X/ @" ?9 w
$node_modules/.bin/ganache-cli
如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到下面的输出。
GanacheCLIv6.0.3(ganache-core:2.0.2)
: k' a9 N8 s3 @* R t! v/ R
AvailableAccounts
==================% l. M5 G* X3 b3 _4 ~3 b8 {- {" a
: k P% D' W0 a7 d; i
(0)0x5c252a0c0475f9711b56ab160a1999729eccce97
(1)0x353d310bed379b2d1df3b727645e200997016ba39 A$ u: K' n5 e) B- k
l' P2 K9 q, W' L" I
(2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23$ b& q6 P; c# V6 B) d' ]0 Y
0 G7 Z( H& n' W- k: Z
(3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5
(4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798
8 ^8 S3 V* r; y
(5)0xda695959ff85f0581ca924e549567390a0034058
d! j) f4 l% g5 [8 `* A/ R
(6)0xd4ee63452555a87048dcfe2a039208d1133237902 e0 J3 o5 W8 {* H8 D$ G3 P
(7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14
! h0 F+ r; j/ A5 p! S g
(8)0xba7ec95286334e8634e89760fab8d2ec1226bf42
(9)0x208e02303fe29be3698732e92ca32b88d80a2d36: f4 s# b j: E1 X
9 |0 e* t4 m a7 T% V
PrivateKeys
==================; p. r0 s i$ U6 D( `0 @" B0 U- s
(0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b, W' ?% S+ y2 b5 e
, E9 {% w* c, q$ ~- P5 R
(1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603! @8 h8 O8 Z5 {+ b
(2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99
(3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430
% l6 {" B3 i# x6 P3 |" j7 e
(4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8, h3 Y2 @# \ V; B
(5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc- G% `9 C/ T% S
3 a6 W* U _ `0 R1 \) f
(6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9* w" J% n9 i$ m' v, ~
, h# G) J1 M- H$ \' R7 F: O/ ^
(7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d
(8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
c' T9 [' z# b" W1 R( C
(9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0
% q* }/ L! {& J$ T5 E
HDWallet' W6 w/ ?: K* c$ S7 J: w! s
+ K% d/ R/ B, b/ R5 L) h& A- V/ A
==================! L! P4 W( I* t
Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella& r7 c( z0 U6 g( M0 f: K5 ^
+ H4 w1 Z) N8 J5 R
BaseHDPath:m/44'/60'/0'/0/{account_index}! p) E0 K8 s0 |4 M y/ S# O
8 r, F+ T8 d e6 O8 ~# [' a9 M
Listeningonlocalhost:85452 _) w1 n) _! z* L/ t
为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。
MacOS
" ]; I: p& Z% t( }; ~
如果你还没有安装homebrew,请按照https://brew.sh/的指示安装homebrew。homebrew是一个包管理器,它可以帮助我们安装开发所需的所有其他软件。按照下面的指示安装所有其他所需的包。$ I1 J1 n4 Q4 f1 k" O+ R: L$ K
$brewupdate0 R! m5 L7 Z: D) l. c. L
[9 H2 d& d {- |
$brewinstallnodejs3 t0 P' t3 j7 a0 p+ C
$node--version9 T, i/ t4 I6 c( \
. \5 z. @+ d2 U( i x
v7.10.0
$npm--version
5 M# M- D. f4 l, t! G
4.2.0& ?1 G7 N% N! B% `& i
$mkdir-pethereum_voting_dapp/chapter1
$cdethereum_voting_dapp/chapter1
$npminstallganache-cliweb3@0.20.1solc
$node_modules/.bin/ganache-cli
我们通过npm安装ganache和web3包。我们也需要安装solc来编译合约。, Q) j- E1 Q( s* ]( X5 ~" [
如果安装成功,运行命令node_modules/.bin/ganache-cli,应该能够看到右图所示的输出。0 B! j" t# ?; E$ N, q* v5 Y
GanacheCLIv6.0.3(ganache-core:2.0.2)3 P$ b- ?0 p/ s) J. e- f
* E" M8 q- @& I& t
AvailableAccounts
==================
1 G2 v0 D% F6 _6 x! p7 X2 {6 @
(0)0x5c252a0c0475f9711b56ab160a1999729eccce97
% Z+ y$ }* b6 K+ v2 U7 k; U
(1)0x353d310bed379b2d1df3b727645e200997016ba3* S) {* m- D. d: r& e$ m
(2)0xa3ddc09b5e49d654a43e161cae3f865261cabd23
. V" y" o! i( `1 D% f
(3)0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5- I$ M" @' t$ z4 Z% U
2 t, u9 U; F+ f3 T: ~
(4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798
(5)0xda695959ff85f0581ca924e549567390a0034058
(6)0xd4ee63452555a87048dcfe2a039208d113323790
( l k4 F' f, j8 A* k' ]; J
(7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14
(8)0xba7ec95286334e8634e89760fab8d2ec1226bf42& J& `, A5 E, }) d" K2 c
(9)0x208e02303fe29be3698732e92ca32b88d80a2d36; f% D, e7 \6 X; h$ j& Q
+ d# s& ~+ z* l/ s- N0 y
PrivateKeys
1 @1 o9 v% b8 C3 [! Y% C1 D9 G# Q( I
==================
(0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b* L% v& z5 k: C
9 {( |3 v+ V( K: A* W! o5 R: H
(1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603
* p0 [ y# Z$ U; B' r; G
(2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99
$ X5 T' \8 ]) B8 s% Y, m; e
(3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430
(4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8
0 g0 w& \) |6 p5 w7 R) C9 _
(5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc4 Q: E5 ?' h5 `0 Q- i6 w1 e
, U# o0 R- h9 a* q8 c9 a
(6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9
0 P7 L6 ]9 v) L$ g% _
(7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d1 R0 J, N3 A7 y9 f$ x! t
(8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a3 L. N; [) O' b! Q
(9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0( D: G4 D) W* p7 ]! n" r
HDWallet
==================7 ^+ J# }8 i' e" A$ u
7 T( M9 b- }' h$ v1 _6 s8 v8 G1 ~) M
Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella
BaseHDPath:m/44'/60'/0'/0/{account_index}# a: E M) _; ^) B
Listeningonlocalhost:8545
为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是以太坊账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。) T5 O4 n- J5 w6 M2 g- i
Windows
' O) w4 x) \* k. [) n
安装VisualStudioCommunityEdition。如果你选择定制安装,那么至少应该安装VisualC++(目前的版本是VS2017)2 o. m4 f0 `4 p5 Q, ?: \% X3 e: @
. f9 T8 d3 a7 v8 ~
安装WindowsSDKforWindows' D# R, r" u% v
安装Python2.7如果你还没有安装的话,并且确保将它加入到环境变量PATH
; ~5 \0 a( O- |; I* z
安装git如果你还没有安装并加入到PATH) S/ I: S! {/ d9 Z
) J: F3 d' m, W$ Y: y
安装OpenSSL。确保选择了正确的安装包,并且只安装完整版(而不是轻装版)。你必须将OpenSSL安装到推荐安装的位置–不要改变安装路径9 u0 e8 P- f" P6 p2 _. L
下载和安装nodev8.1.2。不推荐使用版本v6.11.0搭配VS2017
执行命令npminstallganache-cliweb3@0.20.1solc
. s) I% g Y0 l; ^& W Q# H
SolidityContracts
( t0 X9 t, i$ H' A3 Q
现在已经安装好ganache并运行,我们将会开始编写第一个以太坊智能合约。
我们会使用solidity编程语言来编写合约。如果你熟悉面向对象编程,学习用solidity写合约应该非常简单。我们会写一个叫做Voting的合约(可以把合约看成是面对对象编程语言的一个类),这个合约有以下内容:
一个构造函数,用来初始化一些候选者。
/ z3 u$ K) p; R8 \1 c
一个用来投票的方法(对投票数加1)
& Q( U' o: B' W* R7 h" l/ D
一个返回候选者所获得的总票数的方法
当你把合约部署到区块链的时候,就会调用构造函数,并只调用一次。与web世界里每次部署代码都会覆盖旧代码不同,在区块链上部署的合约是不可改变的,也就是说,如果你更新合约并再次部署,旧的合约仍然会在区块链上存在,并且数据仍在。新的部署将会创建合约的一个新的实例。
pragmasolidity^0.4.18; D3 e* q' s# Y, R9 d
contractVoting{
mapping(bytes32=>uint8)publicvotesReceived;
+ j* D9 F* G5 h
bytes32[]publiccandidateList;( \% P" C; [1 T& Y+ j
functionVoting(bytes32[]candidateNames)public{
; F7 n0 s8 k) F5 W- T) ]& [
candidateList=candidateNames;; T4 U# d5 Z) H* i/ \7 @' d
# u& s' ?# U4 y% f! y
}: C4 I- N. c+ O, ]) S
2 y# Y" ]$ Q5 \
functiontotalVotesFor(bytes32candidate)viewpublicreturns(uint8){
require(validCandidate(candidate));& G# e1 z0 J' h4 N+ \: h# ?
returnvotesReceived[candidate];/ R g) q8 e% `- k& h) P6 f5 k
}5 w4 t0 c0 Y5 f! s4 u7 Q
functionvoteForCandidate(bytes32candidate)public{% \8 q4 a7 x* o/ |0 \* H# B1 k
require(validCandidate(candidate));
votesReceived[candidate]+=1;2 f! c; a. g) P1 c' l+ s, }
}
' {; j6 L) j0 D1 c! ? u; f
functionvalidCandidate(bytes32candidate)viewpublicreturns(bool){3 _* Y5 g! ]7 ]4 @9 F) A
for(uinti=0;i
% R3 G# v* {- H6 V% U1 p
将右侧代码拷贝到一个叫做Voting.sol的文件中,并保存到chapter1目录下面。& L4 {3 O6 a# `5 K
代码和解释
5 {6 c3 Q1 D7 i7 l. X
Line1.我们必须指定代码将会哪个版本的编译器进行编译* Y# Q6 m6 `' B* Z ~! N
1 K( T/ p2 _& F- E( S
Line3.mapping相当于一个关联数组或者是字典,是一个键值对。mappingvotesReceived的键是候选者的名字,类型为bytes32。mapping的值是一个未赋值的整型,存储的是投票数。6 z+ `( [1 u* X5 @+ L. u# v
" J3 W! a- _! K3 v
Line4.在很多编程语言中,仅仅通过votesReceived.keys就可以获取所有的候选者姓名。但是,但是在solidity中没有这样的方法,所以我们必须单独管理一个候选者数组candidateList。
) s) D- L* H) ?7 f# {, x
Line14.注意到votesReceived[key]有一个默认值0,所以你不需要将其初始化为0,直接加1即可。: R! C1 z) T) S, k
你也会注意到每个函数有个可见性说明符(visibilityspecifier)(比如本例中的public)。这意味着,函数可以从合约外调用。如果你不想要其他任何人调用这个函数,你可以把它设置为私有(private)函数。如果你不指定可见性,编译器会抛出一个警告。最近solidity编译器进行了一些改进,如果用户忘记了对私有函数进行标记导致了外部可以调用私有函数,编译器会捕获这个问题。这里可以看到所有的可见性说明符。
& A/ e- t0 q' \' e* w9 ]( O
你也会在一些函数上看到一个修饰符view。它通常用来告诉编译器函数是只读的(也就是说,调用该函数,区块链状态并不会更新)。所有的修饰符都可以在这里看到。! O: W5 C3 W: C1 m4 ]) G; y
编译智能合约 P% h- o" R0 P% R8 N6 ]2 z; O+ E2 E
) A- c! z/ a& o
我们将会使用上一节安装的solc库来编译代码。如果你还记得的话,之前我们提到过web3js是一个库,它能够让你通过RPC与区块链进行交互。我们将会在node控制台里用这个库部署合约,并与区块链进行交互。1 @8 X* C8 R: b5 E
/ t5 y; x0 h- o% L4 Z- F6 A
首先,在终端中运行node进入node控制台,初始化web3对象,并向区块链查询获取所有的账户。
* L1 k0 m6 m% r o) V
确保与此同时ganache已经在另一个窗口中运行0 Z/ l! r# L- \" Z
为了编译合约,先从Voting.sol中加载代码并绑定到一个string类型的变量,然后像下边这样对合约进行编译。
) F1 f* k! `$ }( s( @2 L, T
$node) P1 B6 b# W6 [3 v! [& M
7 J, p5 \; c3 a4 J p! \ F3 p3 W
Inthenodeconsole
>Web3=require('web3')0 H0 w8 @: R; \4 r2 x
1 o7 S1 B) ]& M9 c
>web3=newWeb3(newWeb3.providers.HttpProvider("http://localhost:8545"));
' l( h3 [; O. C( d* @% N6 B
>web3.eth.accounts
! H5 G: Z9 p' X- ^" L ^+ ]
['0x5c252a0c0475f9711b56ab160a1999729eccce97'. h% C) [. X$ ]3 c( T9 e
'0x353d310bed379b2d1df3b727645e200997016ba3'* s3 G. c! s# F* }1 L6 s5 ~ _2 {
'0xa3ddc09b5e49d654a43e161cae3f865261cabd23'7 p' m8 c$ F% c% I9 \$ O
1 |2 A" _- ]1 h+ J2 h- A! a' x
'0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5'
'0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798'4 T/ g$ u2 F% w- ?
'0xda695959ff85f0581ca924e549567390a0034058'
# k$ X6 z. p+ j, Q, r
'0xd4ee63452555a87048dcfe2a039208d113323790'* p# B, z) T6 Z) W- N
- a7 V) s! t$ w. Z! j6 P; [% L
'0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14'
'0xba7ec95286334e8634e89760fab8d2ec1226bf42'/ E4 ?! M$ u* m. p9 n
'0x208e02303fe29be3698732e92ca32b88d80a2d36']
>code=fs.readFileSync('Voting.sol').toString()
u n% B' u) P% D1 ~$ H
>solc=require('solc')
>compiledCode=solc.compile(code)
当你成功地编译好合约,打印compiledCode对象(直接在node控制台输入compiledCode就可以看到内容),你会注意到有两个重要的字段,它们很重要,你必须要理解:
1.compiledCode.contracts[’:Voting’].bytecode:这就是Voting.sol编译好后的字节码。也是要部署到区块链上的代码。
2.compiledCode.contracts[’:Voting’].interface:这是一个合约的接口或者说模板(叫做abi定义),它告诉了用户在这个合约里有哪些方法。在未来无论何时你想要跟任意一个合约进行交互,你都会需要这个abi定义。你可以在这里看到ABI的更多内容。 ^ r' J. s4 [7 @+ J# P! k9 q: B& F1 e
教程参考汇智网的DAPP开发入门教程,如果大家等不及博客更新,也可以直接访问这个以太坊教程。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
成为第一个吐槽的人