Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Solidity合约元数据

飞儿506
151 0 0
Solidity编译器自动生成JSON文件,即合约的元数据,其中包含了当前合约的相关信息。- Q5 s) P7 k+ p7 J. d6 P3 J% |# `
它可以用于查询编译器版本,所使用的源代码,|ABI| 和 |natspec| 文档,以便更安全地与合约进行交互并验证其源代码。
+ E3 o& f* `' d% d7 d8 g编译器会将元数据文件的 Swarm 哈希值附加到每个合约的字节码末尾(详情请参阅下文),
9 |/ W' t7 q9 j2 M以便你可以以认证的方式获取该文件,而不必求助于中心化的数据提供者。
& |( z* {: g) ^5 \当然,你必须将元数据文件发布到 Swarm (或其他服务),以便其他人可以访问它。  D$ G4 B2 c( u% V6 J- F% a
该文件可以通过使用 solc --metadata 来生成,并被命名为 ContractName_meta.json 。! B/ Q; N9 A* A9 G
它将包含源代码的在 Swarm 上的引用,因此你必须上传所有源文件和元数据文件。
- C% W5 \; q* U1 P元数据文件具有以下格式。 下面的例子将以人类可读的方式呈现。' M( A1 P" G  |8 H/ |& F0 Z
正确格式化的元数据应正确使用引号,将空白减少到最小,并对所有对象的键值进行排序以得到唯一的格式。$ a/ ?; E8 J0 s; ~/ S
代码注释当然也是不允许的,这里仅用于解释目的。
# K% A5 |7 I; X$ a! ^7 T{
# M' c+ s! g& `. H  // 必选:元数据格式的版本. L( `4 Q9 _( \! ?/ a+ {4 d, J' _
  version: "1",5 r5 B1 B9 C: _& V! X- c% Q
  // 必选:源代码的编程语言,一般会选择规范的“子版本”
, \! o( m$ d4 j+ e" R3 C3 D0 w  language: "Solidity",! U- k/ d! W$ J6 M4 T' c
  // 必选:编译器的细节,内容视语言而定。! `0 I# I" ^% ^) F
  compiler: {
9 w/ o$ s6 S1 \9 D    // 对 Solidity 来说是必须的:编译器的版本
- y" s% w- A8 o9 V    version: "0.4.6+commit.2dabbdf0.Emscripten.clang",
. A2 d, T% h3 t1 j  I1 e, T# t    // 可选: 生成此输出的编译器二进制文件的哈希值
4 Q! v9 x5 e* x9 e, L: H5 \    keccak256: "0x123..."2 m2 C- z$ E4 w9 y3 `6 Z0 j
  },
; e! x9 g+ x  u! i; R  // 必选:编译的源文件/源单位,键值为文件名1 p5 {" W* J0 H5 i
  sources:- y6 U& u2 {7 k" S/ p
  {
# w1 r; t0 r, P    "myFile.sol": {
! E% I* }! X" C6 P  t      // 必选:源文件的 keccak256 哈希值  G# k0 [9 p6 l' ]1 Z( I
      "keccak256": "0x123...",
2 w  k9 X6 v) A9 b0 l3 F9 I      // 必选(除非定义了“content”,详见下文):
) [+ n) Y2 H$ [4 g      // 已排序的源文件的URL,URL的协议可以是任意的,但建议使用 Swarm 的URL3 k8 N% b+ P& t% ~
      "urls": [ "bzzr://56ab..." ]% _0 L0 A- `6 Y# A" Z& I# z
    },
) k  }% u# |2 W1 A8 K' r  r    "mortal": {8 n8 e7 ]3 v7 R. K% A
      // 必选:源文件的 keccak256 哈希值4 g8 J" @. S# u7 \- r
      "keccak256": "0x234...",% _5 ^  E: a+ a9 q8 r) m1 D
      // 必选(除非定义了“urls”): 源文件的字面内容* }6 a$ I9 S1 u4 y2 N  }
      "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }"( N9 E& S+ ]) G6 k; f
    }
- b* y, e: l% n6 t/ p2 |! h  },
9 O, A( a0 o- M* R  // 必选:编译器的设置* n/ q) N! \3 M; D' `& M" G7 S
  settings:
( j  U; }0 x, k3 [  {$ ]& v" e! Q% r% ~
    // 对 Solidity 来说是必须的: 已排序的重定向列表
  |! C/ z$ l- w* P9 x    remappings: [ ":g/dir" ],7 J7 E) _4 x0 Y: }
    // 可选: 优化器的设置( enabled 默认设为 false )' P, e/ N6 w' i
    optimizer: {
, N; `; D4 ?& u9 F. v) t      enabled: true,
9 D) N3 b( ^3 s' [- q/ c/ L      runs: 500
9 E7 V/ k1 o$ P    },/ N1 V. _+ s& [, h2 M7 i
    // 对 Solidity 来说是必须的:用以生成该元数据的文件名和合约名或库名
8 r% y4 M- s. G  Y0 r    compilationTarget: {
) K5 l' Y) E; K9 ]. d1 y      "myFile.sol": "MyContract"
% H0 b$ c) Y) s  O5 B    },
3 S! i" }9 s% p# U) `    // 对 Solidity 来说是必须的:所使用的库的地址
9 ^; Y! P6 v3 o: r- v( k  q    libraries: {' _) ?0 g4 i" t! P8 X* M
      "MyLib": "0x123123..."
- [2 o/ t1 G0 ?( t2 G$ Z    }7 }2 ]0 V2 }+ S! t7 D+ x' _
  },
