Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Solidity合约元数据

飞儿506
174 0 0
Solidity编译器自动生成JSON文件,即合约的元数据,其中包含了当前合约的相关信息。0 Q/ g% {+ i3 x
它可以用于查询编译器版本,所使用的源代码,|ABI| 和 |natspec| 文档,以便更安全地与合约进行交互并验证其源代码。
, ?  {7 P; m3 ^$ I7 i0 H编译器会将元数据文件的 Swarm 哈希值附加到每个合约的字节码末尾(详情请参阅下文),
( Z0 ]$ X3 O/ Q7 B+ n5 E以便你可以以认证的方式获取该文件,而不必求助于中心化的数据提供者。8 x' n4 ?/ S& n3 w# h
当然,你必须将元数据文件发布到 Swarm (或其他服务),以便其他人可以访问它。
2 |5 K0 r7 A# ]0 G  o- s# h该文件可以通过使用 solc --metadata 来生成,并被命名为 ContractName_meta.json 。  I+ f: N; U) x. N  j  `7 I# p
它将包含源代码的在 Swarm 上的引用,因此你必须上传所有源文件和元数据文件。8 }  M3 r- M+ |# A. G0 v+ R. e
元数据文件具有以下格式。 下面的例子将以人类可读的方式呈现。$ D% o8 D; U4 f+ k7 e
正确格式化的元数据应正确使用引号,将空白减少到最小,并对所有对象的键值进行排序以得到唯一的格式。" W% j; T( ~% ?7 P
代码注释当然也是不允许的,这里仅用于解释目的。
% L  q5 p$ G" g) m1 e" e{* V2 ^  L0 @7 {5 ^9 U" M% s
  // 必选:元数据格式的版本0 r3 \' Y& m* S2 j0 K% C
  version: "1",; h; k3 P8 r7 @7 h
  // 必选:源代码的编程语言,一般会选择规范的“子版本”
# D2 d7 F7 t( T& U3 Q0 B  language: "Solidity",
& K: \: R4 v) ]& C  // 必选:编译器的细节,内容视语言而定。: q$ V9 i7 p+ w6 K) T6 N6 K
  compiler: {
9 a: Q/ _# I, c& [% k) W3 i    // 对 Solidity 来说是必须的:编译器的版本, S1 F0 j! L, o4 C6 d: }
    version: "0.4.6+commit.2dabbdf0.Emscripten.clang",
+ L8 C) F  c0 Q: X9 C    // 可选: 生成此输出的编译器二进制文件的哈希值
  R) k: T% q" O    keccak256: "0x123..."
9 D/ o* H. Y  a( M- D) W  },
. _$ q: P3 u4 M  // 必选:编译的源文件/源单位,键值为文件名
5 H" i/ v! U; V  sources:: `# p( P+ C& }& R4 _3 i3 L8 [: |  `
  {' ]5 x0 Y4 E- C# c+ |$ e& Z4 b
    "myFile.sol": {* F. ^+ j4 u" |' Q6 S
      // 必选:源文件的 keccak256 哈希值5 e8 ~& W0 V: D/ ]/ N
      "keccak256": "0x123...",4 c1 y: Q' n7 F0 X) v: T4 X
      // 必选(除非定义了“content”,详见下文):
+ Q- _1 M+ l% Y  }+ J# C7 M      // 已排序的源文件的URL,URL的协议可以是任意的,但建议使用 Swarm 的URL
* \7 o" u) t. W( T) I0 i      "urls": [ "bzzr://56ab..." ]" Y  u+ ?2 ~) [6 x& W: F
    },
