Solidity

Solidity 合約字節碼末尾的神秘部分是什麼?

  • August 30, 2019

鑑於以下契約:

pragma solidity ^0.4.11;

contract Simple {
   bytes32 public v;
   function set(bytes32 _v) {
       v = _v;
   }
}

反彙編時remixsolcevm都不能正確解釋程式碼的尾端。此外,程式碼似乎無法訪問(它遵循 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 開始,元數據格式如下所示:

堅固度 0.5.9

還有一句警告:

編譯器目前使用元數據的“swarm version 0”散列,但未來可能會改變,所以不要依賴這個序列以 0xa2 0x65 ‘b’ ‘z’ ‘z’ ‘r’ ‘0’ 開頭. 我們可能還會向這個 CBOR 結構添加額外的數據,所以最好的選擇是使用適當的 CBOR 解析器。

引用自:https://ethereum.stackexchange.com/questions/23525