Solidity
calldata如何儲存在記憶體中?
當我執行這個:
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 個字節才能獲得單個單詞。