Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Solidity合约元数据

飞儿506
153 0 0
Solidity编译器自动生成JSON文件,即合约的元数据,其中包含了当前合约的相关信息。
) V6 ~+ J& C7 T; t它可以用于查询编译器版本,所使用的源代码,|ABI| 和 |natspec| 文档,以便更安全地与合约进行交互并验证其源代码。! M2 s$ L& R; F7 E
编译器会将元数据文件的 Swarm 哈希值附加到每个合约的字节码末尾(详情请参阅下文),9 ]- J( }9 f7 Z
以便你可以以认证的方式获取该文件,而不必求助于中心化的数据提供者。
3 M$ G1 f# C0 T& |9 Q% `当然,你必须将元数据文件发布到 Swarm (或其他服务),以便其他人可以访问它。4 K" D6 I& k" D- w; f8 c+ v/ E8 L
该文件可以通过使用 solc --metadata 来生成,并被命名为 ContractName_meta.json 。
7 }& w2 @: y* V; H* E6 [它将包含源代码的在 Swarm 上的引用,因此你必须上传所有源文件和元数据文件。
) c- l" F% [" L4 [, o元数据文件具有以下格式。 下面的例子将以人类可读的方式呈现。
1 E1 M8 H4 b) R1 d. I7 j0 C; I正确格式化的元数据应正确使用引号,将空白减少到最小,并对所有对象的键值进行排序以得到唯一的格式。4 A" i* ]9 y4 i" q
代码注释当然也是不允许的,这里仅用于解释目的。/ T3 Z) f% m7 |2 ]& F5 {
{/ Y9 C& i1 Z0 K) \6 d7 E
  // 必选:元数据格式的版本
1 e; }0 V9 b) Y  version: "1",* t3 G9 R- V, L# F( h- c" u
  // 必选:源代码的编程语言,一般会选择规范的“子版本”
