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

Hardhat中ethers.getContract('VRFCoordinatorV2Mock')返回undefined,导致Raffle合约部署时出现无效地址错误

Hardhat中ethers.getContract('VRFCoordinatorV2Mock')返回undefined,导致Raffle合约部署时出现无效地址错误

我明白你遇到的问题了——从你提供的错误日志能看到,明明已经成功在本地链部署了VRFCoordinatorV2Mock,但在01-deploy-raffle.js里用ethers.getContract('VRFCoordinatorV2Mock')获取合约实例时返回了undefined,最终导致传递给Raffle合约的vrfCoordinatorV2Address是undefined,触发了无效地址错误。

问题根源

在Hardhat Deploy的工作流中,直接调用ethers.getContract()并不总是能正确从部署记录中加载合约实例,因为它依赖于Hardhat的合约缓存和部署上下文的正确绑定。更可靠的方式是通过Hardhat Deploy提供的deployments.get()方法获取已部署合约的元数据(包括地址),再用ethers.getContractAt()生成对应的合约实例。

修复后的01-deploy-raffle.js代码

以下是修改后的完整脚本,我会标注关键的修改点:

const { network, ethers } = require("hardhat")
const { developmentChains, networkConfig } = require("../helper-hardhat-config")
const { verify } = require("../utils/verify")
const VRF_SUB_FUND_AMOUNT = ethers.parseEther("2")

module.exports = async function ({ getNamedAccounts, deployments }) {
    const { deploy, log, get } = deployments // 新增get方法,用于获取已部署合约记录
    const { deployer } = await getNamedAccounts()
    const chainId = network.config.chainId

    let vrfCoordinatorV2Address, subscriptionId

    if (developmentChains.includes(network.name)) {
        // --- 关键修改部分 start ---
        // 改用deployments.get获取已部署的mock合约的元数据
        const vrfCoordinatorV2MockDeployment = await get("VRFCoordinatorV2Mock")
        // 用getContractAt生成可交互的合约实例
        const vrfCoordinatorV2Mock = await ethers.getContractAt(
            "VRFCoordinatorV2Mock",
            vrfCoordinatorV2MockDeployment.address
        )
        // --- 关键修改部分 end ---

        vrfCoordinatorV2Address = vrfCoordinatorV2Mock.address
        console.log(`vrfCoordinatorV2Mock: ${vrfCoordinatorV2Mock.address}`)

        // 创建订阅
        const transactionResponse = await vrfCoordinatorV2Mock.createSubscription()
        const transactionReceipt = await transactionResponse.wait(1)
        subscriptionId = BigInt(transactionReceipt.logs[0].topics[1])
        console.log(`Subscription ID: ${subscriptionId}`)

        // 资助订阅
        await vrfCoordinatorV2Mock.fundSubscription(subscriptionId, VRF_SUB_FUND_AMOUNT)
    } else {
        vrfCoordinatorV2Address = networkConfig[chainId].vrfCoordinatorV2
        subscriptionId = networkConfig[chainId]["subscriptionId"]
    }

    const entranceFee = networkConfig[chainId]["entranceFee"]
    const gasLane = networkConfig[chainId]["gasLane"]
    const callbackGasLimit = networkConfig[chainId]["callbackGasLimit"]
    const interval = networkConfig[chainId]["interval"]
    const arguments = [vrfCoordinatorV2Address, subscriptionId, gasLane, interval, entranceFee, callbackGasLimit]

    const raffle = await deploy("Raffle", {
        from: deployer,
        args: arguments,
        log: true,
        waitConfirmations: network.config.blockConfirmations || 1,
    })

    // 修复verify参数错误:原代码用了未定义的`args`,改为正确的`arguments`
    if (!developmentChains.includes(network.name) && process.env.ETHERSCAN_API_KEY) {
        log("Verifying...")
        await verify(raffle.address, arguments)
    }
}

module.exports.tags = ["all", "raffle"]

额外的小修复

我还注意到你在合约验证部分犯了一个小错误:你定义的构造参数变量是arguments,但调用verify时传的是未定义的args,这会导致验证失败,我已经在修改后的代码中修正了这个问题。

验证修复效果

重新运行部署命令后,你应该能看到vrfCoordinatorV2Mock的地址被正确打印出来,不会再出现undefined,Raffle合约也能正常完成部署。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 11:34:38