Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Solidity合约元数据

飞儿506
152 0 0
Solidity编译器自动生成JSON文件,即合约的元数据,其中包含了当前合约的相关信息。4 t; }, t2 n2 |4 c, h
它可以用于查询编译器版本,所使用的源代码,|ABI| 和 |natspec| 文档,以便更安全地与合约进行交互并验证其源代码。
3 L% }7 t" k) b& s编译器会将元数据文件的 Swarm 哈希值附加到每个合约的字节码末尾(详情请参阅下文),
) a2 \# ~5 l. V# S9 f$ W# c. w以便你可以以认证的方式获取该文件,而不必求助于中心化的数据提供者。! C' {" {! h  J- h
当然,你必须将元数据文件发布到 Swarm (或其他服务),以便其他人可以访问它。* ]3 x6 u8 D# o; i4 @8 m, n
该文件可以通过使用 solc --metadata 来生成,并被命名为 ContractName_meta.json 。! k2 }+ Y% g: {5 w/ a
它将包含源代码的在 Swarm 上的引用,因此你必须上传所有源文件和元数据文件。
' O- ?* G! d% u0 }3 |. I元数据文件具有以下格式。 下面的例子将以人类可读的方式呈现。' M- B1 O' X2 X  P+ ~
正确格式化的元数据应正确使用引号,将空白减少到最小,并对所有对象的键值进行排序以得到唯一的格式。  L4 E( H: t" y. x8 y) I
代码注释当然也是不允许的,这里仅用于解释目的。
3 o: z& q0 R/ D( F9 ^{( F6 D2 S8 a; \# |' P3 z
  // 必选:元数据格式的版本1 o) h( v- f9 y; _  S4 ]
  version: "1",, ]' M9 K5 W6 ]0 _5 L; @+ F
  // 必选:源代码的编程语言,一般会选择规范的“子版本”
+ q; f$ S5 |3 m% X& Z% T: \6 v  language: "Solidity",- c' O8 l; s# V& i' U3 M
  // 必选:编译器的细节,内容视语言而定。# J/ r, `+ ?  [
  compiler: {
4 r. c) c$ M4 p' j! Y    // 对 Solidity 来说是必须的:编译器的版本# ~# |$ p8 M; o* ~# S9 p% o
    version: "0.4.6+commit.2dabbdf0.Emscripten.clang",0 A/ j3 E$ N$ ^$ o# G2 b
    // 可选: 生成此输出的编译器二进制文件的哈希值
/ m: ?4 q9 i# T2 [( L' S    keccak256: "0x123..."
% d: B2 Y7 d: U/ z8 V- b0 S0 T  },2 x+ r- s5 m# b0 M
  // 必选:编译的源文件/源单位,键值为文件名
  x2 ~/ r6 s% c) Y  x  sources:
6 e% W6 o( s4 j  {$ `5 V' e3 L3 [
    "myFile.sol": {) e: W9 {$ l6 o2 c
      // 必选:源文件的 keccak256 哈希值
& `9 G9 t" l. [. A1 ?      "keccak256": "0x123...",0 L9 ^' C2 v  i, F# ~1 D
      // 必选(除非定义了“content”,详见下文):6 }8 J$ c4 O# K) }
      // 已排序的源文件的URL,URL的协议可以是任意的,但建议使用 Swarm 的URL
3 f1 h) g9 B4 z5 T" C( d; E      "urls": [ "bzzr://56ab..." ]; J3 Y' I6 X1 J, b+ P( g
    },  w) R* k+ P: L
    "mortal": {" m/ l! E3 B. A1 v- y6 R
      // 必选:源文件的 keccak256 哈希值3 {' _5 @' C! o' |
      "keccak256": "0x234...",
* r9 K0 y# [/ n' ]* N7 C      // 必选(除非定义了“urls”): 源文件的字面内容
9 o+ r$ `6 D2 j7 H      "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }"
. g0 W2 d/ w" z( Y% F' ~    }
" ?: n- v$ h  a3 J) C  },
' x5 R7 b0 c1 s( [& [5 n  // 必选:编译器的设置
; w1 E2 M0 e- \; L  settings:3 g. |( p& h$ s
  {0 U* G' V6 c6 |8 K4 o6 r, u( W( L
    // 对 Solidity 来说是必须的: 已排序的重定向列表( W2 B1 Z3 ?; F) Q5 q; s0 `
    remappings: [ ":g/dir" ],; d! l: a8 F, B& |% t8 j- }1 V3 r
    // 可选: 优化器的设置( enabled 默认设为 false )
$ D' j% h& `' Z/ V' Z" i    optimizer: {" N$ G! f4 \2 |; I
      enabled: true,
7 F+ R0 f7 G1 k# w/ y* t4 ]$ {      runs: 500# k, ^  Z% c) B  o3 C& M8 Q. [
    },
