如何用ethers.js提取交易中的Solidity自定义错误信息?
解决Solidity自定义错误在ethers.js 5.7中无法提取的问题
一、先确认合约层面的正确性
- 确保Solidity版本≥0.8.4(自定义错误从该版本开始支持)。
- 检查编译后的ABI是否包含自定义错误定义,示例如下:
{ "type": "error", "name": "Documents__AlreadyExist", "inputs": [{"name": "hash", "type": "string"}] }
若ABI中无此部分,需重新编译合约。
3. 确认校验逻辑正确:s_documentsHashes为mapping(string => bool)类型,且addDocumentHash方法中已正确执行s_documentsHashes[hash] = true;,否则校验不会触发。
二、ethers.js 5.7中解析自定义错误的方法
在catch块中通过合约interface解析错误数据,代码示例:
try { const tx = await documents.addDocumentHash(hash) const txReceipt = await tx.wait(1) // 其余代码 } catch (error) { // 适配不同provider的错误数据结构 const errData = error.data || error.error?.data; if (errData) { try { // 解码合约自定义错误 const decodedError = documents.interface.parseError(errData); if (decodedError.name === "Documents__AlreadyExist") { // 提取错误参数 const existingHash = decodedError.args.hash; console.log(`哈希已存在: ${existingHash}`); // 此处可添加业务处理逻辑 } else { context.error(`合约错误: ${decodedError.name}`); } } catch (parseErr) { // 处理非自定义错误(如gas不足、网络问题) context.error(`解析错误失败: ${parseErr.message}`); } } else { // 处理无合约错误数据的通用情况 context.error(`交易失败: ${error.message || error}`); } }
三、Etherscan无法查看失败原因的排查
- 检查gas是否耗尽:若gas不足,Etherscan仅显示“Out of Gas”,可适当提高交易的gasLimit。
- 确认合约已验证:未验证的合约无法被Etherscan解析错误信息,需先完成合约验证。
- 部分测试网节点可能未返回完整错误数据,但通过上述ethers.js解析方法,客户端仍能提取自定义错误。
内容的提问来源于stack exchange,提问作者JohnKot
相关产品推荐
相关产品推荐

