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

Hardhat部署NFT合约时Contract Address显示undefined的解决求助

修复Hardhat部署合约时NFT地址返回undefined的问题

问题场景

运行部署命令:

npx hardhat run src/backend/scripts/deploy.js --network localhost

预期输出包含有效的NFT合约地址,但实际返回:

Deploying contracts with the account: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
Account balance: 9999992459571303767619n
NFT CONTACT ADDRESS undefined

尝试添加await nft.deployed()后,又出现deployed()方法不存在的错误。

原因分析

  • Ethers.js版本差异:Ethers v6移除了deployed()方法,contractFactory.deploy()会直接等待部署交易确认并返回合约实例;若使用Ethers v5,则必须调用deployed()等待交易完成才能获取地址。
  • 合约配置异常:若ethers.getContractFactory("NFT")未正确加载合约(比如合约名与文件名不匹配、合约编译失败),会导致返回的合约实例异常,address属性为undefined。
  • artifacts调用问题:原代码中artifacts.readArtifactSync(name)在部分Hardhat版本中存在兼容性问题,可能引发隐性错误导致流程异常。

解决方案

步骤1:确认合约基础配置

确保NFT合约文件(如contracts/NFT.sol)中的合约名称与代码中一致,示例:

// contracts/NFT.sol
pragma solidity ^0.8.20;

contract NFT {
    // 合约逻辑...
}

执行npx hardhat compile重新编译合约,确保无编译错误。

步骤2:适配Ethers.js版本的部署代码

根据你使用的Ethers版本选择对应写法:

适配Ethers v6(推荐)

deploy()会自动等待交易确认,无需deployed(),同时优化saveFrontendFiles函数兼容性:

async function main() {
    const [deployer] = await ethers.getSigners();

    console.log("Deploying contracts with the account:", deployer.address);
    console.log("Account balance:", await deployer.provider.getBalance(deployer.address));

    // 加载NFT合约工厂
    const NFT = await ethers.getContractFactory("NFT");
    // 部署合约(Ethers v6中deploy()自动等待交易确认)
    const nft = await NFT.deploy();
    
    console.log("NFT CONTRACT ADDRESS:", nft.address);
    
    saveFrontendFiles(nft, "NFT");
}

function saveFrontendFiles(contract, name) {
    const fs = require("fs");
    const path = require("path");
    const contractsDir = path.join(__dirname, "../../frontend/contractsData");

    if (!fs.existsSync(contractsDir)) {
        fs.mkdirSync(contractsDir);
    }

    // 写入合约地址
    fs.writeFileSync(
        path.join(contractsDir, `${name}-address.json`),
        JSON.stringify({ address: contract.address }, undefined, 2)
    );

    // 从合约实例直接获取ABI(替代artifacts调用,兼容性更强)
    fs.writeFileSync(
        path.join(contractsDir, `${name}.json`),
        JSON.stringify(contract.interface, null, 2)
    );
}

main()
    .then(() => process.exit(0))
    .catch(error => {
        console.error("部署出错:", error);
        process.exit(1);
    });

适配Ethers v5

需调用deployed()等待交易完成:

async function main() {
    const [deployer] = await ethers.getSigners();

    console.log("Deploying contracts with the account:", deployer.address);
    console.log("Account balance:", await deployer.provider.getBalance(deployer.address));

    const NFT = await ethers.getContractFactory("NFT");
    const nft = await NFT.deploy();
    // Ethers v5中必须等待deployed()确认交易完成
    await nft.deployed();
    
    console.log("NFT CONTRACT ADDRESS:", nft.address);
    saveFrontendFiles(nft, "NFT");
}

// saveFrontendFiles函数可使用原代码或上方兼容写法

步骤3:验证部署

重新运行部署命令,检查输出是否包含有效的NFT合约地址,同时查看frontend/contractsData目录下是否生成了对应的地址和ABI文件。

内容的提问来源于stack exchange,提问作者Manav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:14:54