/ B$ ~* w& r1 X( x9 k# Y/ y" |    // 对 Solidity 来说是必须的:用以生成该元数据的文件名和合约名或库名6 q1 _- a9 s( ?- G
    compilationTarget: {
1 ]; D: v4 g$ G1 \  W      "myFile.sol": "MyContract"4 B: _3 ]- k7 }, I. t2 w! n& w
    },/ F& v' p8 ?# d+ x
    // 对 Solidity 来说是必须的:所使用的库的地址
9 O2 X% S1 Y; R; g. n    libraries: {$ x7 `% `( y- m0 m
      "MyLib": "0x123123..."
0 g) Q) i0 K( l0 ^2 ?9 F    }3 U) z; _& T2 C: ~; V
  },/ W2 f+ _. a- _. p" E$ H( \! J
  // 必选:合约的生成信息& X5 m4 _& q8 X4 T
  output:
' U1 }- }$ T- ?( p0 f  {
0 ^, {8 i" l1 a4 Q; @0 s& i    // 必选:合约的 ABI 定义$ B  E: K- K" g4 |1 p# F
    abi: [ ... ],7 \9 j6 [, Z) {& i8 K
    // 必选:合约的 NatSpec 用户文档2 a7 J! f0 Z4 i5 w' [( u
    userdoc: [ ... ],
& D1 m5 ?- l3 w& Y; G    // 必选:合约的 NatSpec 开发者文档
; v& L- n5 t. }    devdoc: [ ... ]," I4 r% [1 q+ L; b  b1 `% X6 }
  }
: b0 t$ s: c8 A1 [6 i! c* B}/ l0 g4 b8 J# O/ m9 W
… note::
0 n# y' q% d3 |: @, x, v) ~需注意,上面的 ABI 没有固定的顺序,随编译器的版本而不同。1 Q. Y" c- a: n
… note::: O: W, T- k! n- K1 A- u
由于生成的合约的字节码包含元数据的哈希值,因此对元数据的任何更改都会导致字节码的更改。
/ j, k, W- k' f+ ^此外,由于元数据包含所有使用的源代码的哈希值,所以任何源代码中的,1 r0 o. f7 F; t  k7 v
哪怕是一个空格的变化都将导致不同的元数据,并随后产生不同的字节代码。
. w3 f4 q& a; i2 M元数据哈希字节码的编码4 Z, {1 |0 B0 z: R: [. _; s
由于在将来我们可能会支持其他方式来获取元数据文件,
  J# _! q" r+ n3 b: y+ \类似 {"bzzr0":} 的键值对,将会以 CBOR _ 编码来存储。+ v8 ?  u1 n  x- v; Y
由于这种编码的起始位不容易找到,因此添加两个字节来表述其长度,以大端方式编码。
& C+ u* \% t  }' ~6 E所以,当前版本的Solidity编译器,将以下内容添加到部署的字节码的末尾::
9 Q/ m! W/ A/ @" w* ~- z0xa1 0x65 'b' 'z' 'z' 'r' '0' 0x58 0x20  0x00 0x29
! v+ ^6 j3 U) q# s1 z因此,为了获取数据,可以检查部署的字节码的末尾以匹配该模式,并使用 Swarm 哈希来获取元数据文件。4 r9 Q2 M$ h- x' g
自动化接口生成和 |natspec| 的使用方法
3 x# w/ x9 Z1 p* O$ k元数据以下列方式被使用:想要与合约交互的组件(例如,Mist)读取合约的字节码,
  z# x6 M$ K6 M  x9 v$ R  \从中获取元数据文件的 Swarm 哈希,然后从 Swarm 获取该文件。该文件被解码为上面的 JSON 结构。
& D/ O. Z! q& w+ R/ C6 W5 W, V/ H然后该组件可以使用ABI自动生成合约的基本用户接口。# i# G! y6 x4 p7 m
此外,Mist可以使用 userdoc 在用户与合约进行交互时向用户显示确认消息。7 A5 O' f9 ~% I% {- [
有关 |natspec| 的其他信息可以在 这里 _ 找到。+ h0 V0 A' _! M6 R! R+ {$ D% p- j' p9 }& }
源代码验证的使用方法
6 r, ~, E" B) O( T为了验证编译,可以通过元数据文件中的链接从 Swarm 中获取源代码。
) _. L9 `4 U3 U8 N5 J) |获取到的源码,会根据元数据中指定的设置,被正确版本的编译器(应该为“官方”编译器之一)所处理。
! b, u. K7 O5 y6 W& A) g处理得到的字节码会与创建交易的数据或者 CREATE 操作码使用的数据进行比较。: l5 p# z  L" F% X9 ?. e" f
这会自动验证元数据,因为它的哈希值是字节码的一部分。
! `) \) @$ E+ _2 {4 E) q* l而额外的数据,则是与基于接口进行编码并展示给用户的构造输入数据相符的。
标签: Solidity
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

飞儿506 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11