0

While running the command yarn hardhat deploy it is giving me following error Error: expected 0 constructor arguments, got 6

Deploy Script


        const {network} = require("hardhat");
        const{verify} = require("../utils/verify");
        const {developmentChains, networkConfig} = require("../helper-hardhat-config");
        const {storeImages, storeTokenUriMetaData} = require("../utils/uploadToPinata");
        const fs = require("fs");
        const { networkInterfaces } = require("os");
        require("dotenv").config();

        const imagesLocation = "./images/randomNft";

        const metaDataTemplate = {
            name: "",
            description: "",
            image: "",
            attribute: [
                {
                trait_type: "Cuteness",
                value: 100,
                },
             ],
        };

        module.exports = async function({getNamedAccounts ,deployments}){
        const {deploy, log} = deployments;
        const {deployer} = await getNamedAccounts();
        const chainId = network.config.chainId;
        let tokenUris;
        if(process.env.UPLOAD_TO_PINATA === "true"){
        tokenUris = await handleTokenUris();
        }

        let vrfCoordinatorV2Address, subscriptionId;

        if(developmentChains.includes(network.name)){
        const vrfCoordinatorV2Mock = await deployments.get("VRFCoordinatorV2Mock");
        const vrfCoordinatorV2 = await ethers.getContractAt("VRFCoordinatorV2Mock",vrfCoordinatorV2Mock.address);
        vrfCoordinatorV2Address = vrfCoordinatorV2Mock.address;
        const tx = await vrfCoordinatorV2.createSubscription();
        const txReceipt = await tx.wait(1);

        subscriptionId = txReceipt.logs[0].args.subId;
    }else{
        vrfCoordinatorV2Address = networkConfig[chainId].vrfCoordinatorV2;
        subscriptionId = networkConfig[chainId].subscriptionId;
    }

    log("-------------------");

    const args = [vrfCoordinatorV2Address, subscriptionId, networkConfig[chainId].gasLane, networkConfig[chainId].callbackGasLimit,  tokenUris,  networkConfig[chainId].mintFee];
    const randomIpfs = await deploy("RandomIpfsNft",{
        from: deployer,
        args: args,
        log: true,
        waitConfirmations: network.config.blockConfirmation || 1,
    });

    if (chainId == 31337) {
        await vrfCoordinatorV2Mock.addConsumer(subscriptionId, randomIpfs.address)
    }

    log("-----------------------------");
    
    if(!developmentChains.includes(network.name) && process.env.ETHER_API){
        log("Verifying");
        await verify(randomIpfs.address, args);
    }

    }

        async function handleTokenUris() {
        tokenUris = [];

        const {responses: imageUploadResponses, files} =await storeImages(imagesLocation);

        for(const imageUploadResponsesIndex in imageUploadResponses){
        let tokenUriMetaData = { ...metaDataTemplate};
        tokenUriMetaData.name = files[imageUploadResponsesIndex].replace(".png", "");
        tokenUriMetaData.description = `An adorable ${tokenUriMetaData.name}`;
        tokenUriMetaData.image = `ipfs://${imageUploadResponses[imageUploadResponsesIndex].IpfsHash}`;
        console.log(`Uploding ${tokenUriMetaData.name}`);

        const metaDataUploadResponse = await storeTokenUriMetaData(tokenUriMetaData);
        tokenUris.push(`ipfs://${metaDataUploadResponse.IpfsHash}`);
    }
    console.log("Token Uris uploaded");
    console.log(tokenUris);
    return tokenUris;
    }

    module.exports.tags = ["all", "randomIpfs", "main"]

Soloidity Code

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.24;

import "@chainlink/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

error RandomIpfsNft__RangeOutOfBounds();
error RandomIpfsNft__NeedMoreETHSent();
error RandomIpfsNft__TransferFailed();

