UNPKG

hardhat-tracer

Version:

Hardhat Tracer plugin

119 lines (104 loc) 3.8 kB
import createDebug from "debug"; import { ethers } from "ethers"; import { task } from "hardhat/config"; import { HttpNetworkUserConfig } from "hardhat/types"; import { print } from "../print"; import { addCliParams, applyCliArgsToTracer, colorError } from "../utils"; import { addRecorder } from "../extend/hre"; const debug = createDebug("hardhat-tracer:tasks:trace"); addCliParams(task("tracecall", "Traces a call")) .addParam("to", "destination address") .addOptionalParam("data", "input call data") .addOptionalParam("value", "value to send") .addOptionalParam("gaslimit", "gas limit") .addOptionalParam("gasprice", "gas price") .addOptionalParam("blocknumber", "block number") .addOptionalParam("from", "from address") .addOptionalParam("rpc", "archive node") .setAction(async (args, hre, runSuper) => { applyCliArgsToTracer(args, hre); if (!args.nocompile) { await hre.run("compile"); } // try using current mainnet fork url as rpc url const mainnetForkUrl = (hre.network.config as any).forking?.url; if (mainnetForkUrl && args.rpc === undefined) { args.rpc = mainnetForkUrl; } // try using url specified in network as rpc url if (args.network) { const userNetworks = hre.userConfig.networks; if (userNetworks === undefined) { throw new Error( "[hardhat-tracer]: No networks found in hardhat config" ); } if (userNetworks[args.network] === undefined) { throw new Error( `[hardhat-tracer]: Network ${args.network} not found in hardhat config` ); } const url = (userNetworks[args.network] as HttpNetworkUserConfig).url; if (url === undefined) { throw new Error( `[hardhat-tracer]: Url not found in hardhat-config->networks->${args.network}` ); } args.rpc = url; } if (!args.rpc) { // TODO add auto-detect network throw new Error( "[hardhat-tracer]: rpc url not provided, please either use --network <network-name> or --rpc <rpc-url>" ); } debug("using rpc url %s", args.rpc); const provider = new ethers.providers.StaticJsonRpcProvider(args.rpc); if (args.blocknumber === undefined) { args.blocknumber = await provider.getBlockNumber(); } console.warn( "Activating mainnet fork at block", args.rpc, args.blocknumber ); await hre.network.provider.send("hardhat_reset", [ { forking: { jsonRpcUrl: args.rpc, blockNumber: Number(args.blocknumber), }, }, ]); addRecorder(hre); // reset seems to clear all what we did to the provider await hre.tracer.switch!.enable(); try { debug("making call"); const result = await hre.ethers.provider.call({ to: args.to, data: args.data, value: args.value, gasLimit: args.gaslimit, gasPrice: args.gasprice, from: args.from, }); console.log("eth_call result:", result); } catch (e) { console.error("eth_call error:", (e as any).error); } // TODO try to do this properly const recorder = hre.tracer.recorder!; debug("printing trace"); if (!recorder.previousTraces || recorder.previousTraces.length === 0) { throw new Error("[hardhat-tracer]: Failed to record the trace"); } await print(recorder.previousTraces[recorder.previousTraces.length - 1], { artifacts: hre.artifacts, tracerEnv: hre.tracer, provider: hre.ethers.provider, }); await new Promise((resolve) => setTimeout(resolve, 1000)); return; // const txFromRpc = await provider.getTransaction(args.hash); // after the above hardhat reset, tx should be present on the local node });