Web3js
如果已部署的契約上存在方法,如何從 web3 中檢測?
假設已經部署了一個合約,但我沒有它的原始碼或 ABI。從 web3 開始,我想知道合約是否有帶有給定簽名的方法。(一個範例應用程序是一個區塊鏈服務,它通過呼叫呼叫合約的特定回調方法來響應請求,例如 Oraclize。)
我可以接近以下內容:
methodSignature = web3.sha3('methodName(bytes32,bytes)'); calltx = { to: TARGET_ADDR, data: methodSignature.substring(0,10) }; let result = web3.eth.call(calltx)
然後如果結果不是“0x”,則該方法存在,因為它返回了一些值。但是'0x’並不意味著該方法不存在,這取決於方法本身。我如何區分?
我正在使用這種方法:
public async hasMethod(contractAddress, signature) { const w3 = this.$connection.web3; // this is my web3 instance const code = await w3.eth.getCode(contractAddress); const functionSignature = w3.eth.abi.encodeFunctionSignature(signature); // remove "0x" prefixed in 0x<4bytes-selector> return code.indexOf(functionSignature.slice(2, hash.length)) > 0; }
然後:
const adress = '0xB8c77482e45F1F44dE1745F52C74426C631bDD52'; const signature = 'transferFrom(address,address,uint256)'; this.hasMethod(address, signature).then((has) => console.log(has));
沒有完美的方法可以做到這一點,但您可以掃描程式碼以查找簽名雜湊的出現。為了使這一點更精確,您可以確保 PUSH4 的操作碼在它之前。
這是一些python程式碼(我猜JS幾乎相同):
def hasMethod(contract_addr, signature): code = w3.eth.getCode(contract_addr) fn_hash = w3.sha3(signature.encode("utf-8")) fn_hash = "63" + fn_hash[2:10] # 0x63 is PUSH4 return fn_hash in code contract_addr = "0xB8c77482e45F1F44dE1745F52C74426C631bDD52" signature = "transferFrom(address,address,uint256)" print(hasMethod(contract_addr, signature))