You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 15:42:33