3 q. e  G7 `0 |  v9 S' }& W: ]  // 必选:合约的生成信息/ m, V8 Z) ?8 t5 ~
  output:# f4 F1 e' s9 M8 ~8 Z
  {
7 J/ Q$ y! m) `' k; d) a4 z. r    // 必选:合约的 ABI 定义6 U1 c3 m) U3 J; E
    abi: [ ... ],  {# G2 O3 S4 J4 Q2 t, M8 g( V( f* R
    // 必选:合约的 NatSpec 用户文档2 Q+ Y9 C  b: v1 C/ ~7 g
    userdoc: [ ... ],
8 a7 d9 B1 [, h; [    // 必选:合约的 NatSpec 开发者文档
9 m& ^& N+ T1 _" B    devdoc: [ ... ],
, L+ ^9 S! Y* N) R* h  }5 n( x9 H7 V1 a/ u3 N
}. U6 h4 a, M6 P4 |
… note::
# }0 I: K+ V! Q0 A- l; R0 _2 \需注意,上面的 ABI 没有固定的顺序,随编译器的版本而不同。! ]+ f. L7 G* Q) m, w! K. {# |# z
… note::
/ L, s( b$ N$ [1 f# p由于生成的合约的字节码包含元数据的哈希值,因此对元数据的任何更改都会导致字节码的更改。
0 y% K. p6 d, x; |7 Q: k! a此外,由于元数据包含所有使用的源代码的哈希值,所以任何源代码中的,
4 N+ ~7 e  K3 B$ [5 {* f哪怕是一个空格的变化都将导致不同的元数据,并随后产生不同的字节代码。
! p" ]5 E( F( U4 l" M元数据哈希字节码的编码
5 J* W& S) ^5 n# h* `由于在将来我们可能会支持其他方式来获取元数据文件,+ Z3 h: U! X% I+ i* U) E1 J' X
类似 {"bzzr0":} 的键值对,将会以 CBOR _ 编码来存储。2 Z- v5 o1 [8 h" ~0 s
由于这种编码的起始位不容易找到,因此添加两个字节来表述其长度,以大端方式编码。; T' m% A9 J; ]# f! q2 R- m; J0 l
所以,当前版本的Solidity编译器,将以下内容添加到部署的字节码的末尾::$ R. ]3 m6 f8 g+ ?! ?
0xa1 0x65 'b' 'z' 'z' 'r' '0' 0x58 0x20  0x00 0x29/ s+ r* `/ r9 t: s% Z+ q. j
因此,为了获取数据,可以检查部署的字节码的末尾以匹配该模式,并使用 Swarm 哈希来获取元数据文件。1 X& t6 a& B* p/ Y. U% c4 B* A% r
自动化接口生成和 |natspec| 的使用方法
  r2 D) Q6 q: S& V! v# R3 N元数据以下列方式被使用:想要与合约交互的组件(例如,Mist)读取合约的字节码,/ b$ M# F) l- |8 D0 ~" v! u2 W* v+ V
从中获取元数据文件的 Swarm 哈希,然后从 Swarm 获取该文件。该文件被解码为上面的 JSON 结构。5 h" r% g/ u/ M; }
然后该组件可以使用ABI自动生成合约的基本用户接口。7 M9 J! X# X2 W3 K9 l8 o. d' \
此外,Mist可以使用 userdoc 在用户与合约进行交互时向用户显示确认消息。
/ d6 @( b0 G8 b, s' t. B. d有关 |natspec| 的其他信息可以在 这里 _ 找到。8 x2 x) g% Q" h1 c7 b2 a$ I8 Z# s
源代码验证的使用方法. F( q& i1 z% E- P- y0 V
为了验证编译,可以通过元数据文件中的链接从 Swarm 中获取源代码。  t/ B) m0 L& s' Y2 c9 d' k+ q, {
获取到的源码,会根据元数据中指定的设置,被正确版本的编译器(应该为“官方”编译器之一)所处理。
( M8 `/ m2 F/ K$ c) N, g! T* N# |处理得到的字节码会与创建交易的数据或者 CREATE 操作码使用的数据进行比较。: A7 v; j8 g9 `
这会自动验证元数据,因为它的哈希值是字节码的一部分。
* ]' Q/ @' b" r) C1 U8 g7 U5 r而额外的数据,则是与基于接口进行编码并展示给用户的构造输入数据相符的。
标签: Solidity
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

飞儿506 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11