abstract contract RandomIpfsNft is VRFConsumerBaseV2, ERC721URIStorage, Ownable{

    enum Breed {
        PUG,
        SHIB_INU,
        ST_BERNARD
    }

    VRFCoordinatorV2Interface private  immutable i_vrfCoordinator;
    uint64 private immutable i_subscriptionId;
    bytes32 private immutable i_gasLane;
    uint32 private immutable i_callbackGasLimit;
    uint16 private constant REQUEST_CONFIRMATION = 3;
    uint32 private constant NUM_WORDS = 1;

    mapping (uint256 => address) public s_requestIdToSender;


    uint256 public s_tokenCounter;
    uint256 internal constant MAX_CHANCE_VALUE = 100;
    string[3] internal s_dogTokenUris;
    uint256 internal i_mintFee;

    event NftRequested(uint256 indexed requestId, address requester);
    event NftMinted(Breed dogBreed, address minter);

    constructor(address vrfCoordinatorV2, uint64 subscriptionId, bytes32 gasLane, uint32 callbackGasLimit, string[3] memory dogTokenUris, uint256 mintFee) VRFConsumerBaseV2(vrfCoordinatorV2) ERC721("Random IPFS NFT", "RIN") {
        i_vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinatorV2);
        i_subscriptionId = subscriptionId;
        i_gasLane = gasLane;
        i_callbackGasLimit = callbackGasLimit;
        s_dogTokenUris = dogTokenUris;
        i_mintFee = mintFee;
    }

    function requestNft() public payable returns(uint256 requestId){
        if(msg.value < i_mintFee){
            revert RandomIpfsNft__NeedMoreETHSent();
        }
        requestId;
        requestId = i_vrfCoordinator.requestRandomWords(i_gasLane, i_subscriptionId, REQUEST_CONFIRMATION, i_callbackGasLimit, NUM_WORDS);
        s_requestIdToSender[requestId] = msg.sender;

        emit NftRequested(requestId, msg.sender);
    }
 
    function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override{
        address dogOwner = s_requestIdToSender[requestId];
        uint256 newTokenId = s_tokenCounter;

        uint256 moddedRng = randomWords[0] % MAX_CHANCE_VALUE;
        Breed dogBreed=getBreedFromModdedRng(moddedRng);
        _safeMint(dogOwner, newTokenId);
        _setTokenURI(newTokenId, s_dogTokenUris[uint256(dogBreed)]);
        emit NftMinted(dogBreed, dogOwner);
    }

    function withDraw() public onlyOwner {
        uint256 amount = address(this).balance;
        (bool success, ) = payable(msg.sender).call{value: amount}("");
        if(!success) {revert RandomIpfsNft__TransferFailed();}
    }

    function getBreedFromModdedRng(uint256 moddedRng) public pure returns(Breed){
        uint256 sum = 0;
        uint256[3] memory chanceArray = getChanceArray();
        for(uint256 i = 0; i< chanceArray.length; i++){
            if(moddedRng >= sum && moddedRng < sum + chanceArray[i]){
                return Breed(i);
            }
            sum += chanceArray[i];  
        }
        revert RandomIpfsNft__RangeOutOfBounds(); 
    }

    function getChanceArray() public pure returns(uint256[3] memory){
        return [10,30, MAX_CHANCE_VALUE];
    }

    function getMintFee() public view returns(uint256){
        return i_mintFee;
    }
    function getDogTokenUris(uint256 index) public view returns(string memory){
        return s_dogTokenUris[index];
    }
    function getTokenCounters() public view returns(uint256){
        return s_tokenCounter;
    }
}

1 Answer 1

1

Your RandomIpfsNft contract is marked as abstract, therefore it cannot be deployed directly.

You need to remove the abstract keyword, i.e.,

Replace this:

abstract contract RandomIpfsNft is VRFConsumerBaseV2, ERC721URIStorage, Ownable {

with:

contract RandomIpfsNft is VRFConsumerBaseV2, ERC721URIStorage, Ownable {

Then, in your constructor, you should also pass the argument to the base constructor (i.e., Ownable) like:

constructor(address vrfCoordinatorV2, uint64 subscriptionId, bytes32 gasLane, uint32 callbackGasLimit, string[3] memory dogTokenUris, uint256 mintFee) VRFConsumerBaseV2(vrfCoordinatorV2) ERC721("Random IPFS NFT", "RIN") Ownable(msg.sender) {
4
  • Done the following changes and now showing the following error ``` TypeError: No arguments passed to the base constructor. Specify the arguments or mark "RandomIpfsNft" as abstract. --> contracts/RandomIpfsNFT.sol:14:1: | 14 | contract RandomIpfsNft is VRFConsumerBaseV2, ERC721URIStorage, Ownable{ | ^ (Relevant source part starts here and spans across multiple lines). Note: Base constructor parameters: --> @openzeppelin/contracts/access/Ownable.sol:38:16: | 38 | constructor(address initialOwner) { | ^^^^^^^^^^^^^^^^^^^^^^ ```
    – Jimit
    Commented Jul 9 at 16:59
  • I’ve added that to my answer. Please check. Commented Jul 9 at 17:12
  • What does that base constructor actually means over there?
    – Jimit
    Commented Jul 9 at 19:26
  • Since the Ownable contract is being extended/inherited, so its constructor args need to be passed as well, the way you’re already passing for VRFConsumerBaseV2 and ERC721 contracts. Commented Jul 10 at 4:16

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.