Solidity
EXTCODESIZE 為小於 32 的合約返回 32
我目前正在完成 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。
我希望這能回答你的問題。