如何重置Hardhat至干净状态 解决hardhat-deploy部署Gravatar合约交易回退问题
报错根因分析
你遇到的交易回滚报错核心是合约逻辑限制导致,并非Hardhat环境残留问题:
GravatarRegistry合约的createGravatar方法第一行校验require(ownerToGravatar[msg.sender] == 0),要求每个地址最多只能创建一个Gravatar。你的部署脚本中三次调用createGravatar都是用同一个deployer账户发起交易,第一次调用成功后该地址就已经绑定了Gravatar ID,后续两次调用都会触发校验失败,且该require语句没有配置错误提示字符串,所以返回「Transaction reverted without a reason string」的错误。
另外你部署脚本中的合约调用没有加await,会导致交易还没上链就执行后续逻辑,也可能引发异常。
Hardhat环境重置为干净状态的方法
如果确实需要清空所有历史部署、链上数据,可以按以下步骤操作:
- 重启Hardhat本地节点:直接终止当前运行的
yarn hardhat node --hostname 0.0.0.0进程,重新执行启动命令即可。Hardhat本地节点默认是内存链,重启后所有链上状态、交易记录都会完全清空,回到初始状态。 - 清除hardhat-deploy部署缓存:删除项目根目录下的
deployments文件夹,该文件夹存储了hardhat-deploy插件的所有历史部署记录,删除后重新部署会完全重新执行合约部署流程,不会复用旧的部署结果。 - 清除Hardhat编译运行缓存:删除项目根目录下的
artifacts和cache文件夹,这两个目录存储了合约编译产物和Hardhat运行缓存,删除后重新执行编译、部署流程会完全重新编译合约,避免旧产物导致的异常。
本次问题的针对性修复方案
如果不需要重置环境,只要修改部署脚本,用不同账户调用createGravatar、加上await即可正常运行,示例代码如下:
import {HardhatRuntimeEnvironment} from "hardhat/types"; import {DeployFunction} from "hardhat-deploy/types"; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { const {deployments, getNamedAccounts, ethers} = hre; const {deployer} = await getNamedAccounts(); // 获取额外的测试账户 const [, user1, user2] = await ethers.getSigners(); const deployResult = await deployments.deploy("GravatarRegistry", { from: deployer, log: true, }); const Registry = await ethers.getContractFactory('GravatarRegistry'); const registry = await Registry.attach(deployResult.address); // 不同账户调用,加await等待交易上链 await registry.createGravatar('Virat','https://img1.hscicdn.com/image/upload/f_auto,t_gn_f_345/lsci/db/PICTURES/CMS/316600/316605.png'); await registry.connect(user1).createGravatar('Saurav','https://img1.hscicdn.com/image/upload/f_auto,t_gn_f_345/lsci/db/PICTURES/CMS/319900/319951.png'); await registry.connect(user2).createGravatar('Sachin','https://img1.hscicdn.com/image/upload/f_auto,t_gn_f_345/lsci/db/PICTURES/CMS/316400/316486.png'); }; export default func;
内容的提问来源于stack exchange,提问作者ahsan_cse2004
相关产品推荐
相关产品推荐

