web3.js ↔ JSON‑RPC Provider: Decoding Revert Reasons on Failed Deployments
0 reputation · 30 Aug 2024, 12:11 UTC
0 reputation · 30 Aug 2024, 12:11 UTC
I need to obtain consistent, human‑readable revert reasons when a contract deployment fails, using either web3.js v1.x or the v4 beta across JSON‑RPC providers such as Geth, Besu, Erigon, Infura, or Alchemy.
Only providers that implement eth_getTransactionReceipt with a revertReason field (Geth ≥ 1.10) populate the field that web3.eth.abi.decodeRevertReason consumes. Custom errors (EIP‑838) require the contract ABI at decode time; without it web3.js returns the raw selector. web3.js v4’s Deployment object surfaces a parsed reason only when the provider supports eth_call simulation, and the API is still unstable. Provider‑specific error codes (nonce gaps, replacement‑transaction pricing, gas‑limit errors) are not normalized by web3.js.
Which provider configurations reliably return a populated revertReason in the receipt for a failed deployment? How does web3.js v4’s Deployment.catch behave when the ABI for a custom error is unavailable? What fallback approach works when a provider does not expose debug_traceTransaction or eth_call with tracing?
31775 reputation · 30 Aug 2024, 12:43 UTC
To consistently obtain a populated revertReason in the transaction receipt, you must use a node implementation that extends the standard eth_getTransactionReceipt response. Geth (v1.10+) and Besu typically provide this field when the EVM reverts. However, managed services like Infura or Alchemy often adhere strictly to the official Ethereum JSON-RPC specification, which does not include revertReason in the receipt. For these providers, the receipt will only indicate a status of 0 (failure) without a human-readable string.
When using Deployment.catch in web3.js v4, the behavior regarding custom errors (EIP-838) is determined by the availability of the ABI at the time of decoding:
0x...), leaving the developer to manually look up the selector in a database or the contract source.If your provider does not support debug_traceTransaction or the revertReason receipt field, the most reliable fallback is Manual Simulation via eth_call. Since a deployment is essentially a transaction to the null address with the constructor bytecode as data, you can simulate the failure to extract the error message.
data field (bytecode + constructor arguments) used in the failed deployment.web3.eth.call using the same from address and data, targeting the 0x0 address or leaving the to field empty (depending on provider support for contract creation simulation).To verify if your current provider supports the extended receipt field, execute a failing deployment and check the raw response:
// Example check for raw receipt field
const receipt = await web3.eth.getTransactionReceipt(txHash);
console.log("Revert Reason present:", !!receipt.revertReason);
Note: This approach does not work for "Out of Gas" errors, as these are execution environment failures rather than EVM reverts and do not generate a revert string.
Diagnostic Detail Required: Are you encountering Out of Gas errors specifically, or are these logic-based require()/revert() failures?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.