链上交易失败时,仅凭 Etherscan 错误信息难以定位问题。本篇教你用 Hardhat、Tenderly 等工具调试失败交易,追踪调用堆栈与回滚原因,并提出 gas 使用优化建议,助你构建稳定高效的智能合约。
📚 作者:Henry 🧱 系列:《深入理解区块链 Gas 机制》 · 第 6 篇 👨💻 受众:Web3 开发者 / Solidity 工程师 / 区块链学习者
类别 | 描述 |
---|---|
gas 设置不足 | 设置的 gasLimit 不足或 baseFee + tip 不足 |
调用逻辑失败 | 外部合约 revert、require 检查失败 |
权限或数据异常 | msg.sender 不匹配、无权限、参数非法 |
合约缺陷 | 重入攻击、整数溢出、错误分支逻辑等 |
兼容性问题 | ABI 解码失败、EVM 版本不兼容 |
Fail with error 'Ownable: caller is not the owner'
说明调用了 OpenZeppelin Ownable 模块的 onlyOwner
修饰器,当前账户无权限。
require
/revert
的字符串信息通常能指示错误点;hardhat_fork
功能 fork 对应区块高度console.log
或 debug
调试// hardhat.config.ts
forking: {
url: "https://eth-mainnet.alchemyapi.io/v2/xxx",
blockNumber: 19119119
}
// 调试脚本
const contract = await ethers.getContractAt("MyContract", address)
await contract.connect(attacker).doSomething(params)
Tenderly 可以做到:
场景 | 排查建议 |
---|---|
gas limit 太低 | 提高限制或使用 estimateGas() |
maxFee 太低被淘汰 | 动态设置 baseFee + tip |
simulate 成功但上链失败 | 检查链上下文是否一致(nonce、状态) |
fallback 调用失败 | fallback/receive 函数异常 |
unchecked
块减少溢出检查;掌握失败交易调试技巧,能帮助你:
《开发者常见 Gas 迷思与误区澄清》
将拆解一些常被误解的 gas 相关问题:例如 estimateGas()
为何不准?低 gasPrice 会被矿工打包吗?合约视图函数是否也消耗 gas?敬请期待!
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!