Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Solidity合约元数据

飞儿506
255 0 0
Solidity编译器自动生成JSON文件,即合约的元数据,其中包含了当前合约的相关信息。) t6 H% s' l0 p
它可以用于查询编译器版本,所使用的源代码,|ABI| 和 |natspec| 文档,以便更安全地与合约进行交互并验证其源代码。
, B% ~7 A* D& P& Q编译器会将元数据文件的 Swarm 哈希值附加到每个合约的字节码末尾(详情请参阅下文),+ j5 \* Y! Q7 \, i$ f  x
以便你可以以认证的方式获取该文件,而不必求助于中心化的数据提供者。2 ]0 s' N+ s* v# b, f
当然,你必须将元数据文件发布到 Swarm (或其他服务),以便其他人可以访问它。
/ X1 @7 A: o0 r2 ~. i0 b该文件可以通过使用 solc --metadata 来生成,并被命名为 ContractName_meta.json 。
- t' \) J1 r5 J; L& l& U它将包含源代码的在 Swarm 上的引用,因此你必须上传所有源文件和元数据文件。
- U' W+ P3 `5 ]2 H1 R1 f元数据文件具有以下格式。 下面的例子将以人类可读的方式呈现。9 z) J, y6 K" W4 S. k+ O7 V
正确格式化的元数据应正确使用引号,将空白减少到最小,并对所有对象的键值进行排序以得到唯一的格式。
0 g5 [- {4 {6 {# m% \- @代码注释当然也是不允许的,这里仅用于解释目的。9 C* N/ B4 V% v. O; }" r+ Z% Z
{
& I! s7 f: ~* ^% m/ N. ?  // 必选:元数据格式的版本3 X* t0 M! |; k1 m5 R1 n
  version: "1",
0 @, g$ I9 d( V* q+ y5 s  // 必选:源代码的编程语言,一般会选择规范的“子版本”+ B% \' r2 ]7 Q" R- y( `# X+ {
  language: "Solidity",$ C- U) N* r1 X) ^0 X( P
  // 必选:编译器的细节,内容视语言而定。
5 k4 d1 Y& _% m- s' W1 C  x  compiler: {% }4 [: r! k( N1 [2 k# o3 R
    // 对 Solidity 来说是必须的:编译器的版本
8 K& @3 w9 z' x4 }: `! L0 h0 M( S    version: "0.4.6+commit.2dabbdf0.Emscripten.clang",) D. P9 ]* {: ]6 F/ `2 z
    // 可选: 生成此输出的编译器二进制文件的哈希值
) Q8 \4 ?3 y( p' v    keccak256: "0x123...": i- d3 W3 j7 k2 o
  },
1 \% @% ?% f( ]; B' n: s  // 必选:编译的源文件/源单位,键值为文件名
4 \$ A! f; V4 y8 P. ^  sources:2 M( N. b' N6 Z" d( L( |  g
  {! T. a5 z" ^# S1 Q, K9 P* x
    "myFile.sol": {2 T5 [6 v8 H% e# w( }
      // 必选:源文件的 keccak256 哈希值
$ v% K/ }% w8 A      "keccak256": "0x123...",
. ~! x6 D* X* p0 d+ N1 O# K  V6 N! F      // 必选(除非定义了“content”,详见下文):
$ @& H& s& ?  U" u0 S      // 已排序的源文件的URL,URL的协议可以是任意的,但建议使用 Swarm 的URL
5 ?7 o, E* k5 D0 u% u      "urls": [ "bzzr://56ab..." ]# @4 G( Z% L# `" n5 C* L
    },3 i( T* m! z, n; D, M+ |) k
    "mortal": {
/ D( D* c# O& B. g' Z; O      // 必选:源文件的 keccak256 哈希值2 |( Z9 N. e" y; i' `4 g
      "keccak256": "0x234...",
: n5 v) f/ d2 `* K% e      // 必选(除非定义了“urls”): 源文件的字面内容
7 D2 P% c0 Y% _" K& v0 A      "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }") Y4 L: f. X5 A* }# m. B: J& c
    }
0 P  f$ t* N; K. ?8 s1 D  },
- ]1 ?, V! w  L  // 必选:编译器的设置/ e5 f7 v2 q. l( s- U0 A
  settings:
8 M; e6 {3 s& E" r" D/ H  {
( w% o% d) ^) a) B0 }6 z    // 对 Solidity 来说是必须的: 已排序的重定向列表' U6 N6 V6 R( W% T# ~4 _1 _
    remappings: [ ":g/dir" ],2 |4 f/ M+ J" j4 d  `5 g: d; Z
    // 可选: 优化器的设置( enabled 默认设为 false )
& ~' N( I% q! r- x; P    optimizer: {
4 H( p( H, S1 l, j% I      enabled: true,
+ M5 q$ J8 z( L  [' Y      runs: 500
7 }$ T6 u; x" X. V    },
( Q; i1 B3 }9 d  H    // 对 Solidity 来说是必须的:用以生成该元数据的文件名和合约名或库名
: l/ Z  P. U+ H  u9 U1 {    compilationTarget: {
, s6 T  m" `7 a2 o2 I& @3 L* m      "myFile.sol": "MyContract"
( V  d  |; t. m! l    },
! _6 k3 r* @* u5 g    // 对 Solidity 来说是必须的:所使用的库的地址; @# K, X, z, \, p8 J  R3 A& l
    libraries: {
' Q' b/ @% q' r, x      "MyLib": "0x123123..."
' Z  I: K- l- y$ e7 l/ m    }( i: v/ G* y/ ^9 Q* V+ I
  },
6 {$ S, F- H" Y1 t. a. M  // 必选:合约的生成信息
/ i+ k! u* L* s2 x0 z2 v; m  output:, t7 v/ O2 h) h$ e  ]
  {1 q" L  x' B' |: y0 M
    // 必选:合约的 ABI 定义) b9 c% }- {2 y  Z
    abi: [ ... ],
* Z' j0 c: m$ J5 ]+ k. V% ]    // 必选:合约的 NatSpec 用户文档
1 L3 q# ?2 V' b" w8 r  l    userdoc: [ ... ],
- ~0 U6 C6 A& A9 s    // 必选:合约的 NatSpec 开发者文档% g5 o+ t9 x% Z2 Y
    devdoc: [ ... ],& P+ c% i0 v9 G5 J
  }  O1 r0 `; @& e
}  J2 t$ U% C( s6 v! ]# h
… note::
4 O8 m) r0 \: |$ N需注意,上面的 ABI 没有固定的顺序,随编译器的版本而不同。
( _$ `9 p) p8 u- [0 g… note::' I9 t* l9 }4 [. Q) D( i
由于生成的合约的字节码包含元数据的哈希值,因此对元数据的任何更改都会导致字节码的更改。
7 M$ r; L# e) \此外,由于元数据包含所有使用的源代码的哈希值,所以任何源代码中的,
% I. G# q( m5 \: V- r5 q0 [哪怕是一个空格的变化都将导致不同的元数据,并随后产生不同的字节代码。1 {) R, P# Q5 s/ K1 }
元数据哈希字节码的编码
: t. F) ~' R0 f由于在将来我们可能会支持其他方式来获取元数据文件,4 E( @: c; W9 H0 u' B
类似 {"bzzr0":} 的键值对,将会以 CBOR _ 编码来存储。1 m0 V! q! R( N2 q
由于这种编码的起始位不容易找到,因此添加两个字节来表述其长度,以大端方式编码。6 O, }' H7 O, h9 _* Y
所以,当前版本的Solidity编译器,将以下内容添加到部署的字节码的末尾::
7 a9 h0 }* A. x- p! q4 @0xa1 0x65 'b' 'z' 'z' 'r' '0' 0x58 0x20  0x00 0x29
! \' x: A1 z0 J; y因此,为了获取数据,可以检查部署的字节码的末尾以匹配该模式,并使用 Swarm 哈希来获取元数据文件。
, X4 W$ Q- j* `/ Z自动化接口生成和 |natspec| 的使用方法# c8 |& i$ ~9 K- b( b
元数据以下列方式被使用:想要与合约交互的组件(例如,Mist)读取合约的字节码,& c2 ^- [8 F6 \  a, x7 u
从中获取元数据文件的 Swarm 哈希,然后从 Swarm 获取该文件。该文件被解码为上面的 JSON 结构。
) m. E2 w' o% T, C# K" q- Y' l然后该组件可以使用ABI自动生成合约的基本用户接口。
( E1 N5 ?* n! _7 k6 }; E此外,Mist可以使用 userdoc 在用户与合约进行交互时向用户显示确认消息。
8 }  {- g; V  {, ?有关 |natspec| 的其他信息可以在 这里 _ 找到。
4 k% o8 |9 j2 M+ V& A) d2 r9 a源代码验证的使用方法- Z* i( ?6 I4 |& z" M' X
为了验证编译,可以通过元数据文件中的链接从 Swarm 中获取源代码。9 k8 g1 Y( }1 `1 Z; N
获取到的源码,会根据元数据中指定的设置,被正确版本的编译器(应该为“官方”编译器之一)所处理。
, K* |( H; A, A# \3 S处理得到的字节码会与创建交易的数据或者 CREATE 操作码使用的数据进行比较。3 E/ Y; L/ O# P" K  A) P4 m
这会自动验证元数据,因为它的哈希值是字节码的一部分。
8 W; B: g; E- k6 X而额外的数据,则是与基于接口进行编码并展示给用户的构造输入数据相符的。
标签: Solidity
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

飞儿506 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11