Solidity 合約字節碼末尾的神秘部分是什麼?
鑑於以下契約:
pragma solidity ^0.4.11; contract Simple { bytes32 public v; function set(bytes32 _v) { v = _v; } }
反彙編時
remix
,solc
或evm
都不能正確解釋程式碼的尾端。此外,程式碼似乎無法訪問(它遵循 JUMP 指令),而且它似乎做的事情沒有多大意義。
solc
使用and編譯時會產生類似的尾隨程式碼remix
,前綴和後綴類似,但內容略有不同:00a165627a7a72305820...0029
在反彙編中,前綴字節碼被所有人解釋為:
stop log1 push6 0x627a7a723058 sha3 ...
當使用 編譯時
remix
,Web GUI 中的“程序集”欄位將元件描述為“.data”標籤:[...] SSTORE v = _v POP v = _v tag 10 function set(bytes32 _v) {\n ... JUMPDEST function set(bytes32 _v) {\n ... POP function set(bytes32 _v) {\n ... JUMP [out] function set(bytes32 _v) {\n ... .data
因此暗示這根本不是程式碼,而是某種形式的數據欄位。如果是這樣,這是做什麼用的?,一般來說,在這個具體的例子中?
- 混音: 0.4.14+commit.c2215d46.Emscripten.clang
- evm: 1.7.0-不穩定(git commit 3d32690b)
- solc: 0.4.14-develop.2017.7.27+commit.16ca1eea.Linux.g++
執行時字節碼(來自
remix
):60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637c2efcba146047578063db80813f146075575b600080fd5b3415605157600080fd5b60576099565b60405180826000191660001916815260200191505060405180910390f35b3415607f57600080fd5b6097600480803560001916906020019091905050609f565b005b60005481565b80600081600019169055505b505600a165627a7a72305820e62ffd25aaa1132d83ae4470e9f3991cb237178c38401db1857b9417b74603560029
這是Swarm雜湊。它記錄在https://solidity.readthedocs.io/en/develop/metadata.html
提取如下
合約元數據
Solidity 編譯器會自動生成一個 JSON 文件,即合約元數據,其中包含有關目前合約的資訊。它可用於查詢編譯器版本、使用的源、ABI 和 NatSpec 文件,以便更安全地與合約互動並驗證其原始碼。
編譯器將元數據文件的 Swarm 散列附加到每個合約的字節碼的末尾(有關詳細資訊,請參見下文),以便您可以以經過身份驗證的方式檢索文件,而無需求助於集中式數據提供者。
格式如下所示:
如果您要將元數據文件單獨上傳到 Swarm,那麼您合約的未來使用者可以通過合約程式碼中的此引用找到它。
2019 年 8 月更新
從 Solidity 0.5.9 開始,元數據格式如下所示:
還有一句警告:
編譯器目前使用元數據的“swarm version 0”散列,但未來可能會改變,所以不要依賴這個序列以 0xa2 0x65 ‘b’ ‘z’ ‘z’ ‘r’ ‘0’ 開頭. 我們可能還會向這個 CBOR 結構添加額外的數據,所以最好的選擇是使用適當的 CBOR 解析器。