Hardhat Ignition部署脚本重复部署触发BAD_DATA错误排查
问题:Hardhat Ignition重启本地节点后部署出现解码错误
我使用Hardhat Ignition部署PassNFT智能合约,部署脚本如下:
import hre from "hardhat"; import PassNFTModule from "../ignition/modules/PassNFT"; async function deploy() { const { passNFTContract } = await hre.ignition.deploy(PassNFTModule); const passNFTContractAddress = await passNFTContract.getAddress(); console.log("Pass NFT contract deployed to:", passNFTContractAddress); const isPublicMintEnabled = await passNFTContract.isPublicMintEnabled(); console.log("Pass NFT contract isPublicMintEnabled:", isPublicMintEnabled); } deploy().catch(console.error);
PassNFT合约核心代码:
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.20; import '@openzeppelin/contracts/token/ERC721/ERC721.sol'; import '@openzeppelin/contracts/access/Ownable.sol'; contract PassNFT is ERC721, Ownable { uint256 public mintPrice; uint256 public totalSupply; uint256 public maxSupply; uint256 public maxPerWallet; bool public isPublicMintEnabled; string internal baseTokenUri; address payable public withdrawWallet; mapping(address => uint256) public walletMints; constructor(string memory _tokenUri) payable ERC721('Pass NFT', 'MP') { mintPrice = 0.01 ether; totalSupply = 0; maxSupply = 10000; maxPerWallet = 1; baseTokenUri = _tokenUri; } function setIsPublicMintEnabled(bool newPublicMintStatus) external onlyOwner { isPublicMintEnabled = newPublicMintStatus; } // 其他合约方法省略 }
部署命令:
npx hardhat run scripts/deploy.ts --network localhost
首次部署正常,但重启本地节点后再次执行部署命令,出现错误:
Error: could not decode result data (value="0x", info={ "method": "isPublicMintEnabled", "signature": "isPublicMintEnabled()" }, code=BAD_DATA, version=6.13.2)
原因分析
这个错误的核心原因是Hardhat Ignition的状态缓存与重启后的本地节点不匹配:
- 首次部署后,Ignition会在本地生成缓存文件(默认在
.ignition/deployments目录),记录已部署合约的地址和状态。 - 重启本地节点后,节点的区块链状态被重置(所有之前的部署记录消失),但Ignition仍会尝试使用缓存中的旧合约地址去调用
isPublicMintEnabled方法。 - 由于旧地址上根本没有部署合约,调用返回空数据
0x,导致解码失败。
解决方法
方法1:清除Ignition缓存后重新部署
每次重启本地节点后,先删除Ignition的部署缓存,再执行部署命令:rm -rf .ignition/deployments && npx hardhat run scripts/deploy.ts --network localhost方法2:修改部署脚本,强制重置部署
在部署时添加resetDeployment选项,让Ignition跳过缓存,强制重新部署:async function deploy() { // 添加resetDeployment参数,强制重新部署 const { passNFTContract } = await hre.ignition.deploy(PassNFTModule, { resetDeployment: true }); const passNFTContractAddress = await passNFTContract.getAddress(); console.log("Pass NFT contract deployed to:", passNFTContractAddress); const isPublicMintEnabled = await passNFTContract.isPublicMintEnabled(); console.log("Pass NFT contract isPublicMintEnabled:", isPublicMintEnabled); }方法3:启动本地节点时禁用自动重置
启动节点时添加--no-reset参数,保留之前的区块链状态,重启后无需重新部署:npx hardhat node --no-reset
内容的提问来源于stack exchange,提问作者BoikoVD
相关产品推荐
相关产品推荐

