I was following along with a Patrick Collins tutorial when I came across an error while trying to view the subscriptionId
from inside transactionReceipt
.
This is my code:
const { network, ethers } = require("hardhat");
const { deploymentChains, networkConfig } = require("../helper-hardhat-config");
const { verify } = require("../utils/verify");
require("dotenv").config();
module.exports = async function ({ deployments, getNamedAccounts }) {
const { deployer } = await getNamedAccounts();
const { deploy, log } = deployments;
let VRFCoordinatorV2Address, subscriptionId;
const chainId = network.config.chainId;
const VRF_SUB_AMOUNT = ethers.parseEther("2");
const entranceFee = networkConfig[chainId]["entranceFee"];
const gasLane = networkConfig[chainId]["gasLane"];
const callbackGasLimit = networkConfig[chainId]["callbackGasLimit"];
const interval = networkConfig[chainId]["interval"];
if (deploymentChains.includes(network.name)) {
const VRFCoordinator = await ethers.getContract("VRFCoordinatorV2Mock");
VRFCoordinatorV2Address = VRFCoordinator.address;
const transactionResponse = await VRFCoordinator.createSubscription();
const transactionReceipt = await transactionResponse.wait(1);
subscriptionId = transactionReceipt.events[0].args.subId;
await VRFCoordinator.fundSubscription(subscriptionId, VRF_SUB_AMOUNT);
} else {
VRFCoordinatorV2Address = networkConfig[chainId]["VRFCoordinatorAddress"];
subscriptionId = networkConfig[chainId]["subscriptionId"];
}
const args = [
VRFCoordinatorV2Address,
entranceFee,
gasLane,
subscriptionId,
callbackGasLimit,
interval,
];
const raffle = await deploy("Raffle", {
from: deployer,
log: true,
args: args,
waitConfirmations: network.config.blockConfirmations,
});
if (!deploymentChains.includes(network.name) && process.env.ETHERSCAN_API_KEY) {
await verify(raffle.address, args);
}
log("----------------------------------------------");
};
module.exports.tags = ["all", "raffle"];
This is the error I'm getting:
I've noticed that the error is coming from the line subscriptionId = transactionReceipt.events[0].args.subId;
, can anyone tell me why this is happening?
This is the smart contract code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/AutomationCompatible.sol";
/*errors*/
error Raffle__NotEnoughETHentered();
error Raffle__TransferFailed();
error Raffle__NotOpen();
error Raffle__upKeepNotNeeded(uint256 balance, uint256 numPlayers, uint256 raffleState);
contract Raffle is VRFConsumerBaseV2, AutomationCompatibleInterface {
enum RaffleState {
OPEN,
CALCULATING
}
uint256 private immutable i_entranceFee;
address payable[] private s_players;
uint256 private s_requestId;
bytes32 private immutable i_gasLane;
uint64 private immutable i_subscriptionId;
uint16 private constant REQUEST_CONFIRMATIONS = 3;
uint32 private immutable i_callbackGasLimit;
uint32 private constant NUM_WORDS = 1;
VRFCoordinatorV2Interface private immutable i_vrfcoordinator;
/*lottery variables*/
address private s_recentWinner;
RaffleState private s_raffleState;
uint256 private s_lastTimeStamp;
uint256 private immutable i_interval;
/*Events*/
event RaffleEnter(address payable indexed player);
event RequestedRaffleWinner(uint256 requestId);
event WinnerPicked(address indexed Winner);
/*Functions*/
constructor(
address VRFCoordinatorV2,
uint256 entranceFee,
bytes32 gasLane,
uint64 subscriptionId,
uint32 callbackGasLimit,
uint256 interval
) VRFConsumerBaseV2(VRFCoordinatorV2) {
i_entranceFee = entranceFee;
i_vrfcoordinator = VRFCoordinatorV2Interface(VRFCoordinatorV2);
i_gasLane = gasLane;
i_subscriptionId = subscriptionId;
i_callbackGasLimit = callbackGasLimit;
s_raffleState = RaffleState.OPEN;
s_lastTimeStamp = block.timestamp;
i_interval = interval;
}
function enterRaffle() public payable {
if (msg.value < i_entranceFee) {
revert Raffle__NotEnoughETHentered();
}
if (s_raffleState != RaffleState.OPEN) {
revert Raffle__NotOpen();
}
s_players.push(payable(msg.sender));
emit RaffleEnter(payable(msg.sender));
}
function checkUpkeep(
bytes memory /*checkData*/
) public override returns (bool upkeepNeeded, bytes memory /*performData*/) {
bool isOpen = (RaffleState.OPEN == s_raffleState);
bool timePassed = (block.timestamp - s_lastTimeStamp > i_interval);
bool hasBalance = (address(this).balance > 0);
bool hasPlayers = (s_players.length > 0);
upkeepNeeded = (isOpen && timePassed && hasBalance && hasPlayers);
}
function performUpkeep(bytes calldata /*performData*/) external override {
(bool upkeepNeeded, ) = checkUpkeep("");
if (!upkeepNeeded) {
revert Raffle__upKeepNotNeeded(
address(this).balance,
s_players.length,
uint256(s_raffleState)
);
}
s_raffleState = RaffleState.CALCULATING;
s_requestId = i_vrfcoordinator.requestRandomWords(
i_gasLane,
i_subscriptionId,
REQUEST_CONFIRMATIONS,
i_callbackGasLimit,
NUM_WORDS
);
emit RequestedRaffleWinner(s_requestId);
}
function fulfillRandomWords(
uint256 /*requestId*/,
uint256[] memory randomWords
) internal override {
uint256 indexOfWinner = randomWords[0] % s_players.length;
address payable recentWinner = s_players[indexOfWinner];
s_recentWinner = recentWinner;
(bool success, ) = recentWinner.call{value: address(this).balance}("");
s_players = new address payable[](0);
s_lastTimeStamp = block.timestamp;
if (!success) {
revert Raffle__TransferFailed();
}
emit WinnerPicked(recentWinner);
s_raffleState = RaffleState.OPEN;
}
/*view/pure functions*/
function getEntranceFee() public view returns (uint256) {
return i_entranceFee;
}
function getPlayer(uint256 index) public view returns (address) {
return s_players[index];
}
function getRecentWinner() public view returns (address) {
return s_recentWinner;
}
function getRaffleState() public view returns (RaffleState) {
return s_raffleState;
}
function getNumWords() public pure returns (uint32) {
return NUM_WORDS;
}
function getNumOfPlayers() public view returns (uint256) {
return s_players.length;
}
function getLatestTimeStamp() public view returns (uint256) {
return s_lastTimeStamp;
}
function getRequestConfirmations() public pure returns (uint16) {
return REQUEST_CONFIRMATIONS;
}
}