Solidity
提取使用庫的地址
有沒有辦法從合約字節碼(不是經過驗證的合約程式碼)或部署交易中提取連結庫的地址?
我的問題是關於第 3 步:
步驟 1. 有人部署 SafeMath.sol 並獲取地址為 0x1234……..
步驟 2. 其他人連結和部署使用該庫的 Test.sol,命令將如下所示:
solc –abi –bin Test.sol –libraries SafeMath:0x1234…….. -o bin
步驟 3. 第三個去 etherscan 並查看已部署合約的字節碼或部署交易
EVM 沒有為合約提供直接的方法來檢測它是否使用 CALL 呼叫,但合約可以使用 ADDRESS 操作碼來找出它目前執行的“位置”。
$$ … $$ 更具體地說,庫的執行時程式碼總是以 push 指令開始,它在編譯時是 20 字節的零。當部署程式碼執行時,這個常量在記憶體中被目前地址替換,修改後的程式碼儲存在合約中。
$$ … $$
圖書館:
pragma solidity ^0.5.8; library lib { function isZero (address _address) public pure returns (bool) { return _address == address(0x0); } }
契約:
pragma solidity ^0.5.8; import "./lib.sol"; contract Importer { function doSom (address _address) public pure returns (bool) { require(lib.isZero(_address)); return true; } }
您可以在字節碼中看到
PUSH20
20 個字節的零的指令:... JUMPDEST PUSH1 0x0 PUSH20 0x0 ...
但在混音(調試)中:
143 PUSH20 bbf289d846208c16edc8474705c748aff07732db
您可以做的是
DELEGATECALL
在字節碼中查找操作碼並嘗試搜尋函式的標識符(在本例中為:)isZero(address): 0x673C8BE
。只有當您了解函式的method_id(簽名)時,SafeMath.sol
庫才能輕鬆實現。
DELEGATECALL
:... JUMPDEST POP GAS DELEGATECALL ISZERO ...
在混音(調試)中:
函式標識符:
... PUSH20 0x0 PUSH4 0x673C8BE DUP4 ...
在混音(調試)中: