2

This is my code for utils/verify.js

const { run } = require("hardhat")

const verify = async (contractAddress, arguments) => {
  console.log("Verifying Contract... ")

  try {
    await run("verify:verify", {
      address: contractAddress,
      constructorArguments: arguments,
    })
  } catch (e) {
    if (e.message.toLowerCase().includes("already verified")) {
      console.log("Already verified 🇵🇲 ")
    } else {
      console.log("Error ❄️ : ", e)
    }
  }
}

module.exports = { verify }

This is contract deployment script:

const { network, ethers } = require("hardhat")
const { developmentChains, networkConfig } = require("../helper-hardhat-config")

const { verify } = require("../utils/verify")

const VRF_SUB_FUND_AMOUNT = ethers.utils.parseEther("30")

module.exports = async function ({ getNamedAccounts, deployments }) {
  const { deploy, log } = deployments
  const deployer = await getNamedAccounts()
  const chainId = network.config.chainId
  let vrfCoordinatorV2Address, subscriptionId

  if (developmentChains.includes(network.name)) {
    const VRFCoordinatorV2Mock = await ethers.getContract(
      "VRFCoordinatorV2Mock"
    )

    vrfCoordinatorV2Address = VRFCoordinatorV2Mock.address

    const transactionResponse = await VRFCoordinatorV2Mock.createSubscription()
    const transactionReceipt = await transactionResponse.wait(1)
    subscriptionId = transactionReceipt.events[0].args[0]
    await VRFCoordinatorV2Mock.fundSubscription(
      subscriptionId,
      VRF_SUB_FUND_AMOUNT
    )
  } else {
    vrfCoordinatorV2Address = networkConfig[chainId]["vrfCoordinatorv2"]
    subscriptionId = networkConfig[chainId]["subscriptionId"]
  }

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

  const lottery = await deploy("Lottery", {
    from: deployer.deployer,
    args: arguments,
    log: true,
    waitConformations: network.config.blockConformations || 1,
  })

  if (
    !developmentChains.includes(network.name) &&
    process.env.ETHERSCAN_API_KEY
  ) {
    log("Verifying ..........")
    await verify(lottery.address, arguments)
  }

  log("--------------------------------------------")
}

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

This is corresponding contract to the code:

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

// A contract allows user to pay
// Announces winnner within minutes

// imports
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/interfaces/KeeperCompatibleInterface.sol";



// Errors 
error Lottery__NotEnoughETHEntered();
error Lottery__TransferFailed();
error Lottery__NotOpen();
error Lottery__UpkeedNotNeeded(uint256 currentBalance, uint256 numPlayers, uint256 raffleState);



/** @title A simple Lottery Contract
 * @author yana gupta
 * @dev This implements chainlink vrf v2 or chainlink keepers
 */


contract Lottery is VRFConsumerBaseV2, KeeperCompatibleInterface {

  enum LotteryState {
    OPEN,
    CALCULATING
  }

  // State Variable
  uint256 private immutable i_entranceFee;
  address payable[] private s_players;
  VRFCoordinatorV2Interface private immutable i_vrfCoordinator;
  bytes32 private immutable i_gasLane;
  uint64 private immutable i_subscriptionId;
  uint32 private immutable i_callbackGasLimit;
  uint16 private constant REQUEST_CONFORMATIONS = 3;
  uint16 private constant NUM_WORDS = 1;
  uint256 private immutable i_interval;

  // Lottery Variables 
  address private s_recentWinner;
  LotteryState private s_lotteryState;
  uint256 private s_lastTimeStamp;

  // Events
  event LotteryEnter(address indexed player);
  event RequestedLotteryWinner(uint256 indexed requestId);
  event WinnerPicked(address indexed winner);

  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_lotteryState = LotteryState.OPEN;
    i_interval = interval;
  }

  function getEnterenceFee() public view returns (uint256) {
    return i_entranceFee;
  }

  function getInterval () public view returns (uint256) {
    return i_interval;
  }

  function enterLottery() public payable {
    if (msg.value < i_entranceFee) {
      revert Lottery__NotEnoughETHEntered();
    }
    if ( s_lotteryState != LotteryState.OPEN) {
        revert Lottery__NotOpen();
    }
    s_players.push(payable(msg.sender));
    // Name events wish reversed
    emit LotteryEnter(msg.sender);
  }


  function pickRandomWinner() external {
    // Request the random number
    // Once we get it, do something with it
  }

  function fulfillRandomWords(
    uint256 /* requestId */,
    uint256[] memory randomWords
  ) internal override {
    // random_number mod s_players size -- winner
    uint256 indexOfWinner = randomWords[0] % s_players.length;
    address payable recentWinner = s_players[indexOfWinner];
    s_recentWinner = recentWinner;
    s_lotteryState = LotteryState.OPEN;
    s_players = new address payable[](0);
    s_lastTimeStamp = block.timestamp;
    (bool success, ) = recentWinner.call{value: address(this).balance}("");
    if (!success) {
      revert Lottery__TransferFailed();
    }
    emit WinnerPicked(recentWinner);
  }

  function checkUpkeep ( bytes memory checkData ) public override returns (bool upkeepNeeded, bytes memory /* performData */  ) {
    bool isOpen = (LotteryState.OPEN == s_lotteryState); 
    bool timePassed = ( ( block.timestamp - s_lastTimeStamp ) > i_interval);
    bool hasPlayers = (s_players.length > 0 );
    bool hasBalance = address(this).balance > 0;
    upkeepNeeded = ( isOpen && timePassed && hasPlayers && hasBalance);
    return (upkeepNeeded, "0x0");
  }

  function performUpkeep(bytes memory /* perform Data */) external override {   
    (bool upkeepNeeded, ) = checkUpkeep("");
    if ( !upkeepNeeded ) {
      revert Lottery__UpkeedNotNeeded(address(this).balance, s_players.length, uint256(s_lotteryState));
    }
    s_lotteryState = LotteryState.CALCULATING; 
    uint256 requestId = i_vrfCoordinator.requestRandomWords(
    i_gasLane,
    i_subscriptionId,
    REQUEST_CONFORMATIONS,
    i_callbackGasLimit,
    NUM_WORDS
    );
    emit RequestedLotteryWinner(requestId);
  }

  function getPlayer(uint256 index) public view returns (address) {
    return s_players[index];
    }

  function announceRandomWinner() public {}

  function getRecentWinner() public view returns (address) {
    return s_recentWinner;
  }
  function getLotteryState() public view returns (LotteryState) {
    return s_lotteryState;
  }

  function getNumWord() public pure returns (uint256) {
    return NUM_WORDS;
  }

  function getNumberOfPlayers() public view returns (uint256) {
    return s_players.length;
  }

  function getLatestTimeStamp() public view returns (uint256) {
    return s_lastTimeStamp;
  }

  function getRequestConformations() public pure returns (uint256) {
    return REQUEST_CONFORMATIONS;
  }

} 

Deploy Command:

npx hh deploy --network goerli

Error

Error ❄️ :  NomicLabsHardhatPluginError: Failed to send contrract verification request.
Endpoint URL: https://api-goerli.etherscan.io/api
Reason: The Etherscan API responded that the address 0x9FFee858CDff55BcC6FE5aad1E80Df62360047B9 does not have bytecode.   
This can happen if the contract was recently deployed and this fact hasn't propagated to the backend yet.
Try waiting for a minute before verifying your contract. If you are invoking this from a script,
try to wait for five confirmations of your contract deployment transaction before running the verification subtask.       
    at verifyContract (C:\Users\user\OneDrive\Desktop\BlockChain\hardhat-lottery\node_modules\@nomiclabs\hardhat-etherscan\src\etherscan\EtherscanService.ts:52:11)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at attemptVerification (C:\Users\user\OneDrive\Desktop\BlockChain\hardhat-lottery\node_modules\@nomiclabs\hardhat-etherscan\src\index.ts:474:20)
    at SimpleTaskDefinition.action (C:\Users\user\OneDrive\Desktop\BlockChain\hardhat-lottery\node_modules\@nomiclabs\hardhat-etherscan\src\index.ts:778:48)
    at Environment._runTaskDefinition (C:\Users\user\OneDrive\Desktop\BlockChain\hardhat-lottery\node_modules\hardhat\src\internal\core\runtime-environment.ts:311:14)
    at Environment.run (C:\Users\user\OneDrive\Desktop\BlockChain\hardhat-lottery\node_modules\hardhat\src\internal\core\runtime-environment.ts:159:14)
    at SimpleTaskDefinition.verifySubtask [as action] (C:\Users\user\OneDrive\Desktop\BlockChain\hardhat-lottery\node_modules\@nomiclabs\hardhat-etherscan\src\index.ts:312:28)        
    at Environment._runTaskDefinition (C:\Users\user\OneDrive\Desktop\BlockChain\hardhat-lottery\node_modules\hardhat\src\internal\core\runtime-environment.ts:311:14)
    at Environment.run (C:\Users\user\OneDrive\Desktop\BlockChain\hardhat-lottery\node_modules\hardhat\src\internal\core\runtime-environment.ts:159:14)
    at verify (C:\Users\user\OneDrive\Desktop\BlockChain\hardhat-lottery\utils\verify.js:7:5)
WinnerPicked event fired!
      1) works with live chainlink Keepers and Chainklink VRF, we get a random winner


  0 passing (6m)
  1 failing

  1) Lottery
       fulfillRandwomWords
         works with live chainlink Keepers and Chainklink VRF, we get a random winner:
     Error: Timeout of 300000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (C:\Users\user\OneDrive\Desktop\BlockChain\hardhat-lottery\test\staging\Lottery.staging.js)
      at listOnTimeout (node:internal/timers:559:17)
      at processTimers (node:internal/timers:502:7)

Can someone help me out with this error.

1 Answer 1

0

I had the same error. This basically happens when the Blockchain Explorer hasn't had enough time to index your contract. You basically need to wait for a few moments before running the verify script. In case you want to deploy and verify in one go, there are two ways to do it:

  1. Refer to This post for the sane-ish way to do it. It's a really good answer by @PatrickCollins

  2. This is the way I did it. It is like a duck-tape fix - Wrap your Verify Task inside a setTimeout() so that it waits for some seconds before initiating the verification task. In your case, it would this code inside the try block:

setTimeout(() =>
run("verify:verify", {
      address: contractAddress,
      constructorArguments: arguments,
    }), 10000)

The second way would make the script wait for 10 seconds which should be enough time for the blockchain explorer to index your contract.

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.