Delegatecall
從它的選擇器中找到合約中函式的最快方法?
假設我有一個函式選擇器:
0xa9059cbb
我有這樣的契約:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; contract CallAnything { function balanceOf(address someAddress) external view {...} function transfer(address someAddress, uint256 amount) external {...} function approve(address someAddress, uint256 amount) external {...} }
我找到選擇器涉及的功能的最快方法是什麼?
更多上下文
許多代理使用
delegatecall
目標地址和數據對象呼叫一些合約。如果我是從 UI/前端與代理進行互動的使用者,那麼要準確查看代理正在呼叫的函式和數據可能非常棘手。一種快速找到的方法:
- 被呼叫的函式
- (不在這個問題的範圍內)解碼正在發送的參數。
會很可愛。
提示,在上面的合約中,函式選擇器
0xa9059cbb
是針對transfer
函式的。它有一個函式簽名"transfer(address,uint256)"
您可以使用乙太坊簽名數據庫(https://www.4byte.directory/)註冊功能的簽名超過 956,355 個。
- 使用現有的選擇器數據庫 ==============
並在搜尋欄中輸入您的選擇器。您將獲得數據庫已找到的已知選擇器列表。這裡的優點是它很快,缺點是它們可能在數據庫中沒有您的特定選擇器。
- 使用 Brownie、Foundry、Hardhat 等工具 =================================
鑄造廠
如果您的代工項目中有契約或介面,您可以執行以下操作:
forge inspect CallAnything methods
並獲得如下輸出:
{ "approve(address,uint256)": "095ea7b3", "balanceOf(address)": "70a08231", "transfer(address,uint256)": "a9059cbb" }
並簡單地匹配選擇器(更容易
forge inspect CallAnything methods | grep a9059cbb
)布朗尼
您可以編寫如下腳本:
# call_me.py from brownie import Contract def main(): calldata = "some_calldata_here" result = Contract.from_explorer( "0x2a49Eae5CCa3f050eBEC729Cf90CC910fADAf7A2" ).decode_input(calldata) print(result)
然後執行它:
brownie run scripts/call_me.py --network mainnet
並獲得如下輸出:
Fetching source of 0x2a49Eae5CCa3f050eBEC729Cf90CC910fADAf7A2 from api.etherscan.io... ('openMultiplyVault((address,address,uint256,uint256,uint256,address,bytes),(address,address,uint256,bytes32,uint256,uint256,uint256,uint256,uint256,uint256,bool,string),(address,address,address,address,address))', [['0x6B175474E89094C44Da98b954EedeAC495271d0F', .........
這還有一個額外的好處,即通過代理的 calldata 為您提供您想要的東西,並告訴您它在其他合約上呼叫了哪些函式。
- 將其放入 Tenderly ================
如果交易存在,你可以去Tenderly輸入交易,它會給你所有的函式呼叫 tx 對其他合約的呼叫。
或者,如果您還沒有進行交易,您可以使用交易模擬器。
4.自己編寫一個腳本,將所有函式轉換為函式選擇器
但是誰在這樣做呢?