Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Solidity合约元数据

飞儿506
163 0 0
Solidity编译器自动生成JSON文件,即合约的元数据,其中包含了当前合约的相关信息。
$ ?% @6 m5 E3 L9 i  U7 D# U1 R- Q! t它可以用于查询编译器版本,所使用的源代码,|ABI| 和 |natspec| 文档,以便更安全地与合约进行交互并验证其源代码。
7 c  K: `  C* {6 Z3 g  T" @' ~" }编译器会将元数据文件的 Swarm 哈希值附加到每个合约的字节码末尾(详情请参阅下文),
9 V: h* r& U5 |6 U' A( I8 {* H1 s以便你可以以认证的方式获取该文件,而不必求助于中心化的数据提供者。) K- ~+ |4 D2 Z% w. I
当然,你必须将元数据文件发布到 Swarm (或其他服务),以便其他人可以访问它。: E- T9 L7 ~6 v% k! b: E
该文件可以通过使用 solc --metadata 来生成,并被命名为 ContractName_meta.json 。
4 ~2 |+ }/ B! ]9 P它将包含源代码的在 Swarm 上的引用,因此你必须上传所有源文件和元数据文件。
/ ^+ w' k6 q4 G! ?7 R( j# ^元数据文件具有以下格式。 下面的例子将以人类可读的方式呈现。4 B6 K2 d$ O5 Q  u, W
正确格式化的元数据应正确使用引号,将空白减少到最小,并对所有对象的键值进行排序以得到唯一的格式。
. u/ R9 Z( D" L$ p0 t9 ^代码注释当然也是不允许的,这里仅用于解释目的。, B8 K3 j& ~7 u2 p7 S2 |: m* \! W
{
! E  J& s, A, O6 ~/ I7 v$ e  // 必选:元数据格式的版本
  I' J# e; c+ d2 D  version: "1",
( G7 a1 R2 O/ v! A) O! q  // 必选:源代码的编程语言,一般会选择规范的“子版本”
; C, V% u) ?, A/ G" U  language: "Solidity",9 a4 [' d' P& v
  // 必选:编译器的细节,内容视语言而定。6 ~* k; Y# r3 E! n  q9 n
  compiler: {
: Z* H- s+ J8 i0 m5 X( l    // 对 Solidity 来说是必须的:编译器的版本
' c2 Z: [( G- X. c3 J+ T# A    version: "0.4.6+commit.2dabbdf0.Emscripten.clang",2 y9 ?( \) H! C$ u+ k
    // 可选: 生成此输出的编译器二进制文件的哈希值
0 ]  R" I0 g1 E# F: {/ F    keccak256: "0x123..."
! F& z3 j3 {+ }( j' s' l" G  },2 P/ I) _  k  U) }6 q; r
  // 必选:编译的源文件/源单位,键值为文件名
* d& ^- d; x4 g7 B5 }3 t4 H: _  sources:
$ r$ ^1 u- n# M, J7 L  {
5 G/ @) i; O4 ~# @0 F8 N    "myFile.sol": {
) h% z4 y: h3 E5 i% z3 |      // 必选:源文件的 keccak256 哈希值
5 q! ]: E6 j3 j! @: n" o1 o  z      "keccak256": "0x123...",
4 k( G" X# R. I# ~      // 必选(除非定义了“content”,详见下文):; a+ w5 P+ |& K, J
      // 已排序的源文件的URL,URL的协议可以是任意的,但建议使用 Swarm 的URL" f5 K* Y7 @) @
      "urls": [ "bzzr://56ab..." ]! v# w# Y" r; t5 n5 G5 |
    },+ ~5 y5 a. G4 C# Z5 ~
    "mortal": {1 U- X& V* W1 r. ]6 ]  R# D4 w$ A
      // 必选:源文件的 keccak256 哈希值, d, |* @: V4 f( W/ S2 B# `% `4 t9 E
      "keccak256": "0x234...",
' d0 s( Q- w5 J' Y/ h' }      // 必选(除非定义了“urls”): 源文件的字面内容
! V" p* [7 O7 |      "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }"
8 d6 |, ?( J7 l    }" T7 s; N, G. o# L+ a8 b
  },% _1 F7 j; c" d3 t' u: w3 j1 Q
  // 必选:编译器的设置
9 S. @1 x4 [: b2 V% U: q  settings:- g: P1 O# Q9 v# v
  {
; a' s' G9 f3 q! u# q1 ], R4 v. E# L    // 对 Solidity 来说是必须的: 已排序的重定向列表
& i) g0 a/ y, ], g    remappings: [ ":g/dir" ],2 Y# A" P6 T- `, a7 n% J
    // 可选: 优化器的设置( enabled 默认设为 false )
8 f! G3 l: K* R2 Y& g    optimizer: {* y. I1 R: Z9 C3 m. F1 a5 C
      enabled: true,  B8 G* R0 K3 z$ V$ k
      runs: 500$ ~' _) p5 z$ `0 F( {: x# y
    },
