Solidity合约元数据
飞儿506
发表于 2022-12-31 04:38:06
149
0
0
它可以用于查询编译器版本,所使用的源代码,|ABI| 和 |natspec| 文档,以便更安全地与合约进行交互并验证其源代码。* S* m/ z' _; N& T* k/ L L
编译器会将元数据文件的 Swarm 哈希值附加到每个合约的字节码末尾(详情请参阅下文),; f6 L. F. j2 ? T4 s8 d" ?0 ?% T
以便你可以以认证的方式获取该文件,而不必求助于中心化的数据提供者。; O% Y- r+ D* D' C w: i
当然,你必须将元数据文件发布到 Swarm (或其他服务),以便其他人可以访问它。
该文件可以通过使用 solc --metadata 来生成,并被命名为 ContractName_meta.json 。
它将包含源代码的在 Swarm 上的引用,因此你必须上传所有源文件和元数据文件。
元数据文件具有以下格式。 下面的例子将以人类可读的方式呈现。 s# N: e8 I ~/ Y; G3 B! t
正确格式化的元数据应正确使用引号,将空白减少到最小,并对所有对象的键值进行排序以得到唯一的格式。
代码注释当然也是不允许的,这里仅用于解释目的。+ }# b, B0 n3 z: z- f, _
{
// 必选:元数据格式的版本
version: "1",
// 必选:源代码的编程语言,一般会选择规范的“子版本”9 N# t# i p% d6 l/ w
language: "Solidity",7 r: ^( R- F8 Q$ o3 F7 o
// 必选:编译器的细节,内容视语言而定。. z, A/ q& |% z8 u6 O$ m! Z
compiler: {
// 对 Solidity 来说是必须的:编译器的版本
version: "0.4.6+commit.2dabbdf0.Emscripten.clang",
// 可选: 生成此输出的编译器二进制文件的哈希值
keccak256: "0x123..."
},
// 必选:编译的源文件/源单位,键值为文件名* t) m/ P/ x( m- Q' w1 D8 p
sources:, m) k4 Q' }4 ~4 r1 v
{% K- A" d$ Z+ u2 ?* y
"myFile.sol": {
// 必选:源文件的 keccak256 哈希值
"keccak256": "0x123...",
// 必选(除非定义了“content”,详见下文):" `$ h+ c5 w8 n0 o, C
// 已排序的源文件的URL,URL的协议可以是任意的,但建议使用 Swarm 的URL
"urls": [ "bzzr://56ab..." ]
},
"mortal": {- G7 g! u- ]5 g$ p7 c2 _: H
// 必选:源文件的 keccak256 哈希值
"keccak256": "0x234...",& E: C5 R1 Y+ f% N3 m3 G3 p
// 必选(除非定义了“urls”): 源文件的字面内容
"content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }" r3 B2 y/ N2 @" i1 C7 q9 i1 W
}
},* j4 |7 q8 T( C% Y
// 必选:编译器的设置9 L+ ~) } x1 [% Z
settings:5 t' k4 X. a% y# Y0 J; F2 e: n# _" c
{# l3 U+ F% ]7 S* ^5 w
// 对 Solidity 来说是必须的: 已排序的重定向列表
remappings: [ ":g/dir" ],( M$ J2 K" a! z Q9 ]) t
// 可选: 优化器的设置( enabled 默认设为 false )4 ^3 R" p& p% y1 l- ~" R
optimizer: {/ W' y# s1 h2 w( A$ L$ t
enabled: true,
runs: 500
},
// 对 Solidity 来说是必须的:用以生成该元数据的文件名和合约名或库名
compilationTarget: {
"myFile.sol": "MyContract") a1 O$ d$ e) U Q8 y+ V9 L
},0 _4 X) m! o4 f9 I
// 对 Solidity 来说是必须的:所使用的库的地址, `1 {# o3 w# ~% a; \0 U& h
libraries: {, W2 l* b. f7 P5 M7 v2 O
"MyLib": "0x123123..."
}! I8 ^7 I$ K: r7 ]; l& P
},: V7 Y, t/ r( l- n5 w2 }
// 必选:合约的生成信息, ^2 A) N: W- D+ o4 v
output:8 [( s D& e p$ ? Z( j2 g$ {
{& R7 A$ u5 P; Z5 s. d y
// 必选:合约的 ABI 定义. ^. h% {$ n- {& w x+ w9 z
abi: [ ... ],' o& r! B) m& K8 X* L$ ~3 V G5 A
// 必选:合约的 NatSpec 用户文档9 J2 L {8 D7 s- u T' V j3 A
userdoc: [ ... ],
// 必选:合约的 NatSpec 开发者文档8 \5 p3 T+ [/ i# u1 e* v/ k8 `
devdoc: [ ... ],) _" p( Q5 X# K) Z* y* x
}. ?' l4 Z% v: A e/ w) b) y, t
}0 K) X6 N2 N- X: Z# S$ Z# F' D
… note::8 [4 ?9 q/ h4 B
需注意,上面的 ABI 没有固定的顺序,随编译器的版本而不同。
… note::
由于生成的合约的字节码包含元数据的哈希值,因此对元数据的任何更改都会导致字节码的更改。
此外,由于元数据包含所有使用的源代码的哈希值,所以任何源代码中的,
哪怕是一个空格的变化都将导致不同的元数据,并随后产生不同的字节代码。
元数据哈希字节码的编码/ L2 u; L+ X( k0 {1 J8 g
由于在将来我们可能会支持其他方式来获取元数据文件,
类似 {"bzzr0":} 的键值对,将会以 CBOR _ 编码来存储。9 P7 j" I- m. j. p/ x
由于这种编码的起始位不容易找到,因此添加两个字节来表述其长度,以大端方式编码。
所以,当前版本的Solidity编译器,将以下内容添加到部署的字节码的末尾::
0xa1 0x65 'b' 'z' 'z' 'r' '0' 0x58 0x20 0x00 0x29' r; h- i) w' m4 E3 F$ Q: s% M
因此,为了获取数据,可以检查部署的字节码的末尾以匹配该模式,并使用 Swarm 哈希来获取元数据文件。 b: E& k1 k# i% _9 i) G
自动化接口生成和 |natspec| 的使用方法
元数据以下列方式被使用:想要与合约交互的组件(例如,Mist)读取合约的字节码,
从中获取元数据文件的 Swarm 哈希,然后从 Swarm 获取该文件。该文件被解码为上面的 JSON 结构。
然后该组件可以使用ABI自动生成合约的基本用户接口。 i2 l. A5 | R% J8 `8 J
此外,Mist可以使用 userdoc 在用户与合约进行交互时向用户显示确认消息。+ K6 L$ H( {$ v; d. x8 j- U7 J
有关 |natspec| 的其他信息可以在 这里 _ 找到。% B/ l, W, D Z& z$ d
源代码验证的使用方法
为了验证编译,可以通过元数据文件中的链接从 Swarm 中获取源代码。
获取到的源码,会根据元数据中指定的设置,被正确版本的编译器(应该为“官方”编译器之一)所处理。
处理得到的字节码会与创建交易的数据或者 CREATE 操作码使用的数据进行比较。7 n% w: ?/ ?: y; ]
这会自动验证元数据,因为它的哈希值是字节码的一部分。
而额外的数据,则是与基于接口进行编码并展示给用户的构造输入数据相符的。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
成为第一个吐槽的人