Solidity

encodeWithSelector 和 encode 有什麼區別?

  • June 6, 2022

我一直在搞亂這些abi.encode...功能,我想我很好地掌握了這些差異,除了abi.encodeabi.encodeWithSelector. 因為,它們給出了相似但略有不同的結果,所以我不確定何時使用其中一種。

 abi.encodeWithSelector(bytes4(keccak256("add(uint256,uint256)")), 10,10);
 abi.encode(bytes4(keccak256("add(uint256,uint256)")), 10, 10);

encodeWithSelector 的輸出是

0x771602f7000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a

編碼的輸出是

0x771602f700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a

當我使用delegatecall時,encodeWithSelector的返回值為20,正如預期的那樣,但encode是42949672960

法線abi.encode根據 abicoder 對值進行編碼。一個bytes4值被填充到 32 個字節

0x771602f700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a
 ^ first 32 byte word                                            ^ second 32 byte word                                           ^ third 32 byte word

Usingabi.encodeWithSelector允許您通過在開頭添加一個 4 字節選擇器來正確編碼函式呼叫數據(也可以使用 訪問add.selector)。編碼變成

0x771602f7000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a
 ^ 4 bytes selector
         ^ first 32 byte word                                            ^ second 32 byte word

使用 encode 時,該函式從 calldata 中讀取參數及其預期偏移量。當使用 錯誤編碼時abi.encode,第一個參數(4 字節選擇器之後的前 32 個字節)為 0,第二個 32 字節讀取a00000000,因為 calldata 現在是如何移動的,如此處所示(第三個字被簡單地忽略):

0x771602f700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a
 ^ 4 bytes selector
         ^ first 32 byte word                                            ^ second 32 byte word                                           ^ third 32 byte word

0xa00000000 是 42949672960 編碼的。所以abi.encode基本上返回結果add(0, 42949672960)

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