你能解釋一下為什麼我們必須訪問字節變數“functionCallData”四次才能獲得選擇器嗎?
為什麼我們會得到這樣的函式選擇器,為什麼我們要多次使用那個字節變數 functionCallData 呢?提前致謝!
function getSelectorTwo() public view returns (bytes4 selector) { bytes memory functionCallData = abi.encodeWithSignature( "transfer(address,uint256)", address(this), 123 ); selector = bytes4( bytes.concat( functionCallData[0], functionCallData[1], functionCallData[2], functionCallData[3] ) ); }
該
bytes
類型就像一個數組,其中數組中的每個元素都是 1 個字節。該函式正在使用它期望的參數值(和 )
getSelectorTwo()
對函式選擇器進行編碼。transfer(address,uint256)``address``uint256
如果您列印
functionCallData
,您將看到以下字節:
0xa9059cbb00000000000000000000000059235ef80c8c63b480734c6888754f464fdb212d000000000000000000000000000000000000000000000000000000000000007b
注意前四個字節是函式選擇器
a9059cbb
。然後以下 32 個字節是該合約的地址(左填充零):
00000000000000000000000059235ef80c8c63b480734c6888754f464fdb212d
然後以下 32 個字節是
123
十六進制數(左填充零):
000000000000000000000000000000000000000000000000000000000000007b
7b
十六進制是123
十進制。因此,該程式碼訪問
functionCallData
字節數組 4 次的原因是因為它正在複製該數據的前 4 個字節,我們知道它是函式選擇器:
functionCallData[0] = a9 functionCallData[1] = 05 functionCallData[2] = 9c functionCallData[3] = bb
它連接它並返回它。它不能做類似
functionCallData[0:4]
從functionCallData
字節數組複製範圍的事情,因為切片運算符僅在calldata
字節數組中可用,而不是在本地或儲存數組上(目前)。所以它必須手動複製它,無論是循環還是索引索引,就像它正在做的那樣。在下面檢查並嘗試我的
getTransferFunctionSelectorWithParams
功能://SPDX-License-Identifier: MIT pragma solidity ^0.8.16; contract Contract { function getTransferFunctionSelectorWithParams() public view returns(bytes memory) { bytes memory functionCallData = abi.encodeWithSignature( "transfer(address,uint256)", address(this), 123 ); return functionCallData; } function getSelectorTwo() public view returns (bytes4 selector) { bytes memory functionCallData = abi.encodeWithSignature( "transfer(address,uint256)", address(this), 123 ); selector = bytes4( bytes.concat( functionCallData[0], functionCallData[1], functionCallData[2], functionCallData[3] ) ); } }