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 node
Hardhat 本地链的状态不持久化,重启后从创世块重新开始。如果需要持久化,使用 hardhat_reset + snapshot(evm_snapshot / evm_revert)来管理状态。