! o! y4 G( ?8 i! Y3 g% O: n# Q  language: "Solidity",
& f* U# `8 Z. L5 u: H  U  // 必选:编译器的细节,内容视语言而定。
/ Q( T3 R1 z8 x7 ?  compiler: {
* {* V; w2 C) ?1 H- O/ K4 w    // 对 Solidity 来说是必须的:编译器的版本
% H( q  |* S8 V8 @" Q    version: "0.4.6+commit.2dabbdf0.Emscripten.clang",4 R& S# H8 \8 v* Q+ l; v3 U$ |
    // 可选: 生成此输出的编译器二进制文件的哈希值' g( S5 u( M) F* K
    keccak256: "0x123..."- u: @7 T9 K* K: h
  },/ J# f0 y+ A. m2 [" P2 E5 W
  // 必选:编译的源文件/源单位,键值为文件名
# T* N  m0 @" i" o6 X1 j  sources:( [( [: Z5 K6 d7 u2 h0 l7 i5 G
  {) y  ?: z; g+ u) Y
    "myFile.sol": {. u* s0 V0 W% `8 u5 O4 W% \
      // 必选:源文件的 keccak256 哈希值
; B7 ~. Z8 _: b5 M7 K; e      "keccak256": "0x123...",+ F, C; X; h6 J1 N0 c) C+ l
      // 必选(除非定义了“content”,详见下文):0 O! M1 e+ U4 W. W: N
      // 已排序的源文件的URL,URL的协议可以是任意的,但建议使用 Swarm 的URL0 E* P7 x" J+ `# _: n
      "urls": [ "bzzr://56ab..." ]
8 O# K; A% t5 @+ x1 B    },
3 X7 R& {% E% F. `    "mortal": {7 P! J" a3 s7 F- T; e
      // 必选:源文件的 keccak256 哈希值
  y: s& W# S3 s+ B      "keccak256": "0x234...",0 H- o$ P' j+ P0 H- t) s
      // 必选(除非定义了“urls”): 源文件的字面内容" [) R7 E2 j- b- q! M
      "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }"" `8 o% e' }3 ]/ G3 Y' Z, Q
    }
, c: q9 ?: U1 g$ K% n  },
$ A& d* V- P# @  ?; @  // 必选:编译器的设置
% c+ C/ b5 {& Z5 f. E% l  settings:% b; U  W( {; h
  {) j0 m6 z0 u% v
    // 对 Solidity 来说是必须的: 已排序的重定向列表0 |; A  T1 C( @) t! I5 p
    remappings: [ ":g/dir" ],$ p7 W; ^7 K3 F. p- ]- Y1 {
    // 可选: 优化器的设置( enabled 默认设为 false )
: _+ K$ o9 T# p: X- d; f7 K# q    optimizer: {1 I8 [: d6 [: ^( V2 |# c
      enabled: true,
  R" F# s$ i& W9 C9 X/ Z      runs: 500
" j- _7 v( @% u/ a    },0 x2 D( q  p) P, F5 I
    // 对 Solidity 来说是必须的:用以生成该元数据的文件名和合约名或库名
* X7 {2 A0 v4 y0 a' K    compilationTarget: {
# M: h, a7 T# T; L1 k      "myFile.sol": "MyContract"
' l+ u6 H5 c0 t: r    },/ R9 ~9 n8 N% w, B6 d3 l1 [7 ^
    // 对 Solidity 来说是必须的:所使用的库的地址
1 i. ~" w- L$ Z* q+ Q- L0 y0 X    libraries: {
' a* J  N8 e1 o) B/ B      "MyLib": "0x123123..."
, H5 a1 o: G- ~3 W    }$ `/ F$ X1 l3 J+ a; d! O
  },$ Q8 a; b: @  N* A. x
  // 必选:合约的生成信息
* I1 E1 u" P) r' L5 c  output:, o# l3 I$ n( H" e
  {
" |. F* j0 T( k. w; J+ c    // 必选:合约的 ABI 定义
; K) X" I, w0 A6 P    abi: [ ... ],6 @( T( K- G5 t" K4 ^: f  j
    // 必选:合约的 NatSpec 用户文档) w7 I5 q6 i0 U/ P
    userdoc: [ ... ],3 C' S5 n+ d; j* s
    // 必选:合约的 NatSpec 开发者文档
2 s, d0 @& [* y& r. X7 Q    devdoc: [ ... ],' y; z7 y! W+ g' D
  }. I# |1 G- p* v  ^' B, {
}" I* w) I. B3 X
… note::. l+ ^  T' @: x( u2 ]
需注意,上面的 ABI 没有固定的顺序,随编译器的版本而不同。
! f) G$ P0 u% _% s2 M8 Z… note::- I  V+ {6 z: g
由于生成的合约的字节码包含元数据的哈希值,因此对元数据的任何更改都会导致字节码的更改。" U' W; B2 \* K6 @- _9 e- X1 k
此外,由于元数据包含所有使用的源代码的哈希值,所以任何源代码中的,6 }6 f2 @* v" r1 z) e4 Q3 G" K
哪怕是一个空格的变化都将导致不同的元数据,并随后产生不同的字节代码。
8 B- [* N# g, ^元数据哈希字节码的编码
3 r% z# I( H0 @  ~由于在将来我们可能会支持其他方式来获取元数据文件,
2 Z8 v3 g' W! f4 i, V& j- p类似 {"bzzr0":} 的键值对,将会以 CBOR _ 编码来存储。8 R1 l* ?' w+ x( F: G( r
由于这种编码的起始位不容易找到,因此添加两个字节来表述其长度,以大端方式编码。
$ J+ v: p9 q! _9 f! q所以,当前版本的Solidity编译器,将以下内容添加到部署的字节码的末尾::
! @0 ^; G' b/ t8 r  l+ g( e6 Y0xa1 0x65 'b' 'z' 'z' 'r' '0' 0x58 0x20  0x00 0x299 z* g- A  _, F! m* @' [
因此,为了获取数据,可以检查部署的字节码的末尾以匹配该模式,并使用 Swarm 哈希来获取元数据文件。
7 C0 }. W; Q' x自动化接口生成和 |natspec| 的使用方法/ v& g: e: \& u4 U4 J6 o
元数据以下列方式被使用:想要与合约交互的组件(例如,Mist)读取合约的字节码,: R+ u% i. M! q" r5 r4 U
从中获取元数据文件的 Swarm 哈希,然后从 Swarm 获取该文件。该文件被解码为上面的 JSON 结构。1 |0 D- F) z0 m* G7 c3 J& _
然后该组件可以使用ABI自动生成合约的基本用户接口。
+ o% s- f: C& z此外,Mist可以使用 userdoc 在用户与合约进行交互时向用户显示确认消息。9 E; `7 x8 q  k. }( f
有关 |natspec| 的其他信息可以在 这里 _ 找到。
6 K' T1 h$ }7 O$ T% F3 Y源代码验证的使用方法' R% x' Z4 p1 e( D  h2 Z, W: W0 P
为了验证编译,可以通过元数据文件中的链接从 Swarm 中获取源代码。5 b# ^9 }4 V8 T5 t, J$ ~0 v
获取到的源码,会根据元数据中指定的设置,被正确版本的编译器(应该为“官方”编译器之一)所处理。
' n4 y4 G1 `8 Z- |4 U  q处理得到的字节码会与创建交易的数据或者 CREATE 操作码使用的数据进行比较。, L$ `+ y2 b. h1 i& o& e
这会自动验证元数据,因为它的哈希值是字节码的一部分。( E1 U! ^5 L3 `# M
而额外的数据,则是与基于接口进行编码并展示给用户的构造输入数据相符的。
标签: Solidity
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

飞儿506 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11