0

I want to add consumers to an existing subscription but it's failing as only the owner can add the consumer I want to add Chainlink VRF in my NFT Marketplace and here I am creating NFTs in bulk so users can create as many tokens as they want hence do I need to create a subscription for each address or is there any other way to handle this? Here's my code:

NFT.sol     
constructor(
        string memory _name,
        string memory _symbol,
        uint256 updateInterval,
        uint256 _winnerPercentage,
        uint64 subscriptionId,
        address vrfCoordinator
        )
        ERC721(_name, _symbol)
        VRFConsumerBaseV2(vrfCoordinator)
    {
        interval = updateInterval;
        lastTimeStamp = block.timestamp;
        winnerPercentage = _winnerPercentage;
        s_subscriptionId = subscriptionId;
        COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
        addSubscription();
    }
function addSubscription() internal   {
        COORDINATOR.addConsumer(s_subscriptionId, address(this));
    } 

Marketplace. sol

    function createToken(string memory name, string memory symbol, uint256 updateInterval, uint256 winnerPercentage, uint64 subscriptionId, address vrfCoordinator) public {
       address _address = address(new NFT(name, symbol, updateInterval,winnerPercentage, subscriptionId, vrfCoordinator));   
        uint256 count = 0;
       tokens[msg.sender].push(_address);
       CollectionAddresses.push(_address);
       count++;       
        emit TokenCreated(msg.sender, _address);
    }
Could you please help me with this? 
Thank you!

2 Answers 2

1

Off the top of my head, you could have a single contract handling all the RNG calls (so, no need to add consumers everytime you create a new contract), or make the marketplace contract the subscription owner and manage adding the newly created contracts as consumers there.


EDIT: Here is some example code for the second option :

Marketplace.sol 

 function createToken(
        string memory name,
        string memory symbol,
        uint256 updateInterval,
        uint256 winnerPercentage,
        uint64 subscriptionId,
        bytes32 keyHash,
        address vrfCoordinator
    ) public {
        address _address = address(new NFT(name, symbol, updateInterval, winnerPercentage, subscriptionId, address(this), keyHash, vrfCoordinator));
        uint256 count = 0;
        tokens[msg.sender].push(_address);
        CollectionAddresses.push(_address);
        count++;
        addNFTConsumer(subscriptionId, vrfCoordinator, _address);
        emit TokenCreated(msg.sender, _address);
    }
    function addNFTConsumer(uint64 subscriptionId, address coordinator, address tokenAddress) internal {
        coordinator.addConsumer(subscriptionId, tokenAddress);
    }
0

Thank you for the response! I have made some changes to my NFT and Marketplace contract but I am not able to add the NFT addresses as a consumer from the Marketplace contract yet so can you please check my modified code and provide a suggestion to resolve the issue?

NFT.sol 

 address marketplaceOwner;
      constructor(
           string memory _name,
        string memory _symbol,
        uint256 _updateInterval,
        uint256 _winnerPercentage,
        uint64 _subscriptionId,
        address _marketplaceOwner,
        bytes32 _keyHash,
        address _vrfCoordinator

        )
        ERC721(_name, _symbol)
        VRFConsumerBaseV2(_vrfCoordinator)
    {
        interval = _updateInterval;
        lastTimeStamp = block.timestamp;
        winnerPercentage = _winnerPercentage;
        s_subscriptionId = _subscriptionId;
        marketplaceOwner = _marketplaceOwner;
        keyHash = _keyHash;
    }
   modifier onlyMarketplaceOwner {
        require(msg.sender == marketplaceOwner, "Only Marketplace owner can call this function");
        _;
    }
      function addConsumer() external {
    COORDINATOR.addConsumer(s_subscriptionId, address(this));
}
Marketplace.sol 

 function createToken(
        string memory name,
        string memory symbol,
        uint256 updateInterval,
        uint256 winnerPercentage,
        uint64 subscriptionId,
        bytes32 keyHash,
        address vrfCoordinator
    ) public {
        address _address = address(new NFT(name, symbol, updateInterval, winnerPercentage, subscriptionId, address(this), keyHash, vrfCoordinator));
        uint256 count = 0;
        tokens[msg.sender].push(_address);
        CollectionAddresses.push(_address);
        count++;
        emit TokenCreated(msg.sender, _address);
    }
    function callAddConsumer(address tokenAddress) public {
        NFT(tokenAddress).addConsumer();
    }
5
  • 1
    Hey! This is not an answer to your question. You should have added it as an edit to your original question or open a new question instead of posting it as an answer. Try to do that next time :) To answer you though, your addConsumer() function should be in the marketplace contract directly, i edited my original answer with example code.
    – Foxxxey
    Commented Jan 6 at 13:33
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Jan 8 at 6:10
  • Thank you for the answer. I apologize for this and I will make sure to take care of it the next time! Thanks again! Commented Jan 9 at 4:04
  • Hey @Foxxxe, I modified my code according to your suggestion but I am facing an error called: execution reverted "The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance." while calling the CreateToken function. I have already added the Marketplace contract address as a Consumer to the subscription Management so could you please help me to figure out this issue? Commented Jan 9 at 4:35
  • @MahimaThacker the marketplace contract needs to be the subscription owner, not a mere consumer. You can transfer ownership of a subscription by calling requestSubscriptionOwnerTransfer from the current owner (presumably your address) and having your contract call acceptSubscriptionOwnerTransfer once that's done (so you'd need to write a new function in your contract for that)
    – Foxxxey
    Commented Jan 9 at 13:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.