Solidity

你能解釋一下為什麼我們必須訪問字節變數“functionCallData”四次才能獲得選擇器嗎?

  • September 10, 2022

為什麼我們會得到這樣的函式選擇器,為什麼我們要多次使用那個字節變數 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]
           )
       );
   }

}

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