Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Solidity合约元数据

飞儿506
253 0 0
Solidity编译器自动生成JSON文件,即合约的元数据,其中包含了当前合约的相关信息。
0 |; w3 u2 n( S7 C. }它可以用于查询编译器版本,所使用的源代码,|ABI| 和 |natspec| 文档,以便更安全地与合约进行交互并验证其源代码。
" E1 R7 K# l+ u. v0 E9 l0 K, b4 t' i编译器会将元数据文件的 Swarm 哈希值附加到每个合约的字节码末尾(详情请参阅下文),
. K- |% {# q: G! h4 _以便你可以以认证的方式获取该文件,而不必求助于中心化的数据提供者。/ B1 Z3 _* m4 c. J8 D/ z0 C% x2 ]7 P- F
当然,你必须将元数据文件发布到 Swarm (或其他服务),以便其他人可以访问它。
7 j! c9 P  d2 X6 `" q该文件可以通过使用 solc --metadata 来生成,并被命名为 ContractName_meta.json 。
+ h8 ]: `9 H: @) ~4 H它将包含源代码的在 Swarm 上的引用,因此你必须上传所有源文件和元数据文件。
+ R/ D. M! i  I8 @, W+ V- J6 {/ o元数据文件具有以下格式。 下面的例子将以人类可读的方式呈现。2 _7 M& V$ [7 ]& `. Y+ W$ z
正确格式化的元数据应正确使用引号,将空白减少到最小,并对所有对象的键值进行排序以得到唯一的格式。8 l% ?6 t* w9 `: `/ x, t
代码注释当然也是不允许的,这里仅用于解释目的。
: I0 W  G1 n, V- j9 {* `{
, w+ q4 D: V- n. s% z2 Y8 K) H  // 必选:元数据格式的版本
4 h1 l5 h3 B* U  version: "1",
! S/ ]! X7 d' l# o  // 必选:源代码的编程语言,一般会选择规范的“子版本”
  t( \8 |% B, w# Z! b- Q! R3 K  language: "Solidity",; C  w- c& I; |
  // 必选:编译器的细节,内容视语言而定。4 S: I- {& X9 T2 Y- g9 J
  compiler: {
1 e- J/ u; i; ~( y" j2 q% p  I9 D    // 对 Solidity 来说是必须的:编译器的版本
- ~+ q1 v% t8 ~3 t% Q5 x6 q    version: "0.4.6+commit.2dabbdf0.Emscripten.clang",8 r1 P" W& Y* Q* ~' k3 [5 e
    // 可选: 生成此输出的编译器二进制文件的哈希值% F+ _# F0 D& |1 Z) O! s
    keccak256: "0x123..."
3 G" ^2 `4 T6 ], ?; q! t  },' H6 D% @, L8 B7 X
  // 必选:编译的源文件/源单位,键值为文件名0 m% y. l& O" \+ E2 G% P
  sources:
! ?* b1 K) F9 u3 T) g  ^  {
! h0 Q; ]/ y! [  Z$ t( J' S1 V) G. q    "myFile.sol": {
- M- p' F* u: N1 K+ c- `) M      // 必选:源文件的 keccak256 哈希值5 Z# z! a% _( v/ z$ I* Y
      "keccak256": "0x123...",0 v, I0 c0 b+ D+ b
      // 必选(除非定义了“content”,详见下文):
# C' v4 @: v+ x- u4 z      // 已排序的源文件的URL,URL的协议可以是任意的,但建议使用 Swarm 的URL) F, Z. b$ o/ E4 i
      "urls": [ "bzzr://56ab..." ]/ }3 q. A* n: S+ q! \" J2 H7 |/ ]
    },+ _" Z- t& {' _$ Z  G
    "mortal": {( p' D8 X5 \1 q6 j8 `( q( `. Y0 k
      // 必选:源文件的 keccak256 哈希值. r- Q, s3 T6 {$ U
      "keccak256": "0x234...",) v8 ^9 h# W9 N2 r
      // 必选(除非定义了“urls”): 源文件的字面内容$ A5 b6 p2 B/ q9 T: Q
      "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }"6 {1 Z9 x- G8 M: C! u3 f
    }
; ?; f1 b4 ?2 Q  },
" X" M8 b( ~# `5 s5 m' D  // 必选:编译器的设置: k& w# ^5 F8 F; Z* h7 _+ V8 j
  settings:
. @% H7 W/ C8 K+ s  {
- r) l% T) H9 {9 c0 J/ i    // 对 Solidity 来说是必须的: 已排序的重定向列表$ s$ @" B4 k9 c# e3 c& z
    remappings: [ ":g/dir" ],
6 v: s& g# x! W  z    // 可选: 优化器的设置( enabled 默认设为 false )% j, [) y% h9 X9 _' U5 _0 M
    optimizer: {
5 Y5 a- N: Q/ D      enabled: true,) }: t) n4 @9 ?$ w
      runs: 500. `7 {7 a2 y2 G$ d
    },* P1 e  H! V' G; L; A
    // 对 Solidity 来说是必须的:用以生成该元数据的文件名和合约名或库名7 j9 j/ g! G* p+ U2 x
    compilationTarget: {
0 N/ n" a5 F# G, @      "myFile.sol": "MyContract"# y8 s8 r; h$ v: f2 t! P& I3 Z! k
    },
6 y* E& ]# h/ |. o, g) j  J" N    // 对 Solidity 来说是必须的:所使用的库的地址, o# J7 F- u9 f! n) S
    libraries: {' J' F0 Y9 n* i
      "MyLib": "0x123123..."
2 Z0 |# ]2 E2 o    }
/ }# D( w+ X. {: @3 I$ O  },
1 a- c5 K0 `, r- N  // 必选:合约的生成信息- v$ \1 |' F& C/ ~2 Y( ?
  output:: b" n7 \) b9 C/ B
  {
1 o8 k2 \/ d; T8 N/ M4 D    // 必选:合约的 ABI 定义7 S. S3 b- K3 }& m
    abi: [ ... ],
, y: y# T5 h9 p! U, b+ i    // 必选:合约的 NatSpec 用户文档# O0 L% `4 F8 l6 G  F5 b5 k' n
    userdoc: [ ... ],
9 p7 \1 t/ D- D    // 必选:合约的 NatSpec 开发者文档7 S5 r' L$ a* V
    devdoc: [ ... ],* p2 X% {7 ^& i/ `  G
  }
6 w& m7 j! d8 Y) v% M' Z7 T}
/ @7 D- g+ v; ^1 M% N/ N  ?… note::8 u6 w9 B# |( g) b
需注意,上面的 ABI 没有固定的顺序,随编译器的版本而不同。" z1 M0 H: V" Q) ~* E/ u
… note::
; x' z# g1 @/ |, T  A# P- N由于生成的合约的字节码包含元数据的哈希值,因此对元数据的任何更改都会导致字节码的更改。" L: ^! Z( M- Y4 b( h
此外,由于元数据包含所有使用的源代码的哈希值,所以任何源代码中的,1 H) I5 m- O. m+ _
哪怕是一个空格的变化都将导致不同的元数据,并随后产生不同的字节代码。
) ?$ ^/ D3 u  N. U/ J元数据哈希字节码的编码& x( \/ f. a5 a9 f4 j
由于在将来我们可能会支持其他方式来获取元数据文件,
! R1 t, y% U* a6 h类似 {"bzzr0":} 的键值对,将会以 CBOR _ 编码来存储。
( r) W6 ^, a1 d6 s' G6 P( ?5 T由于这种编码的起始位不容易找到,因此添加两个字节来表述其长度,以大端方式编码。
( P. G! ]+ V0 h, c- w所以,当前版本的Solidity编译器,将以下内容添加到部署的字节码的末尾::
0 _9 S8 A" }0 X% f2 _3 G0xa1 0x65 'b' 'z' 'z' 'r' '0' 0x58 0x20  0x00 0x29
2 y7 M! g1 C3 ], q* o0 f因此,为了获取数据,可以检查部署的字节码的末尾以匹配该模式,并使用 Swarm 哈希来获取元数据文件。- m) X( y, {3 S4 o5 T
自动化接口生成和 |natspec| 的使用方法
2 i- U' o  x+ }5 A/ l' [. X元数据以下列方式被使用:想要与合约交互的组件(例如,Mist)读取合约的字节码,  q. s/ H: I9 U: k
从中获取元数据文件的 Swarm 哈希,然后从 Swarm 获取该文件。该文件被解码为上面的 JSON 结构。
: O' Q6 t3 n% E' W( {, m然后该组件可以使用ABI自动生成合约的基本用户接口。8 v9 Z% Y+ q% X  z2 s
此外,Mist可以使用 userdoc 在用户与合约进行交互时向用户显示确认消息。
0 p8 x: c+ k8 K; T: y! k8 n有关 |natspec| 的其他信息可以在 这里 _ 找到。
% R" y. Y$ D/ T' P# N% H源代码验证的使用方法
: A1 U& b0 x% G* G  {为了验证编译,可以通过元数据文件中的链接从 Swarm 中获取源代码。
0 {: Z6 u7 d/ I' o' S' [3 Z获取到的源码,会根据元数据中指定的设置,被正确版本的编译器(应该为“官方”编译器之一)所处理。
" H, k6 R$ g  f: f* I% Z! E& F处理得到的字节码会与创建交易的数据或者 CREATE 操作码使用的数据进行比较。
2 q2 W" }+ Z7 p& l9 _  N这会自动验证元数据,因为它的哈希值是字节码的一部分。3 _7 q* d+ j$ ^' Z  H" O
而额外的数据,则是与基于接口进行编码并展示给用户的构造输入数据相符的。
标签: Solidity
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

飞儿506 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11