Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Solidity合约元数据

飞儿506
159 0 0
Solidity编译器自动生成JSON文件,即合约的元数据,其中包含了当前合约的相关信息。
6 E: e! H4 q4 P( x1 Q5 n; }它可以用于查询编译器版本,所使用的源代码,|ABI| 和 |natspec| 文档,以便更安全地与合约进行交互并验证其源代码。
! H& ~  x3 r$ G# |9 N编译器会将元数据文件的 Swarm 哈希值附加到每个合约的字节码末尾(详情请参阅下文),. A7 `( `# t& O; S5 I2 Y4 o8 w5 J
以便你可以以认证的方式获取该文件,而不必求助于中心化的数据提供者。8 k5 C4 v# x( b5 d6 ~3 h
当然,你必须将元数据文件发布到 Swarm (或其他服务),以便其他人可以访问它。4 C7 `% c5 o; w2 U8 _
该文件可以通过使用 solc --metadata 来生成,并被命名为 ContractName_meta.json 。, t, E7 I5 k& _. g$ G$ k
它将包含源代码的在 Swarm 上的引用,因此你必须上传所有源文件和元数据文件。
/ W# o% k* b8 h元数据文件具有以下格式。 下面的例子将以人类可读的方式呈现。3 a1 i1 @2 i# V" u% i% a
正确格式化的元数据应正确使用引号,将空白减少到最小,并对所有对象的键值进行排序以得到唯一的格式。
4 X. a8 t9 K5 J# V' m. Q5 K* U代码注释当然也是不允许的,这里仅用于解释目的。( d7 O6 o& G$ o2 T/ C" C
{
8 H2 T' W  q0 o! O8 m  // 必选:元数据格式的版本
/ A& S, y* r5 |' J/ s3 I& [  version: "1",
, Y9 q4 V) N) h  // 必选:源代码的编程语言,一般会选择规范的“子版本”
  m. B+ [, j9 \& A  language: "Solidity",, C3 z0 T9 M+ o1 U5 C
  // 必选:编译器的细节,内容视语言而定。/ z4 x. p3 H. C# w1 r
  compiler: {. _/ |' K, K6 r/ ], r" w
    // 对 Solidity 来说是必须的:编译器的版本; K, v6 h. M1 ~2 A$ h
    version: "0.4.6+commit.2dabbdf0.Emscripten.clang",: A5 N- c" s: b) a0 U
    // 可选: 生成此输出的编译器二进制文件的哈希值( X  `5 |6 ]) K
    keccak256: "0x123..."9 u: e* ?1 X) n1 N8 S4 a! U- M% V- b
  },* ?& G$ D! W' p7 O. o# s
  // 必选:编译的源文件/源单位,键值为文件名8 e. ?+ H( _2 J$ U# x& o
  sources:
