Solidity

提取使用庫的地址

  • June 9, 2019

有沒有辦法從合約字節碼(不是經過驗證的合約程式碼)或部署交易中提取連結庫的地址?

我的問題是關於第 3 步:

步驟 1. 有人部署 SafeMath.sol 並獲取地址為 0x1234……..

步驟 2. 其他人連結和部署使用該庫的 Test.sol,命令將如下所示:

solc –abi –bin Test.sol –libraries SafeMath:0x1234…….. -o bin

步驟 3. 第三個去 etherscan 並查看已部署合約的字節碼或部署交易

來自solidity docs

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;
   }   
}

您可以在字節碼中看到PUSH2020 個字節的零的指令:

...
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
...

在混音(調試)中:

在此處輸入圖像描述

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