Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Solidity合约元数据

飞儿506
210 0 0
Solidity编译器自动生成JSON文件,即合约的元数据,其中包含了当前合约的相关信息。
6 ?+ A2 i. o  `+ h* C" P/ |# I它可以用于查询编译器版本,所使用的源代码,|ABI| 和 |natspec| 文档,以便更安全地与合约进行交互并验证其源代码。8 |1 B, W) j0 z3 B
编译器会将元数据文件的 Swarm 哈希值附加到每个合约的字节码末尾(详情请参阅下文),
$ _9 o& S( [( C( x" [8 f' w& K$ K. i以便你可以以认证的方式获取该文件,而不必求助于中心化的数据提供者。
% I" m% g& i( _$ n+ x& j当然,你必须将元数据文件发布到 Swarm (或其他服务),以便其他人可以访问它。. C% f) t" `$ ]# X/ x; `
该文件可以通过使用 solc --metadata 来生成,并被命名为 ContractName_meta.json 。& J* w! j0 @# c; f
它将包含源代码的在 Swarm 上的引用,因此你必须上传所有源文件和元数据文件。/ ~4 B' T! M4 {( i/ L) d, r
元数据文件具有以下格式。 下面的例子将以人类可读的方式呈现。- x: D2 x3 l0 F3 ]  m
正确格式化的元数据应正确使用引号,将空白减少到最小,并对所有对象的键值进行排序以得到唯一的格式。/ ?* i' O8 B, q4 N' [. H& o3 f% P' \
代码注释当然也是不允许的,这里仅用于解释目的。
2 R1 J2 |+ R8 z  V, @$ J{1 `! ~; ?. k: {6 t: r! o- s
  // 必选:元数据格式的版本: A- G9 N+ O6 |5 w+ `1 p3 V+ L
  version: "1",2 H; l0 e) R/ L% o4 l
  // 必选:源代码的编程语言,一般会选择规范的“子版本”
4 v6 k$ L& q- T  language: "Solidity",
: f! _& J8 h6 E) a  // 必选:编译器的细节,内容视语言而定。5 z0 O6 M( k1 O% N, {& ]
  compiler: {
, h# W6 q0 W6 Y    // 对 Solidity 来说是必须的:编译器的版本% E; D' V6 c; ^  V
    version: "0.4.6+commit.2dabbdf0.Emscripten.clang",
, Y5 M8 r9 [# ^/ C! {    // 可选: 生成此输出的编译器二进制文件的哈希值
/ K+ d3 t6 U/ M3 n    keccak256: "0x123..."1 J; K( l1 b/ d) O! k9 g" G
  },
. q9 N* d) x7 m! U) P9 p, n  // 必选:编译的源文件/源单位,键值为文件名
/ e  u# E: q) @0 A5 F5 ~  sources:
% _! F/ ~# h3 j3 ~4 k$ }  {
8 S- [8 Z2 @) L    "myFile.sol": {  u9 S2 M6 u1 R/ T. O) _
      // 必选:源文件的 keccak256 哈希值$ m* j% h* Y! m  k/ N
      "keccak256": "0x123...",# \* N) K1 x& B6 z6 E$ w6 o
      // 必选(除非定义了“content”,详见下文):
- L' M$ ^/ Z5 q( I, A      // 已排序的源文件的URL,URL的协议可以是任意的,但建议使用 Swarm 的URL
0 F1 {* Y- s% c+ l& W# S$ I      "urls": [ "bzzr://56ab..." ]8 e/ ^$ z, W" [; w3 l, ^* ~
    },4 p, n$ X) g# b, [1 I
    "mortal": {
& m! W6 q: o2 r0 q0 W      // 必选:源文件的 keccak256 哈希值7 a" n7 b* v4 M% K. j0 J# Z" q
      "keccak256": "0x234...",4 }8 u: e4 G6 u7 M
      // 必选(除非定义了“urls”): 源文件的字面内容# a/ F7 M5 q$ |! C" b
      "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }"
1 n3 w% t5 @7 Q9 I    }" ?9 M- k. o/ G' H
  },2 ^- l* o2 k: m. z
  // 必选:编译器的设置
8 K9 l8 \4 ?( v" O3 v  settings:$ V+ E6 @4 s9 t2 A5 R( z+ W' u
  {
( M% M2 Q4 x7 k! `. y5 x7 Q    // 对 Solidity 来说是必须的: 已排序的重定向列表3 W8 y6 ?+ X% t6 f2 N
    remappings: [ ":g/dir" ],3 F" U8 G( Q7 ]+ e  z
    // 可选: 优化器的设置( enabled 默认设为 false )1 k2 U! F2 P0 F, V
    optimizer: {: f! q/ r+ x/ o* T
      enabled: true,5 |; X/ A. Q- o5 K+ P
      runs: 500, ]5 R2 M  G$ L2 c( ~9 {
    },! ]' f6 k9 [% x
    // 对 Solidity 来说是必须的:用以生成该元数据的文件名和合约名或库名
/ x$ B. z" u. |    compilationTarget: {3 U$ n: ^/ _7 l& q) a" c
      "myFile.sol": "MyContract"* S7 E" m5 d& ?) \$ k1 W
    },+ ]1 n# `8 [+ P5 S
    // 对 Solidity 来说是必须的:所使用的库的地址0 J: z$ E: k& q% s% m- @& L8 M
    libraries: {1 P' P, k& g- Y' m. U# l( |: R
      "MyLib": "0x123123..."
3 ^- D" z" i( p9 \8 x; l5 Z1 z    }+ i2 e- F, R; Z7 L. j: b
  },; q/ s+ E4 Y1 s* i% |) m
  // 必选:合约的生成信息% W1 n" P& s; M7 k
  output:: @$ B5 v( s- e
  {
1 r2 w3 U, \2 V8 C& ~0 v    // 必选:合约的 ABI 定义+ `) V' \" i, h* _' E8 q+ P6 A# x0 ]
    abi: [ ... ],
2 P2 a+ I+ {$ p' v) t    // 必选:合约的 NatSpec 用户文档
2 L2 \  E8 R, w( V: f" D$ c0 R) T    userdoc: [ ... ]," K5 ]# N1 T. B: z# Y
    // 必选:合约的 NatSpec 开发者文档
9 G$ L2 |4 Z( r4 i( m6 \    devdoc: [ ... ],5 d9 Y6 t! O( t+ U0 |
  }
7 F% d' d; a0 D& E. N}  K/ z2 z0 V" V; ]% b
… note::5 g  m& f/ g' J+ Y5 u& \+ e
需注意,上面的 ABI 没有固定的顺序,随编译器的版本而不同。7 _+ A2 {$ \0 J5 g' }% B
… note::6 L8 a5 P- V7 f0 l$ j. ^
由于生成的合约的字节码包含元数据的哈希值,因此对元数据的任何更改都会导致字节码的更改。
% r9 I4 B2 h; p0 {- s1 i" L' E此外,由于元数据包含所有使用的源代码的哈希值,所以任何源代码中的,5 J/ G+ s4 n& K4 W1 W
哪怕是一个空格的变化都将导致不同的元数据,并随后产生不同的字节代码。
8 N, _' J3 H# f% ~* @9 S元数据哈希字节码的编码+ i0 p, T& p! d; o0 `7 B" M3 Q
由于在将来我们可能会支持其他方式来获取元数据文件,
% q/ B  \, A0 J6 z类似 {"bzzr0":} 的键值对,将会以 CBOR _ 编码来存储。
) c! m) ?& H3 a9 T1 Y由于这种编码的起始位不容易找到,因此添加两个字节来表述其长度,以大端方式编码。  h: t8 S' I* |! b5 P' x
所以,当前版本的Solidity编译器,将以下内容添加到部署的字节码的末尾::
3 q0 P7 B( v% f5 i, F* @) B0xa1 0x65 'b' 'z' 'z' 'r' '0' 0x58 0x20  0x00 0x29' T" [/ f( h3 t' ~2 {9 C" ]8 k! {
因此,为了获取数据,可以检查部署的字节码的末尾以匹配该模式,并使用 Swarm 哈希来获取元数据文件。* t/ s9 P0 x# L1 D
自动化接口生成和 |natspec| 的使用方法
+ p+ M) `: }& u元数据以下列方式被使用:想要与合约交互的组件(例如,Mist)读取合约的字节码,
  f) `: g4 y1 `1 B从中获取元数据文件的 Swarm 哈希,然后从 Swarm 获取该文件。该文件被解码为上面的 JSON 结构。; y6 M1 O- z1 C0 W
然后该组件可以使用ABI自动生成合约的基本用户接口。% H9 m7 m# E8 x
此外,Mist可以使用 userdoc 在用户与合约进行交互时向用户显示确认消息。
$ o; P# B% [0 ~+ L- B有关 |natspec| 的其他信息可以在 这里 _ 找到。
* V0 k$ M& l$ H- \0 K源代码验证的使用方法
( v3 Q+ w& t' s+ {& m为了验证编译,可以通过元数据文件中的链接从 Swarm 中获取源代码。; S" c# R6 A1 N7 E! a+ ?
获取到的源码,会根据元数据中指定的设置,被正确版本的编译器(应该为“官方”编译器之一)所处理。1 i  G6 k: R+ V* }2 G
处理得到的字节码会与创建交易的数据或者 CREATE 操作码使用的数据进行比较。
9 \% z1 Q# ~# J' w' ~4 _这会自动验证元数据,因为它的哈希值是字节码的一部分。
6 Y: ~, Y' I4 l4 x  \9 q/ w! n而额外的数据,则是与基于接口进行编码并展示给用户的构造输入数据相符的。
标签: Solidity
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

飞儿506 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11