, t5 i1 z# V- ]# Q- J5 o8 m+ N  {7 z& V. w5 b9 B- y
    "myFile.sol": {
" j1 S/ L9 N1 ~/ `( Q1 B      // 必选:源文件的 keccak256 哈希值$ E7 M) K6 J# Y3 d5 _% u7 m) G
      "keccak256": "0x123...",% i$ W5 Z+ u1 C
      // 必选(除非定义了“content”,详见下文):  p7 ?7 N) I6 ~0 G3 ?
      // 已排序的源文件的URL,URL的协议可以是任意的,但建议使用 Swarm 的URL
* a- e. d- \$ ~" _% f      "urls": [ "bzzr://56ab..." ]% g6 `( o* ~1 Z6 u2 L. G
    },3 {2 l5 Z# s. r( `
    "mortal": {( I& k5 G0 d1 g: F" S1 E1 A# [- I
      // 必选:源文件的 keccak256 哈希值
" C" ^1 y" x+ F, J( _6 ]      "keccak256": "0x234...",1 a( K; Y. A+ x; _7 X
      // 必选(除非定义了“urls”): 源文件的字面内容! @$ Q5 E: l9 ^( M$ I
      "content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }"
/ {9 z. R; ~9 z8 A) q8 c$ x" X    }
" F# v$ _8 Y) N: o# V& |$ U  },
- a: Q- U. f- [, d  // 必选:编译器的设置
  l$ ]: d: D$ a# b& G  settings:: [& b% `7 M" m& J1 k3 u* D
  {! Z% Q/ u% ^5 u8 i
    // 对 Solidity 来说是必须的: 已排序的重定向列表, S) U8 V/ N' U8 Z5 T6 Q" z7 z/ g; J
    remappings: [ ":g/dir" ],
  }( F6 C- j3 j# e* S7 |    // 可选: 优化器的设置( enabled 默认设为 false )* w, _! l1 c1 A. z  Y, B
    optimizer: {
: `" m. g- b+ G0 Q  b      enabled: true,
) h1 [; v1 t! N) L6 W      runs: 5007 c3 l/ L  ]. F  E6 N  {% |6 F
    },/ {2 [. |, l# H) M$ E5 a
    // 对 Solidity 来说是必须的:用以生成该元数据的文件名和合约名或库名
: }1 r# ]! b6 n; W. O- Y    compilationTarget: {+ B% ]& B  O0 b- ^
      "myFile.sol": "MyContract"+ B2 r7 |  S: O8 j& m7 }
    },$ u, i4 ]3 A4 c7 C6 n7 M
    // 对 Solidity 来说是必须的:所使用的库的地址5 p( k7 J6 g: @# F# Z1 t& g. H
    libraries: {( ^) h& U; f" G* t1 {- i
      "MyLib": "0x123123..."8 z( a2 A2 |+ r6 l) l1 e3 \
    }
" `# v2 R* _7 Z$ M1 k$ X+ M  },
" K& [* L7 m5 ~" h* U' \( `6 `! [  // 必选:合约的生成信息# T) ]: i7 r  f9 |
  output:2 U0 n8 F% P$ ~4 h
  {1 m9 c* G& R6 U7 m0 s7 E
    // 必选:合约的 ABI 定义9 w) S& [$ H' K: J: a) |4 y1 ?
    abi: [ ... ],) K( o' v$ X+ E- R0 H  A2 J
    // 必选:合约的 NatSpec 用户文档
7 o$ h, N' R5 f9 ]8 k* T% Z    userdoc: [ ... ],: d1 s- A$ r" @3 d
    // 必选:合约的 NatSpec 开发者文档# b0 P$ V- I- c) I" Q/ ?
    devdoc: [ ... ],
" |( Z2 B& T$ P$ T) c  }. x4 r* y4 L! X/ w
}# m, L+ z; O& q5 b$ b) F
… note::
( T0 ^& Z% G0 W3 t需注意,上面的 ABI 没有固定的顺序,随编译器的版本而不同。5 L9 Q0 v2 w! d  |
… note::
; r8 `9 F' X3 V. H% l! K由于生成的合约的字节码包含元数据的哈希值,因此对元数据的任何更改都会导致字节码的更改。5 O+ F% Q1 b: z/ W& X9 n4 |" S: x; D* x
此外,由于元数据包含所有使用的源代码的哈希值,所以任何源代码中的,' s8 t2 l. o4 |% Y$ [7 S' @. m9 R
哪怕是一个空格的变化都将导致不同的元数据,并随后产生不同的字节代码。$ F, }+ S+ T6 l- Y
元数据哈希字节码的编码
" O' ?/ N* B" O8 T  o& F1 {! V2 x由于在将来我们可能会支持其他方式来获取元数据文件,
' T! b! n3 }, O: e$ t  d- Y, v2 E类似 {"bzzr0":} 的键值对,将会以 CBOR _ 编码来存储。
9 Z- m) q' M: i4 C, r2 \1 F. H& e( m由于这种编码的起始位不容易找到,因此添加两个字节来表述其长度,以大端方式编码。
" _+ p& f7 B" I! S; g5 Z# s% w! e所以,当前版本的Solidity编译器,将以下内容添加到部署的字节码的末尾::  K/ ]! A. Y) c- L* ~2 q
0xa1 0x65 'b' 'z' 'z' 'r' '0' 0x58 0x20  0x00 0x29
! q$ n' A9 E2 P3 I' ~- [1 p因此,为了获取数据,可以检查部署的字节码的末尾以匹配该模式,并使用 Swarm 哈希来获取元数据文件。
2 l6 S3 k% f, E: {自动化接口生成和 |natspec| 的使用方法* \1 R. C9 k+ h- o
元数据以下列方式被使用:想要与合约交互的组件(例如,Mist)读取合约的字节码,
+ F( c/ {+ \; T5 S从中获取元数据文件的 Swarm 哈希,然后从 Swarm 获取该文件。该文件被解码为上面的 JSON 结构。* x( W" p  i, M/ u$ m
然后该组件可以使用ABI自动生成合约的基本用户接口。$ U2 G3 [% v1 Y* ^5 U" v
此外,Mist可以使用 userdoc 在用户与合约进行交互时向用户显示确认消息。) L( @4 s9 ]" e9 V# M; V
有关 |natspec| 的其他信息可以在 这里 _ 找到。; g; j2 K! j/ V, j! d
源代码验证的使用方法. O# E' Y, t3 k! `5 R
为了验证编译,可以通过元数据文件中的链接从 Swarm 中获取源代码。
1 M6 s/ e; j6 g9 d8 G! Y& E获取到的源码,会根据元数据中指定的设置,被正确版本的编译器(应该为“官方”编译器之一)所处理。/ v, b/ ?; e. h4 ~
处理得到的字节码会与创建交易的数据或者 CREATE 操作码使用的数据进行比较。
: @3 S4 L! b; h+ R' ~这会自动验证元数据,因为它的哈希值是字节码的一部分。, N( k; o- S) K( f1 F
而额外的数据,则是与基于接口进行编码并展示给用户的构造输入数据相符的。
标签: Solidity
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

飞儿506 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11