Showing Posts From

Hardhat

Hardhat 本地链卡链?先看是不是关了自动挖矿

Hardhat 本地链跑合约,await tx.wait() 卡住不返回,感觉链死了。看着像 bug,其实基本都是配置问题。 快速定位 一条命令看当前区块号: cast block-number --rpc-url http://127.0.0.1:8545没有 cast 就用 curl: curl -X POST http://127.0.0.1:8545 \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'隔几秒再跑一次,区块号不变——链停了。 原因 1:配了 auto: false hardhat.config.js 里如果有: networks: { hardhat: { mining: { auto: false, // 关掉了自动挖矿 // interval: 5000 // 或者只按间隔挖 } } }交易发到内存池后不会被打包,得手动 mine: await network.provider.send("evm_mine");或者恢复自动挖矿: await network.provider.send("evm_setAutomine", [true]);原因 2:nonce 冲突 之前发过一个低 gas 交易占住了某个 nonce,后面的交易全排在它后面: cast nonce 0x<address> --rpc-url http://127.0.0.1:8545解法:发一个相同 nonce、更高 gas 的交易顶掉旧的(cancelTx 模式)。 原因 3:fork 主网时 RPC 挂了 npx hardhat node --fork https://eth-mainnet.g.alchemy.com/v2/xxxAlchemy 超限、RPC 断线、网络超时,Hardhat 表现得就像卡住。开 debug 日志看: DEBUG=hardhat* npx hardhat node会看到"Waiting for chain state"之类的提示。 原因 4:不是链卡,是前端缓存了 Hardhat 每次重启链状态会重置,但前端还拿着旧合约地址、旧 ABI。清理编译产物: rm -rf cache artifacts npx hardhat compile npx hardhat run scripts/deploy.js --network localhost原因 5:evm_mine 返回 0 不等于失败 有人看到: await network.provider.send("evm_mine"); // '0'以为报错了。其实 '0' 是 RPC 的正常返回值,表示成功。区块号会 +1,验证一下: await ethers.provider.getBlockNumber();兜底:一键重置 想快速回到初始状态而不重启进程: await network.provider.request({ method: "hardhat_reset", params: [], });链状态、快照、内存池全清。跑测试之间用这个特别方便。 或者最粗暴——Ctrl+C 结束 npx hardhat node,重新起一个。 一句话总结 Hardhat "卡链" 九成是 auto: false 关了自动挖矿。先 evm_setAutomine [true] 或手动 evm_mine 一下,绝大多数情况就通了。

Hardhat 本地链卡住:交易 pending、区块不出块的排查与解决

Hardhat 本地链卡住通常表现为:交易发出后一直 pending、await tx.wait() 不返回、区块号停止增长。 快速诊断:区块是否在出块 # 用 cast(foundry 工具) cast block-number --rpc-url http://127.0.0.1:8545# 用 curl curl -s -X POST http://127.0.0.1:8545 \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'重复执行,如果区块号不增长说明链已卡死。 原因一:开启了手动挖矿模式 hardhat.config.js 中配置了 auto: false: networks: { hardhat: { mining: { auto: false, interval: 0 } } }此时交易发出后不会自动打包,需要手动触发出块: // Hardhat 测试脚本里 await network.provider.send("evm_mine");// 一次挖多个块 await network.provider.send("hardhat_mine", ["0xa"]); // 10 个块用 curl 触发: curl -X POST http://127.0.0.1:8545 \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"evm_mine","params":[],"id":1}'原因二:nonce 冲突导致交易队列堵塞 某笔 gas 过低的交易占住 nonce,后续交易全部等待。查当前 nonce: cast nonce 0x你的地址 --rpc-url http://127.0.0.1:8545最简单的解法是直接重置链: await network.provider.request({ method: "hardhat_reset", params: [] });或者重置到 fork 某个区块高度: await network.provider.request({ method: "hardhat_reset", params: [{ forking: { jsonRpcUrl: "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY", blockNumber: 20000000 } }] });原因三:fork 主网时 RPC 超时 npx hardhat node --fork https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY如果 Alchemy/Infura 限速或网络超时,Hardhat 会表现得像卡住。开启调试日志: DEBUG=hardhat* npx hardhat node --fork ...看是否有 timeout 或 rate limit 报错。 原因四:缓存/artifacts 脏数据 有时前端或脚本缓存了旧的合约地址/ABI,链本身没问题但调用失败。清理后重新编译部署: rm -rf cache artifacts npx hardhat compile npx hardhat run scripts/deploy.js --network localhost最直接的解法:重启 如果不需要保留链状态,直接重启即可: Ctrl+C npx hardhat nodeHardhat 本地链的状态不持久化,重启后从创世块重新开始。如果需要持久化,使用 hardhat_reset + snapshot(evm_snapshot / evm_revert)来管理状态。