Abi

了解彙編中引用類型的第一個 evm 詞

  • March 12, 2019

給定以下功能:

function getArrayItems(bytes calldata) external returns (
   bytes4 _signature,
   bytes32 _wutIsThis,
   bytes32 _length,
   bytes32 _firstItem
) {
   assembly {
       _signature := calldataload(0x00) // trim the first 4 bytes
       _wutIsThis := calldataload(0x04)
       _length := calldataload(0x24)
       _firstItem := calldataload(0x44)
   }
}

當我執行與輸入混合0xcafe的程式碼時,我得到以下輸出:

{   
   "0": "bytes4: _signature 0x38626302",
   "1": "bytes32: _wutIsThis 0x0000000000000000000000000000000000000000000000000000000000000020",
   "2": "bytes32: _length 0x0000000000000000000000000000000000000000000000000000000000000002",
   "3": "bytes32: _firstItem 0xcafe000000000000000000000000000000000000000000000000000000000000"
}

我完全理解第 1 項、第 3 項和第 4 項。_length很棘手,但根據文件

動態數組的長度儲存在數組的第一個槽中,然後是數組元素。

這是第二項,_wutIsThis這給我帶來了麻煩。我的預感是它與數組的數據位置有關。也就是說,數據偏移了0x0000000000000000000000000000000000000000000000000000000000000020,這意味著數組的第一項位於 calldata 中所述位置的位置之後的 32 個字節(我知道,這是元數據)。

那是對的嗎?如果是,我們為什麼要這樣做,我在哪裡可以找到更多的文件?關於類型數據位置的solidity 文件有點含糊,僅說明引用類型必須指定關鍵字(memorystoragekeyword

那是對的嗎?如果是,我們為什麼要這樣做,我在哪裡可以找到更多的文件?

是的,你是對的。

交易根據合約 ABI 規范進行編碼。很難通過,但這些文件有你問題的所有答案。


有問題的事務是傳入一個動態參數 ( bytes) 而不是靜態參數 ( uint,address等)。在對參數進行編碼時,EVM 會查看參數是靜態的還是動態的。

靜態參數以相當簡單的方式編碼——它們被轉換為十六進製表示,然後連接到輸入數據十六進製字元串中。

動態值更有趣。使用文件的這一部分來完全理解,但想法是編碼數據是數據的位置。在所有動態類型之後,編碼數據本身然後連接到輸入數據十六進製字元串的末尾。對於動態類型,然後包含參數的長度,然後是數據本身。

分解您發布的交易:

0x386263020000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002cafe000000000000000000000000000000000000000000000000000000000000

0x38626302

這是被呼叫函式的方法 ID(在本例中為getArrayItems(bytes)

0x0000000000000000000000000000000000000000000000000000000000000020

這是第一個(動態)參數的位置。這是calldata生活的地方,但不是數據本身。

0x0000000000000000000000000000000000000000000000000000000000000002

這是動態的長度calldata。在這種情況下,長度為 2由於方式bytesworks。EVM 將您0xcafe視為 [ 0xca],[ 0xfe],這就是長度為 2 的原因,即使只有一個參數傳入。

cafe000000000000000000000000000000000000000000000000000000000000

傳入的數據calldata

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