# C  i4 G5 K* t6 C6 ?, ], i    // 对 Solidity 来说是必须的:用以生成该元数据的文件名和合约名或库名2 y& A8 P: f4 I% k
    compilationTarget: {! v3 j. L- W" o& F# U7 D$ [
      "myFile.sol": "MyContract"
5 i2 c* {1 ~1 U/ Y    },
% o0 E5 N8 ^+ x    // 对 Solidity 来说是必须的:所使用的库的地址6 v# p5 T, n  n" H* ^, O2 w& N
    libraries: {6 I. G+ v; h" W! Y6 l; R
      "MyLib": "0x123123..."
, ?6 O4 e: V; p# p  }( H) i* Q    }3 h/ ?# U- ~4 a
  },
3 R" F+ ~, B( h4 `# p  // 必选:合约的生成信息7 t) U# Q4 {7 o
  output:
/ i* s; K- L/ U) v  {# A6 H  {/ c- B. U. m; l0 B, D* @1 ^
    // 必选:合约的 ABI 定义
, p1 J3 @) s$ C! j) }! j* I    abi: [ ... ],* @* J* o0 |/ u5 n
    // 必选:合约的 NatSpec 用户文档3 A4 }( c$ y+ F) F  T. g! H
    userdoc: [ ... ],9 y* L& J6 A0 i; K. v
    // 必选:合约的 NatSpec 开发者文档
$ I/ Y2 }% X- O8 ?! Y    devdoc: [ ... ],
6 }0 {8 {4 P! M" [. ?  }4 p/ q( ^  ~) M' I  J3 ~; l+ X& c
}0 s3 \$ l- W+ o: \% \9 Q/ v) h
… note::5 Z3 k9 D( J0 i. w# O
需注意,上面的 ABI 没有固定的顺序,随编译器的版本而不同。" q; o2 @  B1 a5 O; U
… note::4 k! C) |, m1 W$ g- @$ ?2 d5 X2 A6 P0 s
由于生成的合约的字节码包含元数据的哈希值,因此对元数据的任何更改都会导致字节码的更改。2 r5 ~4 @. d3 j3 y' F' Z: g
此外,由于元数据包含所有使用的源代码的哈希值,所以任何源代码中的,5 |' c' _7 e7 ^. I9 `: `
哪怕是一个空格的变化都将导致不同的元数据,并随后产生不同的字节代码。8 G2 d' ^. ~$ `8 {
元数据哈希字节码的编码% a0 E; K0 t! b' ?, ~
由于在将来我们可能会支持其他方式来获取元数据文件,
/ v( w- v9 u5 e& N& y类似 {"bzzr0":} 的键值对,将会以 CBOR _ 编码来存储。
) R% c: Y1 {$ ?6 B由于这种编码的起始位不容易找到,因此添加两个字节来表述其长度,以大端方式编码。
- H: C; Y8 U% Q; U0 H所以,当前版本的Solidity编译器,将以下内容添加到部署的字节码的末尾::
8 U8 n+ s; T1 o; G& k" u6 I  H0xa1 0x65 'b' 'z' 'z' 'r' '0' 0x58 0x20  0x00 0x29
4 p! u) q1 u* j) A( \3 [1 ]" L因此,为了获取数据,可以检查部署的字节码的末尾以匹配该模式,并使用 Swarm 哈希来获取元数据文件。; I1 R, X# R" D4 j5 h  s6 e
自动化接口生成和 |natspec| 的使用方法) Y+ \8 H0 L7 s7 m; S1 ]" S
元数据以下列方式被使用:想要与合约交互的组件(例如,Mist)读取合约的字节码,
8 l" S5 E  g% }$ D$ Z从中获取元数据文件的 Swarm 哈希,然后从 Swarm 获取该文件。该文件被解码为上面的 JSON 结构。) {4 k& V$ z3 o6 I: f$ s6 N) ?
然后该组件可以使用ABI自动生成合约的基本用户接口。
$ |" V7 J  r: J) X( V4 u此外,Mist可以使用 userdoc 在用户与合约进行交互时向用户显示确认消息。7 U! O: D, W/ `+ {
有关 |natspec| 的其他信息可以在 这里 _ 找到。
  U5 G9 V. H/ b: |5 |源代码验证的使用方法" g. v$ ^* X9 G& M- Z
为了验证编译,可以通过元数据文件中的链接从 Swarm 中获取源代码。8 H7 G3 w7 y" o2 e! p. d' b5 k
获取到的源码,会根据元数据中指定的设置,被正确版本的编译器(应该为“官方”编译器之一)所处理。
5 [8 T$ p! P6 k+ H处理得到的字节码会与创建交易的数据或者 CREATE 操作码使用的数据进行比较。! |! J: j/ }# k. ~
这会自动验证元数据,因为它的哈希值是字节码的一部分。9 @' |0 |3 T' `4 v% J
而额外的数据,则是与基于接口进行编码并展示给用户的构造输入数据相符的。
标签: Solidity
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

飞儿506 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11