以太坊开发演练 :Truffle,Ganache,Geth 和 Mist
李悔之2015
发表于 2022-12-2 09:56:46
194
0
0
5 k- s5 g9 C- M$ W" x) c
Truffle:是以太坊的开发环境、测试框架和资产通道。换句话说,它可以帮助你开发、发布和测试智能合约等等。你可以阅读有关Truffle套件的文档,了解更多信息。
7 Z @) M! k: g* O8 f* l/ _+ P4 s
Ganache:以前叫作TestRPC,如果你读过几个月前的教程的话,有可能他们在使用TestRPC的情境下配合使用了Truffle,它在TestRPC和Truffle的集成后被重新命名为Ganache。Ganache的工作很简单:创建一个虚拟的以太坊区块链,并生成一些我们将在开发过程中用到的虚拟账号。, b7 i1 S! B5 [
Mist:Mist是一个分布式网络apps的浏览器,相当于是只针对Dapps的Chrome或Firefox。目前来说,它仍然是不安全的,所以你还不能在不受信任的dapp中使用它。
' u2 B4 W7 G) _( b7 v% o
以太坊钱包:它是Mist的一个版本,但只启动一个dapp——以太坊钱包。Mist和以太坊钱包只是UI(用户界面)前端,我们还需要一个将我们连接到以太坊区块链的核心程序(它可以是一个真正的以太坊区块链,也可以是一个测试版的)。) P# ~* E/ D6 b. q- H
, ^8 ~; e# Y; Y" ]) X
Geth:Geth是把你连接到区块链的核心应用程序,它也可以启动一个新的区块链(在我们这个示例中,我们将创建一个本地测试网区块链),创建合约,挖掘以太币等。! l; v( z9 z( D9 P y
我们会先使用Truffle配套Ganache,然后使用Truffle配套Geth和Mist。5 k9 ? N# F& O5 F
安装
/ A2 V5 r4 C2 g8 m2 n# h1 O
本教程的要求是你要知道它是什么以及如何使用命令行工具,并且你要稍微熟悉NPM。1 n% s: E8 ]7 S7 f& J
Truffle: a9 }6 W. |+ L5 N) L
. Y4 [6 u* i9 O$ ~" k6 X v
打开命令行,并输入:
' M/ r( f8 Y1 o3 {4 P2 q
npminstall-gtruffle% `, }/ t% t& p6 P; v6 N% ?
如果出现错误,建议你多阅读有关Truffle的文档。- Y$ U# ~% s2 s: n* `# A: n8 l
8 y% P& a, [+ {* s6 T
Ganache3 I1 G9 r2 a: t: @- T0 i
然后,安装Ganache的命令行界面:+ M8 K3 v( s& [( s3 {! m
: Q- B. d. ` K E+ v
npminstall-gganache-cli/ N! f/ c @, b! U. |. {
) s5 I( S) J' E2 P3 M
如果你对此不是很确定,点击此处访问Ganache的Github页面。3 f3 l/ @: B! C9 r
注意:这是Ganache的GUI(图形用户界面),不过既然我们都是程序猿,还是要用CLI(命令行界面)。3 ] D3 V, T. z \; q: C
i, N4 g# G3 {
开始吧5 _6 y9 r q* O f7 w! D
; J# B0 U6 T# N+ J# X/ d: M3 O( a0 E
首先,创建一个新的文件夹,并输入。
8 o7 G s# E1 A8 Q' @$ g3 k
truffleinit+ n' ]& D. y, E
它会初始化一个空的truffle项目。: y H% Q9 F3 ^! G" r& Q
然后从上一个教程中复制Wrestling.sol文件,粘贴到到contracts文件夹中。接下来,打开“migrations”文件夹并创建一个名为“2_deploy_contracts.js”的新文件。Migrations只是帮助我们将合约部署到区块链的脚本。$ ^4 @8 v# i9 O/ H8 y, t
* [: m) S3 s" H! t1 g
将下面的代码粘贴到里面,然后保存。3 }7 s' Z2 l: h+ U
$ W; v6 z; g1 E/ C5 D
constWrestling=artifacts.require("./Wrestling.sol")
module.exports=function(deployer){. k0 O U' x! Z4 x N% J& i
deployer.deploy(Wrestling);4 _8 M R: b2 x6 O
};0 Q- p$ a4 j3 }( U% ?
- i+ p B6 x. m1 D. w7 Q+ H/ d
第1行是用来导入“Wrestling.sol”文件的(从“contracts”文件夹导出),第4行则将它部署到区块链中。- v" \% t" {* |- S% C3 ?
) S& k) F, `# N
现在,回到根目录,你会看到两个文件,“truffle.js”和“truffle-config.js”。如果你在Windows上操作,那就删除“truffle.js”;如果你在另一个系统上操作,删除其中一个或者同时保留它们,都不要紧。这样做的原因是,在Windows上有一个命名问题,当我们想要执行Truffle命令时,它会打开“truffle.js”配置文件而不是读取里面的数据。5 f* _9 {) h/ F$ V
我是在Windows上写的这篇教程,所以我把“truffle.js”文件删掉了。然后我会把这段代码放入truffconfig.js中:
module.exports={- E6 R8 N& v% S8 C
: g% q+ y# O5 h$ Y; F3 o
//See
. R( H3 Q0 g: K/ \
//formoreaboutcustomizingyourTruffleconfiguration!
networks:{8 M/ E6 k# g% ?8 Q4 ]" H0 g
development:{
host:"127.0.0.1",
% M# ^. M4 P& q+ \
port:7545,8 q0 i9 j& O$ u$ j0 T
# V9 e! Y2 T9 a) R
network_id:"*"//Matchanynetworkid' J. I* @# D- T4 D
}- \/ v1 K$ w9 H9 u8 u
}
2 u- ` b. T' a$ a& j4 V
};
基本上是说,当使用开发网络时,使用端口7545,连接到127.0.0.1(localhost)的主机。2 V/ n/ }7 v: d/ L& s* v5 W+ C
现在我们准备在区块链上测试代码啦!- o& N: G2 z' {2 R, D8 P
# d+ d' w' n4 n! c N8 C
测试我们的代码$ v( E7 {8 `& R# c
在第一部分,我们会使用Ganache。5 [8 ]( g) A. _, |& R
启动一个新的命令行,并输入以下命令:
8 C$ O2 a' ^9 Z: D
ganache-cli-p7545
: ~/ Q% z) i* [- P, i' L
它所做的,就是告诉ganache-cli从端口7545启动。
" f1 ` K+ i2 V
Ganache会为我们生成测试账户,默认情况下,每个账户都有未锁定的100个以太币并,所以我们可以自由地从那里发送以太币。第一个示例账户就是这个家伙:. g ~- e* p! J, S3 Y/ p
现在,回到我们的第一个命令行界面,执行两个命令:
; I0 O/ f3 r# k+ N2 O
trufflecompile
trufflemigrate--networkdevelopment: B4 D L9 r: ^8 S# b6 \$ \4 S+ o
Compile将把我们的Solidity代码编译成字节码(以太坊虚拟机(EVM)能理解的代码),在我们的例子中,Ganache模拟了EVM。
Migrate(迁移)会把代码部署到区块链,我们之前在“truffle-config.js”文件中设置了“development”网络,我们可以在那里找到区块链。
7 M% s! U9 |1 W' \' z/ m, G1 I
现在,如果一切都按照预期进行,你应该会在终端上看到:& \# j# J9 X7 ~8 ^( D @
注意,这里显示了实例化的Wrestling合约的地址。
在ganache-cli运行的命令行界面上,你可以看到正在执行的交易:% r) \' ?' D5 ?( w: v+ u Q9 n2 p
! u9 g" F" t$ l+ V0 Y
注意,它显示了实例化的Wrestling合约的地址。
现在输入以下命令启动Truffle控制台,这会帮助我们与ganache的区块链进行交互。
truffleconsole--networkdevelopment
% n6 _& y! ^" T* E4 b: G% q/ U
首先,我们会执行这个命令:
, t9 U' Y, J. R* }, g
account0=web3.eth.accounts[0]
account1=web3.eth.accounts[1]
它会把第一个帐户的地址分配给变量account0,第二个帐户分配给变量account1。Web3是一个JavaScriptAPI,它将RPC调用包装起来以方便我们与区块链进行交互。/ v' \8 J4 _% J
然后我们输入:
/ g. k- s$ w2 o
Wrestling.deployed().then(inst=>{WrestlingInstance=inst})
" n0 D2 n$ h% q/ ~! \2 x. a
它为truffle部署到变量“WrestlingInstance”的合约实例分配了一个引用。4 W- E8 x; ^# x1 C5 J3 J7 f
执行下一行:
WrestlingInstance.wrestler1.call()
4 C! p$ ^6 @; v2 E# @
它将返回参与者1的地址,在我们的例子中,这是第一个帐户。在migration(迁移)过程中,Truffle会从Ganache选择默认账户,因为我们没有在迁移过程中指定另一个帐户地址或是Truffle配置文件中的另一个地址,所以这是第一个账户。
6 b o) f7 j* _ `; Q
然后我们把第二个账户注册为一个对手:
3 b* n, _0 S: I' @
WrestlingInstance.registerAsAnOpponent({from:account1}); G( [4 p) X5 W7 L% `! g) O( t, Q
! r1 s* C+ b# m' ~
在这里,“from”指令会告诉函数应该从哪一个账户触发交易。 m5 V7 h. [: b# t; L
在执行这一行之后,它应该会返回类似的内容:, |0 ?& F' J$ @" d+ B. T
/ f- D2 G( p* \) Z
注意,该项交易使用了Gas,并且触发了“WrestlingStartsEvent”事件。+ y7 B/ h) H1 H: F
你可以通过执行下列代码来检索第二位参与者的地址:
WrestlingInstance.wrestler2.call()9 s3 r, K2 F I
3 S. b2 n7 [) ]: q
现在,玩家们可以开始角力了:
; j! E l: {8 E7 r3 o. T
WrestlingInstance.wrestle({from:account0,value:web3.toWei(2,"ether")})
WrestlingInstance.wrestle({from:account1,value:web3.toWei(3,"ether")})
//Endofthefirstround2 `" \! k% X, G! |, w, ], O
WrestlingInstance.wrestle({from:account0,value:web3.toWei(5,"ether")})
2 l3 K: V9 E( Z: N/ C n2 Y
WrestlingInstance.wrestle({from:account1,value:web3.toWei(20,"ether")})8 V0 I9 x6 h0 P- }5 J
4 s( q' `# k3 l( R6 D( X6 P n
//Endofthewrestling
1 N, `4 [1 f5 E' |1 n
“value”指令用来在交易时发送以太币。“web3.toWei(5,“ether”)”意味着发送5个以太币,这个值会被转换成Wei。Wei是以太币的基本单位(最低面额)。点击此链接,可以找到更多的信息。
在执行最后一行时,account1会是大赢家,因为我们总共投入了23个以太币,比我们在account0投入的两倍还要多。/ o1 O$ H3 F+ C
给你留个小练习:从合约中提取以太币。* c) g( [ J( g ], X! ]: ?3 a
) D5 P! M6 s7 K: E: e& m
现在,靠你自己研究如何使用Truffle和Ganache的高级功能啦。你可以从阅读文档开始,或者,如果你感到读不懂或者想要加强你对刚才所学知识的了解,这里有一篇很好的Truffle介绍。
geth如何在这个过程中发挥作用
% \9 g/ B/ s) O! I
好了,我们已经使用了Ganache来进行开发,现在我们想要试一试更接近真实运行环境的东西,就算只是让自己更熟悉运行环境就好了。
6 q7 r: T& ?# f9 N
安装
首先,下载geth。在Windows上,你可能需要将geth的安装文件夹添加到你的PATH变量中。
下载Mist或以太坊钱包。其实使用起来都是一样的,所以选择哪一个都可以。- w- ]) g- J9 |: C+ |# C
. H0 v# I: ~; e1 z1 ?1 j# w: h
创建本地私有测试网络& e# m$ s( L8 a5 j5 q4 A
S( N8 r2 B A9 ^
在同一个根目录中,创建一个新文件,并将其命名为“genesis.json”。然后把下面的内容复制进去。* b' c; H* R; ^- W* N- [+ w
{+ A6 u H3 }& b+ V' g2 h; [
"difficulty":"0x20000",: X% Q. @2 n/ o( x. k
"extraData":"",
( K! Z# N. M' K6 v/ |
"gasLimit":"0x8000000",# f$ C' {3 R. ]3 E4 O
"alloc":{},
"config":{. _# w/ q* {' n6 m, L. L
, C* S0 |4 \5 O2 }
"chainId":15,+ a4 W; [) t/ C" d, r; _
! f+ T0 P0 ~, U
"homesteadBlock":0,
"eip155Block":0,
* M4 b) X$ w# a4 b3 X6 P' \$ ^
"eip158Block":0
c" B% f5 t# b6 G
}
4 l" B7 P0 M2 T2 \; _( [; O8 E K% O
}9 A/ C" o; o/ q4 T
“genesis.json”是一个配置文件,geth需要用它来创建一个新的区块链。现在了解这个文件的内容并不重要。0 \ U \' y' p: f& P$ `* X5 E
如果你在没有指定任何参数的情况下运行Geth,它会尝试连接到Mainnet。Mainnet是以太坊的主网络,是真正的以太坊区块链。
如果你在没有指定任何参数的情况下运行Mist,那么如果geth实例也正在运行,它就会报错。但如果你让Mist连接到正在运行的geth实例(我们将在稍后操作),它就会正常工作。如果你在没有geth实例运行的时候运行Mist,它将会启动一个新的geth实例,并最后向你询问它应该从哪一个区块链中下载区块。/ T. p4 M# A3 K. G- C8 n5 v
# r9 A0 ^; \* F: d6 c0 u0 G
虽然有公共的以太坊测试网络,但我们会使用之前创建的“genesis.json”文件在本地创建一个私有测试网络。
, `3 m: ?" r' Y- n# k2 R! V' W0 ?
启动另一个命令行界面并输入以下命令(确保在项目根文件夹中运行它):+ |2 L" L# [" y+ u/ c+ r/ R
geth--datadir=./chaindata/init./genesis.json
启动geth并指定区块链的存储位置,这里是在chaindata文件夹中(它会自动生成),然后我们用“genesis.json”配置文件对它进行初始化。$ i+ C9 Z& }3 j1 w
, u( y+ U! K( U8 h
接下来,我们使用以下命令启动geth:
geth--datadir=./chaindata/--rpc" \7 \& J# [6 R. h
# X7 q; O0 _% ~( V+ e& s. r
用“–rpc”参数让geth接受RPC连接,这是很有必要的,这样truffle才可以连接到geth。& z4 {1 C0 J+ q# ^
打开另一个命令行界面,启动Mist或以太坊钱包,使用相同的参数:
- a, D1 `+ E3 N! a
mist–rpchttp://127.0.0.1:85451 S* P3 ?1 O7 D; S! d$ ?: A
& U6 V( j8 |. e2 j
“-rpc”参数让Mist(或以太坊钱包)连接到我们刚刚启动的geth实例。9 ^! {9 f' d" w4 M& I: Q
在“钱包”选项卡中,按下AddAccount(添加帐户),创建一个新的钱包:
! H: x% w- r. l9 F6 S
请注意,我们正在使用私有网络。注意,你不应该为了开发,而在主网上上使用以太币。
我会用密码“123456789”创建一个帐户。在真实环境中,要使用更强的密码哦。
打开一个新的命令行界面并运行以下命令:
, V/ |6 `) G! f# K
gethattach6 e: W8 G; a' q- I! b' d% q/ t
f J" y$ V$ B' A6 B/ y% Y
它会运行geth的控制台,现在我们可以与它进行交互。
无须通过在MistUI上创建的主帐户,我们将在“gethattach”控制台中运行这个命令:
miner.start()$ R1 B+ }8 H2 e2 a9 t1 m9 G" b. h+ W0 I
6 S- U2 c9 x- O- a9 b, S
它会启动一名矿工,这个过程将会确认交易,而且在几秒钟或几分钟之后(这取决于你的电脑),你应该能开始看到你的余额中新增了以太币(以及你的主帐户也会有)。
# B3 u; }! H% T
请注意,如果你没有足够的可使用的RAM,它可能根本不会开始采矿。你可以使用“miner.stop()”指令停止挖矿。( a& k: m) Z: C P
现在,再次打开“truffle-config.js”文件,像这样修改它:
module.exports={8 i" ~3 D) W' F- E: @( i+ y
//See
+ Z. s# a2 E; c& }: E) @5 ?
//formoreaboutcustomizingyourTruffleconfiguration!
networks:{) B4 {) l1 F( C+ m
development:{( z5 N7 v$ n; ]
: j( I1 t5 N+ \4 Y
host:"127.0.0.1",% F2 o: G* ?* a
port:7545,
network_id:"*"& Y7 } y! b0 r# K& e* f+ O; _
},9 q# y! f# q. j$ C' ]" D7 p
) [+ \& u3 S* j7 ?1 I( |# L
ourTestNet:{; U! W1 C, a' Y( S6 {4 `1 e
: A* ~4 {& O6 r F2 D& m
host:"127.0.0.1",. ?5 {6 X F4 r" U
( D# T* I6 E- J3 F) R' i7 _& p
port:8545,$ h0 h% O' P$ f/ ]9 ^
* z! T% p0 [* m# T
network_id:"*"2 @" z# V. O- ~! X8 j- d- W
}- X# p1 h5 V7 v( o, Y* Q: U/ P5 c
) ] I4 {* ^- o6 p4 A7 A, b) `( J
}* O( G& n# D/ y2 G9 u4 P$ L% L J4 O
};
# \* M8 j& q5 w7 c/ s' {
“ourTestNet”是连接到geth实例所必需的配置。Geth在端口8545上默认启动。6 q; e Q. V' M# _4 q1 ]* k, m5 q
在我们启动“gethattach”的命令行界面中,我们会解锁账户。所以有了它,我们就可以从Truffle迁移智能合约。使用以下指令:
1 d- _. \( D4 S: @4 _( d5 K7 R
personal.unlockAccount('0x6AC4660c960Aaf5d9E86403DDAcB4791767e5869','123456789'), \0 {2 ~" Z% }+ h
; G" k( o: J$ d$ u# L- Y5 ?: r' o6 k D4 `
在这里,我使用了刚刚创建的账户的地址,在你创建的时候,它会是一个不同的地址,以及我将用于这些测试的密码“123456789”,对你来说也会是不同的。请注意,密码是以纯文本形式显示的,在真实账户中你应该使用一个不同的方法。
现在,回到我们之前发布的Geth的命令行界面,运行以下命令:
trufflemigrate--networkourTestNet- I! j! @; C! z
它会开始把合约转移到geth正在运行的区块链。如果你之前停止了挖矿,那现在启动它,否则,迁移将不会被执行。如果迁移成功,会看到这样的输出:% a x( \5 n- [9 l, z3 @% C$ N
现在,运行以下命令启动Truffle控制台:$ u' u9 E+ K* S1 u# P$ v5 P
truffleconsole--networkourTestNet4 E, }- k9 ^4 b& ~+ a$ j
5 H" K8 |7 q5 H! [# b1 Z5 F9 d+ s
然后运行这两个命令:
Wrestling.address0 t3 M, F7 {/ ~5 M+ m4 ]
JSON.stringify(Wrestling.abi)/ l. N- @- D, U; W% _8 v6 i8 m
. f2 p1 f+ D3 \. A' o7 W9 r( O" A
你会看到这样的输出:
! U- @$ y1 m9 z1 ~0 E
第一行返回已部署的Wresting合约实例的地址。3 }% {3 B/ N/ u# s" ?
6 p9 h' }) A2 W0 P, n+ Y7 h
第二行返回Wresting合约ABI。ABI基本上就是对合约的描述。它包含了一个函数、变量和其他因素的列表。( l# Y9 h5 d, W+ J
在复制地址和ABI的时候,删除屏幕截图中红色箭头所高亮显示的省略符号。
' T4 E/ U% v6 S/ N9 j) Q
现在,回到Mist,我们打开合约中的选项卡,点击“watchcontract.”。2 _/ t) d! B' x( w8 X( \9 [
+ x+ P6 d s4 {* _6 u2 c
然后,复制之前部署的Wrestling合约的地址和ABI:. M2 F' d" O' U& j+ @" ]
点击“OK”,然后它将显示在你要查看的合约列表中。点击它,它将打开合约页面。如果你向下滚动,你会看到这样的东西:
使用“selectafunction”部分与合约进行交互。这和我们前面使用Truffle控制台是一样的。5 @( u1 D. E* H! @9 y/ Z
就是这样,我们了解了Ganache和geth是如何发挥作用的。当你想要把合约部署到真正的区块链时,你应该使用第二种方法,并将geth与mainnet连接起来。
/ P, P) Q( Q2 G
注意:你可以直接在Mist上部署一个合约而不使用Truffle迁移系统,这里有一个这个过程的示例视频。虽然在实际开发过程中,使用Truffle其实更有意思,因为如果你要用模块化的方法来开发你的智能合约,你可以导入多个其他智能合约和脚本。
还有:你可以在一个基础的nodepad应用程序上编写你的合约代码,并使用一些可信的第三方门户把它部署到mainnet上,但是我不建议你这样做。2 m' g* Q: Y% F- ]/ w* Q" \
i$ c3 j% N, t5 ^
本教程的资源库可以在这里找到:
; j5 g# w# I. c' s: r) c; F4 h
devzl/ethereum-walkthrough-2
总结
我们已经学习了4种开发和部署智能合约的方法:, T9 y3 P8 I- d+ M" N
第1种是使用Truffle和Ganache。由于我们从上一篇教程中复制了代码,所以我想告诉你,有些插件可用于目前最流行的文本编辑器和IDEs。有些只提供语法高亮显示,而另一些则提供其他方面的帮助。
第2种是将Truffle的代码部署到geth(以及Mist的图形界面中)。: b( p9 F! V, |5 m2 | ?
: R( L! {+ R5 A7 z
第3种方法则是当你刚学习Solidity时,使用Remix来编写小的简单的合约,并像之前链接的视频中演示的那样,在Mist中部署代码。3 E" E3 a, I- N1 v& m' D% o
3 x+ y( X8 X, n# t) r
第4种,你也可以像真正的牛仔一样,用一个简单的文本编辑器进行编写,然后使用一个匿名第三方的拖放部署特性来部署未经测试的合约。
7 k( E$ _2 T2 o
因为我们的“Wrestling”脚本还远远没有准备好在一个真实的环境中启动,所以在下一讲中,我们将会讨论安全性。
成为第一个吐槽的人