Adding subscription address to chainlink vrf v2 inside of the contract

Viewed 24

So I'm writing this lottery smart contract which is pretty straight forward, and since I want to test this on the goerli test net, I want to be able to add the contract as a subscriber to my VRF every time it's deployed.


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import "node_modules/@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import "node_modules/@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "node_modules/@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";

contract Lottery is VRFConsumerBaseV2 {
    VRFCoordinatorV2Interface COORDINATOR;

    address owner;
    address[] buyers = [msg.sender];
    address winner;
    address vrfCoordinator = 0x2Ca8E0C643bDe4C2E08ab1fA0da3401AdAD7734D;

    bytes32 keyHash;

    uint32 callbackGasLimit = 5000000;
    uint16 requestConfirmations = 3;
    uint32 numWords = 1;
    uint256[] public randomWords;
    uint256 public requestId;
    uint64 subscriptionId;
    uint256 usdEntryFee;
    uint256 startingTime;
    uint256 endTime;
    uint256 prizePool;
    bool available;

    AggregatorV3Interface public priceFeed;

    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    function enterLottery() public payable returns (bool success) {
        buyers.push(msg.sender);
    }

    function getEntranceFee() public view returns (uint256) {
        (, int256 price, , , ) = priceFeed.latestRoundData();
        uint256 adjustedPrice = uint256(price) * 10**10; // 18 decimals
        // $50, $2,000 / ETH
        // 50/2,000
        // 50 * 100000 / 2000
        uint256 costToEnter = (usdEntryFee * 10**18) / adjustedPrice;
        return costToEnter;
    }

    constructor(address _priceFeed, uint64 _subscriptionId)
        VRFConsumerBaseV2(vrfCoordinator)
    {
        priceFeed = AggregatorV3Interface(_priceFeed);
        COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
        owner = msg.sender;
        usdEntryFee = 50 * (10**18);
        subscriptionId = _subscriptionId;
    }

    function requestRandomWords() public onlyOwner {
        requestId = COORDINATOR.requestRandomWords(
            keyHash,
            subscriptionId,
            requestConfirmations,
            callbackGasLimit,
            numWords
        );
    }

    function addSubscription() public {
        COORDINATOR.addConsumer(subscriptionId, address(this));
    }

    function fulfillRandomWords(
        uint256, // requestId
        uint256[] memory _randomWords
    ) internal override {
        randomWords = _randomWords;
    }

    function startLottery(uint256 _endTime) public onlyOwner {
        startingTime = block.timestamp;
        available = true;
        endTime = startingTime + _endTime;
    }

    function endLottery() public payable onlyOwner returns (uint256) {
        require(
            block.timestamp > endTime,
            "Auction ending date not arrived yet!"
        );
        available = false;
        uint256 randomIndex;
        requestRandomWords();
        randomIndex = randomWords[0] % buyers.length;
        winner = buyers[randomIndex];
        return (randomWords[0]);
    }

    function transferWinnings() public payable onlyOwner {
        if (!payable(winner).send(prizePool)) {
            revert("Transaction failed!");
        }
    }
}

I'm using brownie framework to deploy and test, and this is the test function I'm using.

from brownie import Lottery, accounts, config, network
from scripts.helpful_scripts import get_account
from web3 import Web3

def test_random_number():
    account = get_account()
    lottery = Lottery.deploy(config["networks"][network.show_active()]["eth_usd_price_feed"], 1563, {"from": account})
    lottery.addSubscription({"from": account})
    lottery.requestRandomWords({"from": account})
    assert lottery.randomWords[0] != 0

I'm using the VRF admin wallet to do all of this but still it's not adding the contract to my subscriptions.

Also if anyone is familiar with how I could use the Chainlink VRF V2 mocks, any help would be appreciated.

0 Answers
Related