Hardhat Network and Ethers.js: Gas Estimation Consistency Across Providers
0 reputation · 07 Jan 2021, 09:56 UTC
0 reputation · 07 Jan 2021, 09:56 UTC
Integrating the Hardhat Network with Ethers.js allows for rapid local development and testing through the Hardhat Runtime Environment (HRE). While the HRE provides seamless provider injection, a discrepancy often arises when the same Ethers.js configuration is used to target both the local simulated node and external Ethereum testnets.
The local Hardhat Network utilizes specific EVM versioning and instant mining behaviors that may not align with the gas calculation logic of live networks. This creates uncertainty when validating transaction costs for contracts intended for production deployment.
Does the Hardhat Network provide a mechanism to synchronize gas estimation behavior with a specific external network's parameters? How can developers ensure that estimateGas calls via Ethers.js remain consistent when switching between the local HRE provider and a remote JSON-RPC endpoint?
32275 reputation · 07 Jan 2021, 14:11 UTC
The Hardhat Network does not provide a single "sync" button to mirror a remote network's gas behavior, but it allows you to align the underlying EVM execution environment. Because estimateGas in Ethers.js is a wrapper for the eth_estimateGas RPC call, the consistency of the result depends entirely on the node's EVM version and the current state of the blockchain, not the Ethers.js configuration.
Discrepancies usually stem from two sources: EVM Versioning (the set of opcodes and their costs) and State Differences (the data present in the contract storage during simulation). If your local network is running a different hardfork than the target testnet, certain operations will cost different amounts of gas.
shanghai, london) and set it in your hardhat.config.js. This ensures the local node uses the same opcode gas costs as the remote node.
module.exports = {
hardhat: {
hardfork: "shanghai",
},
};
estimateGas is consistent, use Hardhat's forking feature to pull the actual state from the remote RPC endpoint.
module.exports = {
hardhat: {
forking: {
url: "https://your-remote-rpc-endpoint",
},
},
};
gasUsed field in the resulting transaction receipts.This approach assumes you are targeting a standard Ethereum-compatible EVM. It may not provide 100% consistency for Layer 2 solutions (like Optimism or Arbitrum) that implement custom gas metering logic not fully replicated in the Hardhat Network. Furthermore, estimateGas does not account for dynamic fee market fluctuations (EIP-1559), only the units of gas required for execution.
Diagnostic Detail Needed: Are you targeting a standard EVM chain or a specific Layer 2/Sidechain? L2s often require specific provider overrides that Hardhat's default settings cannot simulate.
Use comments to ask for clarification. Post a solution as an answer.
4,690 reputation · 07 Jan 2021, 13:37 UTC
While aligning the hardfork and state via forking addresses opcode costs, it is important to distinguish between gas units (the amount of work) and the gas price (the cost per unit). estimateGas returns the former, but the actual cost in ETH depends on the network's fee market.
In a local Hardhat environment, the base fee behavior may differ from a live EIP-1559 network unless explicitly managed. To get a more realistic cost projection, consider these verification steps:
ethers.provider.getFeeData() on both providers to compare the lastBaseFeePerGas.hardhat_setBalance or specific Hardhat network settings to ensure the account has sufficient funds to cover the maxFeePerGas and maxPriorityFeePerGas required by the remote network.Remember that estimateGas is a simulation of the current state; if the state changes between the call and the broadcast, the transaction may still fail or cost more on a live network.