Solidity

EXTCODESIZE 為小於 32 的合約返回 32

  • February 16, 2022

我目前正在完成 Ethernaut 挑戰,其中之一是部署一個小合約(執行時字節碼長 10 個字節)。

我正在本地機器上執行測試,並使用 Solidity 部署契約。

我正在使用CREATE操作碼來部署我在契約中明確定義的字節碼。結果與CREATE2.

當我EXTCODESIZE用來取回已部署合約的合約程式碼大小時,它正在返回32,當執行時字節碼大小確定為 10(初始化字節碼大小為22)時。

我的程式碼:

   function Deploy() public returns(uint) {
       bytes memory code = "\x60\x0a\x60\x0c\x60\x00\x39\x60\x20\x60\x00\xf3\x60\x42\x60\x80\x52\x60\x20\x60\x80\xf3";

       address addr;
       uint size;
       assembly {
         addr := create(0, add(code, 0x20), mload(code))
         size := extcodesize(addr)
         if iszero(extcodesize(addr)) {
           revert(0, 0)
         }
       }
       return size;
   }

為什麼返回 32?我知道這是最小字長,但我沒有code用零填充輸入。但是,返回的結果(通過EXTCODECOPY)用零填充。

它返回 32 是因為您的部署字節碼明確返回 32 個字節。

分解它:

\x60\x0a\x60\x0c\x60\x00\x39\x60\x20\x60\x00\xf3

  • PUSH 0x0a :要複製的長度(執行時字節碼長 10 個字節)
  • PUSH 0x0c :源偏移量(執行時字節碼從第 12 個字節開始)
  • PUSH 0x00 :目標偏移量(在記憶體地址 0x00 及以上複製)
  • CODECOPY :執行實際的複制
  • PUSH 0x20 : 要返回的長度**<– 這是你的錯誤**
  • PUSH 0x00 : 返回的源地址
  • RETURN : 返回從地址 0x00 開始的 0x20 個字節

您剛剛複制了 0x0a 字節,但返回的是 0x20。只需將部署字節碼的錯誤 PUSH 0x20 (0x60 0x20) 更改為 PUSH 0x0a (0x60 0x0a),您將看到預期的合約大小為 10。

我希望這能回答你的問題。

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