: V5 R  m& U5 y; C, C; }- s    "mortal": {& y  {. {+ O8 J& u
      // 必选:源文件的 keccak256 哈希值2 K6 r( Q% l2 t* H# g9 z  N& R
      "keccak256": "0x234...",* G6 u: w4 D: P4 P% H  ?% E* ?  D
      // 必选(除非定义了“urls”): 源文件的字面内容" N7 ~1 O* w, I5 r4 O
      "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }"
' e+ f) c. w. c, t3 C! B4 r    }# B3 u# q  X: W6 C: Y$ n' o
  },7 O. f3 g$ f, P3 x4 K- L# Q" `: r! @
  // 必选:编译器的设置5 ]% i8 Z( o+ f- X/ [& a# e# J, {: H
  settings:, t/ X* K4 H1 _) j7 o3 v
  {3 [- w, t. R9 O! j! b
    // 对 Solidity 来说是必须的: 已排序的重定向列表3 l; @& a& k$ m: W/ N/ M
    remappings: [ ":g/dir" ],- c5 |' }0 Q, j- P% ]
    // 可选: 优化器的设置( enabled 默认设为 false )
4 a, R: @7 d1 Y8 j% |    optimizer: {( t- d( |+ M) t5 V* S/ T, f; h6 V
      enabled: true,( A5 V" r2 M2 G+ I& o- y2 @# z
      runs: 500$ T: ^- U2 ^7 U2 A
    },
. q. M9 k+ n$ d. T$ H2 I    // 对 Solidity 来说是必须的:用以生成该元数据的文件名和合约名或库名
+ T* F. y( d. d    compilationTarget: {
* f/ Y$ v6 ~+ _4 s' ]! [      "myFile.sol": "MyContract"
( p' d& `4 r3 e' @% e- L    },
6 R8 E! |( `  R8 Z# P& V    // 对 Solidity 来说是必须的:所使用的库的地址
# @& y0 C6 F6 W% Q) g    libraries: {
- h5 v% U7 [' c) u5 u, ?$ G      "MyLib": "0x123123..."% p4 }9 H5 k2 F; h5 W
    }
' D9 X4 o7 @! c. \# P1 I! e  },
7 S4 x0 Y3 z5 |2 ~  // 必选:合约的生成信息+ f1 X% A/ L% k  J$ k  l
  output:
! g1 Y* I+ Q% [# x" d5 q  {
# Y6 m' J' P3 c" `% a8 c% D    // 必选:合约的 ABI 定义
3 o, O' j1 W$ |; r$ T" z& [8 _    abi: [ ... ],
& c: o! ]$ w' l; L( c    // 必选:合约的 NatSpec 用户文档) n* V  _  _* l. L  B
    userdoc: [ ... ],
" n8 K7 ?8 f9 X7 M# B0 Q    // 必选:合约的 NatSpec 开发者文档
2 P& c! ], {2 |    devdoc: [ ... ],
7 l# h6 f% Z, f8 V" }1 Z  }
! W& l# Z' L# O: ~, i5 e}
% y! h- p+ {  X" y8 p" d… note::
4 V" X# H3 B7 h) ]% ]4 c需注意,上面的 ABI 没有固定的顺序,随编译器的版本而不同。; d9 {& \) f' F
… note::) e* D" T5 U( O
由于生成的合约的字节码包含元数据的哈希值,因此对元数据的任何更改都会导致字节码的更改。
5 o$ u4 Y, o& c- L! y此外,由于元数据包含所有使用的源代码的哈希值,所以任何源代码中的,
% z+ {* Q" a7 }; \哪怕是一个空格的变化都将导致不同的元数据,并随后产生不同的字节代码。# G4 G/ f* C# B0 b5 \# u7 K
元数据哈希字节码的编码  Q% e! G, L; F3 q% W2 e, S
由于在将来我们可能会支持其他方式来获取元数据文件,0 t) [  r. k$ Q
类似 {"bzzr0":} 的键值对,将会以 CBOR _ 编码来存储。
1 w5 `  i! H8 v6 s3 G由于这种编码的起始位不容易找到,因此添加两个字节来表述其长度,以大端方式编码。/ X; \3 O6 k& }: ~. C
所以,当前版本的Solidity编译器,将以下内容添加到部署的字节码的末尾::
' B' Z. I! O9 ^; {0xa1 0x65 'b' 'z' 'z' 'r' '0' 0x58 0x20  0x00 0x294 e6 Q  y$ ?  E8 Q
因此,为了获取数据,可以检查部署的字节码的末尾以匹配该模式,并使用 Swarm 哈希来获取元数据文件。2 x6 r3 N+ u6 ?& s4 p) f
自动化接口生成和 |natspec| 的使用方法, Y8 D  d6 i6 [: |$ G5 g
元数据以下列方式被使用:想要与合约交互的组件(例如,Mist)读取合约的字节码,# m% V+ ^0 y  V$ f/ S. p3 o
从中获取元数据文件的 Swarm 哈希,然后从 Swarm 获取该文件。该文件被解码为上面的 JSON 结构。% z* W$ t0 g+ w' k
然后该组件可以使用ABI自动生成合约的基本用户接口。
2 X7 O" G' D2 F4 }6 y此外,Mist可以使用 userdoc 在用户与合约进行交互时向用户显示确认消息。
% E& m+ y( S6 T/ k有关 |natspec| 的其他信息可以在 这里 _ 找到。# ?6 U3 Y% o- m. E( t
源代码验证的使用方法
8 f' g* g) C; W! `% N2 I为了验证编译,可以通过元数据文件中的链接从 Swarm 中获取源代码。
- f& ^3 R6 Q* p+ I获取到的源码,会根据元数据中指定的设置,被正确版本的编译器(应该为“官方”编译器之一)所处理。" `5 w2 }0 z% d' K1 ?/ S! s7 Y
处理得到的字节码会与创建交易的数据或者 CREATE 操作码使用的数据进行比较。
( d, B& T8 {, F" ^+ A0 y这会自动验证元数据,因为它的哈希值是字节码的一部分。
9 ]( _) x- F2 J7 d: }% h  f# h而额外的数据,则是与基于接口进行编码并展示给用户的构造输入数据相符的。
标签: Solidity
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

飞儿506 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11