Solidity
encodeWithSelector 和 encode 有什麼區別?
我一直在搞亂這些
abi.encode...
功能,我想我很好地掌握了這些差異,除了abi.encode
和abi.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
Using
abi.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)