以太坊教程:搭建环境、编写编译一个智能合约
dancing520
发表于 2022-11-6 21:10:54
716
0
0
6 r; Y, S' A7 G0 Q, q
以太坊是什么7 A) C3 l! x" u" f+ x
以太坊(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 ~
以太坊区块链是什么?
' 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是到目前为止用得最多也是相对更容易的选择)。所以,以太坊不仅仅会存储交易数据,它还会存储和执行智能合约代码。
可以简单的理解以太坊区块链的作用就是存储数据和代码,并在EVM(EthereumVirtualMachine,以太坊虚拟机)中执行代码。( P6 @; E, V6 D
要准备的基础知识" ], d, j/ f. H- d8 S# Y
为了进行以太坊开发,你应该对以下语言/技术有基本了解:
! w5 u7 v8 V* R+ u8 B
熟悉某种面向对象语言(如Python,Java,go)
HTML/CSS/Javascript2 X0 n v0 ]7 X! d1 o
7 C; M3 ^. j" A9 d, K/ h( K
基本的命令行交互如Linuxshell命令
理解数据库的基本概念
为了构建以太坊去中心化应用即Dapp(Decentralizedapplication),以太坊有一个非常方便的JavaScript库即web3.js,你也可以在一些js框架中直接引入该库构建应用,比如react,angular,vue等。! T$ j4 G+ A5 u# r' {
3 w7 M% i, [7 j, W
示例:一个以太坊投票应用
$ 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)。
# f9 E/ z, o9 [- a2 p4 z' ^
现在,你对以太坊已经有了基本了解,我们可以开始构建投票的dapp了。这将会加强你对以太坊的认识,并且初略了解以太坊的功能。
以太坊开发环境搭建
Linux
. H+ z* L9 q5 ^( [ p0 X. c+ f l
示例是Ubuntu16.04下的学习环境搭建,你只需要成功安装了nodejs和npm,就可以继续项目的下一步了。
( }. i' r2 }1 D& g4 d
我们通过npm安装ganache和web3包来为以太坊教程提供支撑。我们也需要安装solc来编译合约。
& m- V& D4 m; q' l, D4 |( b' C$ U
下面是安装过程:# H4 h) j$ H' R
$sudoapt-getupdate
* h" g2 i$ h5 U5 M
$curl-sLhttps://deb.nodesource.com/setup_7.x-onodesource_setup.sh
$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
v7.4.0
$npm--version
4.0.5& E+ M/ o9 E( W0 R8 f5 T
$mkdir-pethereum_voting_dapp/chapter1
# R8 l0 t3 R7 o7 A. T' f
$cdethereum_voting_dapp/chapter16 x) M$ J5 g# \9 v8 @* T0 s
$npminstallganache-cliweb3@0.20.1solc
/ ^& N. @3 K X4 L- u2 w
$node_modules/.bin/ganache-cli3 @: \: o) ~. E0 |0 K5 L$ d. o. q
如果安装成功,运行命令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
================== s# R9 J/ e9 X+ K
(0)0x5c252a0c0475f9711b56ab160a1999729eccce97
4 Z+ d# m$ x2 _, m6 R/ x) E
(1)0x353d310bed379b2d1df3b727645e200997016ba3
2 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
(4)0xc0aa5f8b79db71335dacc7cd116f357d7ecd2798' {/ a8 k4 Z$ ^% r
(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
(9)0x208e02303fe29be3698732e92ca32b88d80a2d36
& 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
(0)a6de9563d3db157ed9926a993559dc177be74a23fd88ff5776ff0505d21fed2b
8 Q; U4 Y5 \6 I2 T1 Q
(1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d603
0 W- ~9 V9 _3 Z) d' |' D8 `
(2)ad2b90ce116945c11eaf081f60976d5d1d52f721e659887fcebce5c81ee6ce99
(3)68e2288df55cbc3a13a2953508c8e0457e1e71cd8ae62f0c78c3a5c929f35430, _, g! f; Z, ^: P
(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
(6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9
(7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d% p1 ?: \7 t, G% d
' Z+ ^& A! H4 S' J. G
(8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
* 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
==================9 m) o' |/ f$ h
" u/ d1 E$ L7 l% A4 O
Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella- G+ t# M0 V" g7 S5 v
BaseHDPath:m/44'/60'/0'/0/{account_index}/ C8 M: P [" _6 T: E, j0 X
Listeningonlocalhost:8545
/ k% E, S g/ {) h0 F& m
为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。
6 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是一个包管理器,它可以帮助我们安装开发所需的所有其他软件。按照下面的指示安装所有其他所需的包。
* 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
$node--version0 Q( {: e1 @: o
v7.10.08 p1 }) M" E) q
8 p3 ^- ?6 E. @2 e: l( r: i
$npm--version
4.2.0/ Z% A3 y& j5 m1 K$ e; {
6 s: ] J0 o0 P9 ^$ o
$mkdir-pethereum_voting_dapp/chapter1
, D0 |% ] w0 o2 ? J! m& V
$cdethereum_voting_dapp/chapter18 k3 L& X% {6 c2 X, I' W1 {: `
$npminstallganache-cliweb3@0.20.1solc& v0 [" ^% @( d: B% Y! H& |1 u$ L
$node_modules/.bin/ganache-cli( M. ~+ X6 \% `0 i
% t( x# ~4 u3 V5 ]. j1 z( K( v% c
我们通过npm安装ganache和web3包。我们也需要安装solc来编译合约。
如果安装成功,运行命令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
AvailableAccounts
4 u, l2 l1 D- w) @7 b# h; U. X
==================
(0)0x5c252a0c0475f9711b56ab160a1999729eccce97
% 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
(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
(7)0xc60c8a7b752d38e35e0359e25a2e0f6692b10d143 i1 L; @7 ^6 u/ ?& s
0 b; {, b( T% f
(8)0xba7ec95286334e8634e89760fab8d2ec1226bf42
/ W5 D0 E! ]6 J% X
(9)0x208e02303fe29be3698732e92ca32b88d80a2d36/ {# j& a R: q0 ?/ W
" K8 M4 ^2 G9 S. `
PrivateKeys
6 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: `
(1)17f71d31360fbafbc90cad906723430e9694daed3c24e1e9e186b4e3ccf4d6032 N$ e9 o6 m9 m$ N* B" [, G
(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
(4)9753b05bd606e2ffc65a190420524f2efc8b16edb8489e734a607f589f0b67a8
(5)6e8e8c468cf75fd4de0406a1a32819036b9fa64163e8be5bb6f7914ac71251cc
(6)c287c82e2040d271b9a4e071190715d40c0b861eb248d5a671874f3ca6d978a9$ l; U1 B% [ _+ p, n
$ [# Y7 n% ]! O$ ]9 s# _: y- m
(7)cec41ef9ccf6cb3007c759bf3fce8ca485239af1092065aa52b703fd04803c9d
(8)c890580206f0bbea67542246d09ab4bef7eeaa22c3448dcb7253ac2414a5362a
(9)eb8841a5ae34ff3f4248586e73fcb274a7f5dd2dc07b352d2c4b71132b3c73f0
; X* j e) \2 ^6 V
HDWallet
==================4 Y$ q3 j* }4 T0 l5 r B% s
Mnemonic:cancelbettershockladycapablemaincrunchalcoholderivealarmduckumbrella
BaseHDPath:m/44'/60'/0'/0/{account_index}# z: h* W! d r4 M' U4 W4 \
Listeningonlocalhost:8545
0 Z5 R% \+ S* e3 V
为了便于测试,ganache默认会创建10个账户,每个账户有100个以太。如果你还不懂什么是以太坊账户,把它想象成存钱的银行账户就可以了(以太(Ether,ETH)就是以太坊生态系统中的钱/货币)。你需要用这个账户创建交易,发送/接收以太。
: q( a8 u( x$ _' a* f1 T* ?* K
Windows
^4 ?2 [4 y4 X' ]
安装VisualStudioCommunityEdition。如果你选择定制安装,那么至少应该安装VisualC++(目前的版本是VS2017)
% e6 ?% G/ Q8 ~2 E
安装WindowsSDKforWindows
) {+ 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
下载和安装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
SolidityContracts% w* [/ Z& U$ |" U7 O
现在已经安装好ganache并运行,我们将会开始编写第一个以太坊智能合约。
" ?; r, |/ N( X
我们会使用solidity编程语言来编写合约。如果你熟悉面向对象编程,学习用solidity写合约应该非常简单。我们会写一个叫做Voting的合约(可以把合约看成是面对对象编程语言的一个类),这个合约有以下内容:
1 P4 u% K% ~# \5 I. k) g. ^
一个构造函数,用来初始化一些候选者。, Q$ A( w- n+ K N
一个用来投票的方法(对投票数加1); m: Q6 f4 I9 L. Q+ v- P
一个返回候选者所获得的总票数的方法
5 W# ~5 T7 s4 X
当你把合约部署到区块链的时候,就会调用构造函数,并只调用一次。与web世界里每次部署代码都会覆盖旧代码不同,在区块链上部署的合约是不可改变的,也就是说,如果你更新合约并再次部署,旧的合约仍然会在区块链上存在,并且数据仍在。新的部署将会创建合约的一个新的实例。! ]* d4 y' K0 W/ E# V
pragmasolidity^0.4.18;( j. ?, h( M1 P J
5 _7 H% z v: b; u, i
contractVoting{
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
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
}$ M6 `* V" A1 O9 V1 ]( x/ Q
y) @& b; D9 f9 W. H$ x1 q/ j i
functiontotalVotesFor(bytes32candidate)viewpublicreturns(uint8){
require(validCandidate(candidate));1 ` T! w, A5 O; y
returnvotesReceived[candidate];
8 L! W$ D9 ^( @% y
}
: Y+ q4 z6 K( t4 h7 V$ {
functionvoteForCandidate(bytes32candidate)public{
6 G8 Q6 N" [' w; K1 V0 d3 o: X O
require(validCandidate(candidate));
votesReceived[candidate]+=1;
9 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){
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
代码和解释* T& M3 W5 R9 h, M: [4 N
5 A2 }, L) R+ r( ]
Line1.我们必须指定代码将会哪个版本的编译器进行编译& Y8 R0 L* l/ J0 L
Line3.mapping相当于一个关联数组或者是字典,是一个键值对。mappingvotesReceived的键是候选者的名字,类型为bytes32。mapping的值是一个未赋值的整型,存储的是投票数。
0 u3 D2 `+ Y1 E! s. c) X
Line4.在很多编程语言中,仅仅通过votesReceived.keys就可以获取所有的候选者姓名。但是,但是在solidity中没有这样的方法,所以我们必须单独管理一个候选者数组candidateList。
; V5 J! d, |" x$ @6 h, m/ Z+ a
Line14.注意到votesReceived[key]有一个默认值0,所以你不需要将其初始化为0,直接加1即可。
你也会注意到每个函数有个可见性说明符(visibilityspecifier)(比如本例中的public)。这意味着,函数可以从合约外调用。如果你不想要其他任何人调用这个函数,你可以把它设置为私有(private)函数。如果你不指定可见性,编译器会抛出一个警告。最近solidity编译器进行了一些改进,如果用户忘记了对私有函数进行标记导致了外部可以调用私有函数,编译器会捕获这个问题。这里可以看到所有的可见性说明符。0 y' Y- l' h S2 C
) [: z6 ?; T' ~ X8 F
你也会在一些函数上看到一个修饰符view。它通常用来告诉编译器函数是只读的(也就是说,调用该函数,区块链状态并不会更新)。所有的修饰符都可以在这里看到。
& b1 \7 M* m& j7 H5 c: ~( g! X7 w
编译智能合约
: 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
确保与此同时ganache已经在另一个窗口中运行
4 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
6 b: R# \6 p# E
Inthenodeconsole( H- I6 O( `, H0 c5 q$ h5 M" d, J
>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"));
>web3.eth.accounts
['0x5c252a0c0475f9711b56ab160a1999729eccce97'; O, w' H" r# v! x7 s+ J" J
'0x353d310bed379b2d1df3b727645e200997016ba3'3 a; E, ^( U- W8 W, _9 ]( X4 D
# [ Z8 C `$ v* Q
'0xa3ddc09b5e49d654a43e161cae3f865261cabd23'$ u5 E E" l- Z5 z6 i6 @- \0 q( |
'0xa8a188c6d97ec8cf905cc1dd1cd318e887249ec5'
( 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
'0xd4ee63452555a87048dcfe2a039208d113323790'
'0xc60c8a7b752d38e35e0359e25a2e0f6692b10d14'6 d Z# g1 |$ w2 `: Y* W0 |
'0xba7ec95286334e8634e89760fab8d2ec1226bf42'+ o5 X: `9 u1 K/ e- n
" y: _7 S+ u8 p5 {+ @+ X/ \: C( D3 W
'0x208e02303fe29be3698732e92ca32b88d80a2d36']
. T0 G- B4 D9 Z$ q* v) W1 [
>code=fs.readFileSync('Voting.sol').toString()- t$ ~. ^$ M7 g, s3 M, m7 b2 b( Q
>solc=require('solc')
>compiledCode=solc.compile(code)
) 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编译好后的字节码。也是要部署到区块链上的代码。
2.compiledCode.contracts[’:Voting’].interface:这是一个合约的接口或者说模板(叫做abi定义),它告诉了用户在这个合约里有哪些方法。在未来无论何时你想要跟任意一个合约进行交互,你都会需要这个abi定义。你可以在这里看到ABI的更多内容。
教程参考汇智网的DAPP开发入门教程,如果大家等不及博客更新,也可以直接访问这个以太坊教程。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
成为第一个吐槽的人



