如何通过solc编译solidity编写的以太坊智能合约
曲水流觞113
发表于 2022-11-6 23:42:53
122
0
0
2 L9 U0 E E; I4 z; C1 T# W$ d
solidity编写的以太坊智能合约可通过命令行编译工具solc来进行编译,成为以太坊虚拟机中的代码。solc编译后最终部署到链上形成我们所见到的各种智能合约。
作为一个solidity命令行编译工具,我们来看看官网都怎么说solc。
solc的安装很简单:
' [6 _. ~4 S% t6 M+ x
npminstall-gsolc
//或者
! t: ]4 h; R5 E6 }
npminstall-gsolc-cli
//或者
sudoapt-getinstallsolc6 V+ r2 N5 J8 U& u6 b' T, o% W
: s r( I* m0 l% P' m# u
安装完成后我们来看,solc--help,solc--help命令显示所有的solc命令选项。编译器可以生成各种输出,比如最终的二进制合约文件、语法树的汇编或者需要预计的要花费的gas等。solc--binsourceFile.sol,可以编译后输出一个名为sourceFile.sol的智能合约文件。如果你想从solc获得更丰富的一些输出变量,你可以使用solc-ooutputDirectory--bin--ast--asmsourceFile.sol。
N9 M# L5 Q: C# \) V
你在部署以太坊智能合约之前可以用solc--optimize--binsourceFile.sol优化一下。默认情况下solc编译器会帮你优化200次。你也可以设置--runs=1,这样就按照最小化的方式进行编译,如果你希望多次交易不太在乎成本,那你可以设置成你想要的次数:)。; m4 U7 J/ Y3 ?" p
命令行编译器会自动读取需要导入的文件,也可以通过使用prefix=path来指定路径,例如:1 y' B( f- Z) [' E$ i# g
' K) a8 J$ f2 U4 s5 `- W
solcgithub.com/ethereum/dapp-bin/=/usr/local/lib/dapp-bin/=/usr/local/lib/fallbackfile.sol
这样编译器就会从指定目录github.com/ethereum/dapp-bin/下的/usr/local/lib/dapp-bin/目录开始搜索,如果没有找到文件,它将查看/usr/local/lib/fallback。solc将只读取你指定的这两个路径的,因此像import"/etc/passwd";必须要通过/=重新映射才起作用。如果有多个匹配,则选择具有最长公共前缀的进行匹配。
出于安全上的考虑,编译器限制了它可以访问的一些目录。在命令行中指定的源文件的路径(及其子目录)和命令行指定的路径外其他所有内容都会被拒绝。--allow-paths/sample/path,/another/sample/path来切换。
. d# L; |4 f6 o7 ^' ?
如果智能合约使用了libraries,你会注意到字节码包含了__LibraryName______的子字符串。您可以使用solc作为链接器,这意味着它将在这些点为您插入库地址。 g, c2 a! Y0 V' V. m8 u
+ i4 I e" y5 p- S; U( W5 r8 P N) u/ [
可以通过添加库--libraries"Math:0x12345678901234567890Heap:0xabcdef0123456"到您的命令,以提供每个库的地址,或者使用文件中的说明字符串(每行一个库),并使用--librariesfileName运行solc。
如果用选项--link调用Solc,则所有输入文件都被解释为未链接的二进制文件(HEX编码),在上面给出的__LibraryName____格式中,将其链接到适当地址(如果从stdin读取输入,则将其写入stdout)。在这种情况下,除了库外,所有选项都被忽略(包括-o)。
, e+ j; @% ^$ U: l9 |9 x- ~" x
如果用--standard-json调用SOLC,它就将标准的JSON输入(如下所述),并返回JSON输出。0 d) |. i ?' @/ L3 y! ^
4 r& V1 z9 Q+ D$ x
#solc编译器输入输出JSON描述
这些JSON格式通过编译器API使用,可以通过SOLC获得。内容都是可以修改的,一些对象是可选的(如前所述),其目的是向后兼容。) x `5 J3 d5 q/ W
. U' c! T: w v
编译器的API需要一个JSON格式的输入,然后以JSON格式输出编译结果。3 \, T# D# Q; D
. f, g. V8 \+ W2 z
注意不允许注释。下面示例中的注释,是官网为了学习者更好的理解标注的。
% R+ m; U* T. M( b, m5 b8 N
输入格式说明:6 C6 J" t6 H* P l5 E' i
0 ^( [% Z9 _5 `
{
//Required:Sourcecodelanguage,suchas"Solidity","serpent","lll","assembly",etc." q/ Z; N. x5 Q) J& P5 C
language:"Solidity",
I6 X1 }1 Q. [% B; e0 T, [( u
//Required
sources:3 a, c) }1 S( q: G
1 r& z3 R6 b& j% \: h# m' H
{$ M" d0 ?8 p6 E7 G5 h
* C6 |5 a; W7 O/ u( @
//Thekeysherearethe"global"namesofthesourcefiles,
5 m0 Q5 X# e( a: Q& `
//importscanuseotherfilesviaremappings(seebelow).
5 n, E- Q) @8 g
"myFile.sol":) H o/ |, Y" e7 t3 I) P: b) {
{! n$ Q1 i! ?5 W; z
: y" Q( ~2 l0 j% i9 z2 Q( K: q
//Optional:keccak256hashofthesourcefile+ s$ o5 k2 W8 ~7 V
6 \5 b7 x! C) [- n0 ~: b1 q
//ItisusedtoverifytheretrievedcontentifimportedviaURLs.$ V$ }; f' A% C' H5 |9 U* u
: A5 o7 P; ~( W9 p
"keccak256":"0x123...",
' [( E! M4 {8 N* ]8 c8 ?$ [
//Required(unless"content"isused,seebelow):URL(s)tothesourcefile.
4 E$ T: x! M2 L. Y' ~2 S
//URL(s)shouldbeimportedinthisorderandtheresultcheckedagainstthe5 Q5 F$ m& | g1 y5 q" g
//keccak256hash(ifavailable).Ifthehashdoesn'tmatchornoneofthe( [. j) `+ u; \
- @* _) g \$ S4 n/ W( ]/ g
//URL(s)resultinsuccess,anerrorshouldberaised.# N" P) Z, H% B7 [
"urls":4 f$ V5 G0 s4 ^
[* Y% ]8 G% j4 R* k% ~
"bzzr://56ab...",) U( i: o- H: ?# B
"ipfs://Qma...",: W; j3 n+ t4 ~* W; m
"file:///tmp/path/to/file.sol"
]
! J! k& O, x. y9 @3 {
},
"mortal":
/ s& e) c' Y% p m. i
{* J2 G3 }0 E5 ] I& n
//Optional:keccak256hashofthesourcefile9 }2 K8 T) f/ @! ^3 k" E4 {6 S
/ h) ~) k4 l; b( r t& K4 o! x
"keccak256":"0x234...",+ D) \9 Z: M8 W
2 l, ^% y0 o( ~ L7 ~- \9 e' F
//Required(unless"urls"isused):literalcontentsofthesourcefile
3 @- S+ w" }. l" w/ ^
"content":"contractmortalisowned{functionkill(){if(msg.sender==owner)selfdestruct(owner);}}"
}0 u) K! B- y; ~8 p
4 A: {. `( l0 _2 w1 v; U
},
# z) O5 {. g* b6 c
//Optional& ~4 G$ }) [! J- {- }! U
settings:- X4 U/ K8 V- t9 r7 X# @, w
{
% b* L$ b0 e3 ]% k; ~( ^$ P
//Optional:Sortedlistofremappings0 y! Y9 ]( M- i$ c7 p# C+ R
) c4 z, m t- ^( t2 U2 ^
remappings:[":g/dir"],. O: d% J/ x1 ?6 }8 y) L
# r5 s+ B6 B, h+ m; s* \3 |0 P0 r
//Optional:Optimizersettings
optimizer:{
//disabledbydefault6 D. [2 h. h; N; T
enabled:true,4 ?6 i: P& q& l
5 t$ H! @3 }) L0 q( E7 C
//Optimizeforhowmanytimesyouintendtorunthecode.
7 a# D1 A1 N* Q% ~1 W
//Lowervalueswilloptimizemoreforinitialdeploymentcost,highervalueswilloptimizemoreforhigh-frequencyusage.5 F' @$ l8 T+ z8 a2 e
runs:200. v( I$ ?6 v1 P! |
},
evmVersion:"byzantium",//VersionoftheEVMtocompilefor.Affectstypecheckingandcodegeneration.Canbehomestead,tangerineWhistle,spuriousDragon,byzantiumorconstantinople
, \4 K% N( k' W# n2 V* D7 L, ?
//Metadatasettings(optional)
metadata:{4 Z- |: P6 l; F( V4 v M
//UseonlyliteralcontentandnotURLs(falsebydefault)
: U; D$ F# [# r+ l A
useLiteralContent:true
0 C7 f0 m3 z- v) {
},
3 R9 c$ u' h1 y+ F) f4 K/ D' t
//Addressesofthelibraries.Ifnotalllibrariesaregivenhere,itcanresultinunlinkedobjectswhoseoutputdataisdifferent. C+ r) y' \# F1 o) I( u) a
libraries:{( m7 n( @1 L7 c8 @: @ B
3 k) q4 g5 N( E W& u
//Thetoplevelkeyisthethenameofthesourcefilewherethelibraryisused.
, r" Y R3 m+ F- d
//Ifremappingsareused,thissourcefileshouldmatchtheglobalpathafterremappingswereapplied.% I% z. Q. {8 z* x6 @
9 A) P9 j# d# L' X$ G5 b3 z* M8 x
//Ifthiskeyisanemptystring,thatreferstoagloballevel.- R( M6 ^" S! T8 \. Q9 W( ~. g
/ e# U) X$ L8 N3 H2 \& D+ u
"myFile.sol":{
"MyLib":"0x123123..."! W/ X" b# ?1 ?. T4 P; L$ d
}
}. ^( w s& p+ P
//Thefollowingcanbeusedtoselectdesiredoutputs.
3 I! c) i6 ]& ~
//Ifthisfieldisomitted,thenthecompilerloadsanddoestypechecking,butwillnotgenerateanyoutputsapartfromerrors.8 t. {* D$ Q6 K- s
. r6 T" D# k( M0 c' M
//Thefirstlevelkeyisthefilenameandthesecondisthecontractname,whereemptycontractnamereferstothefileitself,
4 `+ ?) Y" D$ M; ~
//whilethestarreferstoallofthecontracts." ?2 |0 b9 R* I7 G; `6 s6 l& z: g
( ]- _. D% R. Y/ y2 p, G
//. }+ v/ ~* i: b/ {
//Theavailableoutputtypesareasfollows:, V1 E4 H- x/ e" X0 I
( }9 S8 z# N* ?8 Z3 _; x$ J
//abi-ABI
; K- r& A% F1 U
//ast-ASTofallsourcefiles5 U; x: ~; L- j4 v) n: J: d
5 f' ]; v6 q$ u S. I
//legacyAST-legacyASTofallsourcefiles
//devdoc-Developerdocumentation(natspec)9 s( r( K+ g) _
//userdoc-Userdocumentation(natspec) N* b# H, e9 \ F" R
9 f- b2 E: W9 B. i& N
//metadata-Metadata$ A: W$ H" P: P2 x/ K p: @
//ir-Newassemblyformatbeforedesugaring; y, A u: |' I+ [) ?
//evm.assembly-Newassemblyformatafterdesugaring) {4 }; ?" X4 K5 o( b- f
d9 R# m2 [; K! f
//evm.legacyAssembly-Old-styleassemblyformatinJSON9 U; H6 g+ i9 D2 d0 T& p2 E# B
//evm.bytecode.object-Bytecodeobject
//evm.bytecode.opcodes-Opcodeslist+ L; s. `8 w6 r ~, s
# m2 _" m; ^: e" e% g" d
//evm.bytecode.sourceMap-Sourcemapping(usefulfordebugging)
! y6 ]3 C! \$ X3 y/ d# V, a, n9 n$ e. i
//evm.bytecode.linkReferences-Linkreferences(ifunlinkedobject)
//evm.deployedBytecode*-Deployedbytecode(hasthesameoptionsasevm.bytecode)
8 _ B9 ]% T5 n" I" o
//evm.methodIdentifiers-Thelistoffunctionhashes! a* H8 K4 y3 i9 t/ g+ [2 w% C- Y4 E
' ?0 U# R+ d% t5 \! n5 A
//evm.gasEstimates-Functiongasestimates9 W$ u& b5 Z0 R/ M' a* s
//ewasm.wast-eWASMS-expressionsformat(notsupportedatm)( p9 F7 i: a d0 S" B8 _/ }
//ewasm.wasm-eWASMbinaryformat(notsupportedatm); T1 Y* M' h S, \- u/ }
//
//Notethatusingausing`evm`,`evm.bytecode`,`ewasm`,etc.willselectevery
9 H; s, M* ?& \8 w
//targetpartofthatoutput.Additionally,`*`canbeusedasawildcardtorequesteverything.* l' a5 }) @: c5 @
// d' _ y# S8 m4 G7 p' O; j
1 r0 }8 I E: K, U* w5 P
outputSelection:{5 k# Q; m$ g5 X! c# l0 e% u) @
( G/ {" p% V, _. @6 U( i# s
//Enablethemetadataandbytecodeoutputsofeverysinglecontract.
0 z5 D F: M% {
"*":{. e% a# F4 G4 I$ t4 c2 G
"*":["metadata","evm.bytecode"]( b4 a& R& L* p5 E' P
% e, s4 B8 t4 i7 p' Z
},0 l9 }: e$ i( |/ K
//EnabletheabiandopcodesoutputofMyContractdefinedinfiledef.
"def":{) k& u$ J, e0 ]; f( C
"MyContract":["abi","evm.bytecode.opcodes"], s* y. l8 @2 V. j/ Y
},
//Enablethesourcemapoutputofeverysinglecontract.& c" y n% v8 r; |% r( G
+ n) u2 \& V# ]9 g1 }5 f
"*":{/ t6 l' s l3 T3 k1 o3 b" p6 U
"*":["evm.bytecode.sourceMap"]
},
2 `9 ]+ B4 N8 [
//EnablethelegacyASToutputofeverysinglefile.( {/ S" Q$ Z; J. x1 B1 H3 J
8 v2 J! A, v# S: E" Q$ r! C) J
"*":{
"":["legacyAST"]; g: ?9 y$ j7 o% R3 I9 c
- M. F0 E8 }0 l- B* f: ^
}
. K; E5 O9 {% y5 a
}% B" g5 @( S( m% N; O0 [5 Y
}
: z' _0 A; K; H) X5 }1 p
}' t" |7 h6 b; L$ t5 X
5 K7 R4 s' ?9 |9 X5 j2 x3 F1 ?
输出格式说明
7 S7 V9 ]# {6 l6 R4 n
{5 R4 s* M) W# c- \, }$ y! i7 l% @7 m
//Optional:notpresentifnoerrors/warningswereencountered, ~* x; @! [( J8 W) W6 ~
errors:[
/ Y6 X9 E5 ~& H7 u |' J) X5 {6 W
{$ S+ j2 O( T0 c1 [ r
//Optional:Locationwithinthesourcefile.* G' k3 B6 t# S' [
sourceLocation:{ T% a" V2 p1 K' l
file:"sourceFile.sol",
2 }2 E6 I& A+ F, J n
start:0,
0 D. A1 z2 n! p5 J5 V6 R
end:100
],' X% ^3 T* k D/ w# X& x0 f( o
//Mandatory:Errortype,suchas"TypeError","InternalCompilerError","Exception",etc.) I, W2 A9 S8 j% T4 h$ P$ |
! H$ m# E/ S2 u9 J% ~) b
//Seebelowforcompletelistoftypes.5 @ s; c! C2 C. n/ m& J) W9 M& o
type:"TypeError",
//Mandatory:Componentwheretheerrororiginated,suchas"general","ewasm",etc., v# e0 I; U/ ^5 U R, N3 ^0 Y
0 V" _9 N2 N$ \; y6 v6 `: d! i
component:"general",
//Mandatory("error"or"warning")1 _1 ~, ?& P8 J" e1 W' i$ i/ l) m
severity:"error",8 {+ r0 P6 I4 n, {; _5 W
; U' P5 m0 e& m6 X# Q1 `
//Mandatory* I; [% T, Z9 e
3 S# D3 J; Q1 H+ X* n
message:"Invalidkeyword"' K" P" X* o- L. \' C. P
- m% Q0 v9 F+ p. r- b
//Optional:themessageformattedwithsourcelocation2 X n" j; d4 ~( h; K
) z: V) c, Q, f% H$ [6 J
formattedMessage:"sourceFile.sol:100:Invalidkeyword"2 r2 d& c h% u- P
" Z. [8 X8 f/ y& a& a/ _: x
}- X/ m6 ^7 K5 C- s1 v/ L7 {9 w
],: |' { g1 Z9 x T9 `
& y! E& U; U C D
//Thiscontainsthefile-leveloutputs.Incanbelimited/filteredbytheoutputSelectionsettings.
9 [0 |" ^( F& Q& r, s o
sources:{
"sourceFile.sol":{
//Identifier(usedinsourcemaps)( m1 w8 c$ `% _5 R$ s$ D
) D$ f( a- z; P- p
id:1,' S& H$ J1 s& v! _, N( q' D0 _
//TheASTobject+ B+ s; `. P5 o+ ^2 q
ast:{},- U) N7 u$ |4 P- b
//ThelegacyASTobject3 I% @9 l" t; I8 n. B- B
legacyAST:{}
! c( n {) t7 ~- J0 k- Q( C. @
}' K1 l! T) u% l: ^' K- [
1 y$ o* p& U- A% h: e9 L# H
},
6 D8 `9 u$ S! U7 L4 `& X/ ~2 u
//Thiscontainsthecontract-leveloutputs.Itcanbelimited/filteredbytheoutputSelectionsettings.
contracts:{" x5 x/ I+ Q8 e- U& E% G5 F
7 M; R: }6 Y- i' n; B, X* g
"sourceFile.sol":{2 _5 T2 i; g/ w; ] ?
4 T7 p, ?+ \$ u
//Ifthelanguageusedhasnocontractnames,thisfieldshouldequaltoanemptystring.2 ]/ G" a+ C# r; x' i) I% W
"ContractName":{9 A; _7 n% p. _4 b1 t6 W) @# H5 p4 x
//TheEthereumContractABI.Ifempty,itisrepresentedasanemptyarray.
//Seehttps://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI$ x b+ C: P" k' i/ c) _& A2 T
abi:[],
* Z# W3 f- m6 k" ^9 d a8 g8 D, k
//SeetheMetadataOutputdocumentation(serialisedJSONstring)
) J6 I* h y7 e- G& J# Q4 m
metadata:"{...}",
//Userdocumentation(natspec)
userdoc:{},
//Developerdocumentation(natspec)
devdoc:{},+ F0 Y% G2 e4 c2 l$ b* ^3 i
3 B4 H/ g; m3 A( V0 h- z* S1 z
//Intermediaterepresentation(string)) S9 Z0 t8 b- V( T
ir:"",1 }. W. |$ e8 J6 [3 F
5 I0 e( E5 \6 r& v: U$ K
//EVM-relatedoutputs' K2 s" C* q" l* ?
7 o' u7 F* p! |% o
evm:{2 W7 p2 _7 d$ g4 A
//Assembly(string)7 V6 q4 y3 E# K& F$ S7 ]+ M6 u
assembly:"",1 F! F4 p$ O0 T
//Old-styleassembly(object)
legacyAssembly:{},
4 J. Q9 w4 a; I* g7 p+ y2 f
//Bytecodeandrelateddetails.( [8 i- r) {" x+ {% P. D( U
bytecode:{! h- ~) ^: \# W5 h! d- Q% f
//Thebytecodeasahexstring.8 D) A; s3 t- G
* C) l/ Y5 [, w r4 \
object:"00fe",
: f4 V/ D1 f3 {& X
//Opcodeslist(string)
- ^5 r' @. }6 h; J' S/ o6 s* {! V4 m1 K
opcodes:"",1 Z1 w( |) `- f1 E2 \4 ~
//Thesourcemappingasastring.Seethesourcemappingdefinition.
1 C. {* X! X6 [2 q8 W* ?
sourceMap:"",# q+ T1 d* Q5 q j, ]3 P- L
: E" N! B6 F: c& A; Y! U5 z
//Ifgiven,thisisanunlinkedobject.
* p& f0 `: y& }
linkReferences:{, E# E; s+ ^! J/ l* b* Z/ B. q7 Q
"libraryFile.sol":{9 J9 k9 O/ x* t5 B$ B& {
7 b E; b" N' B
//Byteoffsetsintothebytecode.Linkingreplacesthe20byteslocatedthere.* H3 c- j4 w& O; V7 u, T# F
"Library1":[
9 J/ h* t) @+ c# y0 w5 q
{start:0,length:20},+ y( h) w, B3 c# P. R' V
5 J4 G$ b5 ?% ~$ u! _. ^% ^
{start:200,length:20}- u. t. |3 B3 k4 ?; {6 a
" M5 S- }0 k$ |5 p
]
5 W# } G6 f" |
}" g; e" l* t- l! n7 L
% e! q1 Y3 F% I* |7 Y7 _" E) y
}
},+ ~6 A: w0 n6 x0 y8 P- W, ]
//Thesamelayoutasabove.
. F2 u+ a4 A' {1 U3 n* K9 S: u3 ?
deployedBytecode:{},/ z/ O: K# `! K; P( {& Z4 ^/ a7 c
: a; D2 Z, M) h! b% ~) F) E+ _4 \
//Thelistoffunctionhashes
methodIdentifiers:{3 M$ i; U l+ n: y; k
% g$ {$ B% Y' w& {4 A' k3 b
"delegate(address)":"5c19a95c"
},
//Functiongasestimates) B, s" V( V! y. O
gasEstimates:{
creation:{
codeDepositCost:"420000",
$ M$ z( ^) L" r9 |$ a2 Y
executionCost:"infinite",# E3 L- A/ n. z+ a. U4 @( b7 u
Y j8 g5 n- j
totalCost:"infinite"
},# k6 I) B' n/ v8 \
2 e5 V5 o" F$ J3 b, u
external:{
"delegate(address)":"25000"! D: Y, P6 Q, _% J
},1 f* g& t- F6 c
) M0 w+ B. v1 B$ @( C* ]
internal:{
$ ?* n' G+ D0 w |- p! ^
"heavyLifting()":"infinite" G9 m4 J$ S1 `
}
}
, j" f9 ~- o8 `5 o G. Z
},' q2 ]! t+ G' ^- a# m, i" M+ T2 w: `
# L# @$ \/ g. b& T
//eWASMrelatedoutputs5 n! N! Y! G3 k: n
ewasm:{
//S-expressionsformat( ^/ J: o. x( i( o
& U! y0 A3 F' x/ a
wast:"",
* ?+ T! O/ D5 k2 u
//Binaryformat(hexstring): ?1 h, C" F8 m- Z
: X8 Z6 _6 h& S. s w/ w- M9 \
wasm:""* b( |0 x! _/ z4 k( b( L5 z
}
- t+ D& F! z. M& X- E
}
, }- a. g/ z% A
}6 e% Z& _- r2 C8 \
4 Q$ A. W" e9 Z# c" s4 V
}
}
错误类型说明:
& @& g3 @3 a h. g
2 w: k g7 h. o2 l5 x
JSONError:JSON错误,JSON输入不符合要求的格式,例如输入不是JSON对象,不支持语言,等等。
4 e: P3 Y, H' }" m9 s3 \
IOError:IO错误,IO和导入处理错误,如提供的源中的不可解析URL或hash不匹配。
+ S9 n8 w; F' T; X& q
ParserError:语法f分析错误,源代码不符合语言规则。
; m7 W7 i4 S! U% w* L0 l: D# f
DocstringParsingError:文档解析错误,无法解析注释块中的NATSPEC标记。
* ?! }; T% L, w- w
SytRealError:语法错误,如continue在for循环之外使用。
DeclarationError:声明错误,无效、不可解析或冲突的标识符名称。例如未找到标识符
$ K1 m3 ^8 x/ R% r* `7 S5 u6 g
TypeError:类型错误,如无效类型转换、无效赋值等。* y8 N8 y8 d; T! ~5 c+ E: a) x
UnimplementedFeatureError:编译器不支持该特性,但希望在将来的版本中得到支持。0 p$ M6 R' l. z
" |/ N F* i W7 `
InternalCompilerError:编译器中触发内部错误,这应该作为一个问题来反馈。
Exception:例外,编译过程中未知的故障,这应该作为一个问题反馈。( o" @6 K+ j1 d
7 t6 {! g- w( O; X
CompilerError:编译错误,编译器堆栈的使用无效,这应该作为一个问题来反馈。0 l; n: F4 F3 _$ `4 D
' {- r0 S9 L: y
FatalError:致命错误,这应该作为一个问题来反馈。1 ^+ E* q8 p3 ^3 J& z
: j0 S3 d1 W3 B2 R( M
Warning:警告并没有停止编译,但如果可能的话,应该加以处理。
: a+ ?0 D- k' E3 g1 D6 L
+ I2 @0 n2 @" d9 [$ }5 Q7 |
原文请访问:solc
如果你希望马上开始学习以太坊DApp开发,推荐访问一个在线教程:
以太坊智能合约,主要介绍智能合约与dapp应用开发,适合入门。9 G& F% H7 l" j3 O) b2 H4 a
以太坊开发,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
成为第一个吐槽的人