Solidity

calldata如何儲存在記憶體中?

  • March 16, 2021

當我執行這個:

bytes8 h = 0x000008dfe2f440000733c;
t.call.gas(0x7e0b0)(bytes4(keccak256("enter(bytes8)")),0x8dfe2f440000733c0000000,h);

呼叫數據是:

0: 0x3370204e000000000000000000000000000000000000000008dfe2f440000733c00000008dfe2f440000733c000000000000000000000000000000000000000000000000

我將其拆分為 32 個字節:

3370204e000000000000000000000000000000000000000008dfe2f440000733
c00000008dfe2f440000733c0000000000000000000000000000000000000000   
00000000   

為什麼是這樣?

3370204e // bytes4(keccak256("enter(bytes8)"))
000000000000000000000000000000000000000008dfe2f440000733c0000000 // 0x8dfe2f440000733c0000000 uint96 padded to 32 bytes
8dfe2f440000733c000000000000000000000000000000000000000000000000 // 0x000008dfe2f440000733c bytes8 padded to 32 bytes

文件

此外,為了與不遵守 ABI 的合約互動,提供了函式呼叫,該函式呼叫採用任意數量的任何類型的參數。這些參數被填充到 32 個字節並連接起來。一個例外是第一個參數被編碼為恰好四個字節的情況。在這種情況下,它沒有被填充以允許在此處使用函式簽名。

請注意, uintN 是左填充的,而 bytesN 是右填充的。從文件

uint<M>:enc(X) 是 X 的大端編碼,在高階(左)側用零字節填充,使得長度為 32 字節。

bytes<M>:enc(X) 是 X 中的字節序列,用尾隨零字節填充,長度為 32 個字節。

就像@libertylocked 在他們的評論中所說的那樣,函式選擇器是 4 個字節,因此您必須在拆分為 32 個字節之前刪除這 4 個字節才能獲得單個單詞。

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