I am attempting to deploy a smart contract to the Sepolia testnet. I currently have ~1 Sepolia eth in my wallet. I am using Hardhat and Alchemy and I am following this tutorial Here is my code for hardhat.config.js :


const { API_URL, PRIVATE_KEY } = process.env;

// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
  const accounts = await hre.ethers.getSigners();

  for (const account of accounts) {

// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more

 * @type import('hardhat/config').HardhatUserConfig
module.exports = {
  solidity: "0.8.19",
  defaultNetwork: "sepolia",
  networks: {
    sepolia: {
      url: API_URL,
    accounts: [PRIVATE_KEY]

Here is my run.js:

async function main() {
    const baseTokenURI = "ipfs://QmemE2wZKkf8Y9FPufzxRbnoF1VtB17FvRSkn7f2ve2wY5/";

    // Get owner/deployer's wallet address
    const [owner] = await hre.ethers.getSigners();

    // Get contract that we want to deploy
    const contractFactory = await hre.ethers.getContractFactory("NFTCollectible");

    // Deploy contract with the correct constructor arguments
    const contract = await contractFactory.deploy(baseTokenURI);

    // Wait for this transaction to be mined
    await contract.deployed();

    // Get contract address
    console.log("Contract deployed to:", contract.address);

    // Reserve NFTs
    let txn = await contract.reserveNFTs();
    await txn.wait();
    console.log("3 NFTs have been reserved");

    // Mint 1 NFTs by sending 0.01 ether
    txn = await contract.mintNFTs(3, { value: utils.parseEther('0.01') });
    await txn.wait()

    // Get all token IDs of the owner
    let tokens = await contract.tokensOfOwner(owner.address)
    console.log("Owner has tokens: ", tokens);


    .then(() => process.exit(0))
    .catch((error) => {

Here is my contract.sol

//SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";

contract NFTCollectible is ERC721Enumerable, Ownable {
    using SafeMath for uint256;
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    uint public constant MAX_SUPPLY = 50;
    uint public constant PRICE = 0.01 ether;
    uint public constant MAX_PER_MINT = 3;
    string public baseTokenURI;

constructor(string memory baseURI) ERC721("NFT Collectible", "NFTC"){

function reserveNFTs() public onlyOwner {
uint totalMinted = _tokenIds.current();

    totalMinted.add(3) < MAX_SUPPLY, "Not enough NFTs"
for (uint i = 0; i < 3; i++){

function _baseURI() internal
                    returns (string memory) {
            return baseTokenURI;

function setBaseURI(string memory _baseTokenURI) public onlyOwner{
baseTokenURI = _baseTokenURI;

function mintNFTs(uint _count) public payable{
    uint totalMinted = _tokenIds.current();
        totalMinted.add(_count) <= MAX_SUPPLY, "Not enough NFTs!"
        _count >0 && _count <= MAX_PER_MINT,
        "Cannot mint specified number of NFTs(Please enter a valid amount)."
    msg.value >= PRICE.mul(_count), "Not enough ether to purchase NFTs."
     for (uint i = 0; i < _count; i++) {
     function _mintSingleNFT() private{
     uint newTokenID = _tokenIds.current();
     _safeMint(msg.sender, newTokenID);
     function tokenOfOwner(address _owner)
            returns (uint[] memory){
        uint tokenCount = balanceOf(_owner);
        uint[] memory tokensId = new uint256[](tokenCount);
        for (uint i = 0; i < tokenCount; i++){
        tokensId[i] = tokenOfOwnerByIndex(_owner, i);
        return tokensId;
function withdraw() public payable onlyOwner {
    uint balance = address(this).balance;
    require(balance > 0, "No ether left to withdraw.");
    (bool success, ) =(msg.sender).call{value: balance}("");
    require(success, "Transfer failed.");


.env has my alchemy URL and my private key. When I run

enpx hardhat run scripts/run.js --network sepolia

it throws this error:

Contract deployed to: 0x1234567890qwerty1234567890qwerty
3 NFTs have been reserved
Error: cannot estimate gas; transaction may fail or may require manual gas limit [ See: https://links.ethers.org/v5-errors-UNPREDICTABLE_GAS_LIMIT ] (reason="execution reverted: Not enough ether to purchase NFTs.", method="estimateGas", transaction={"from":"0x1234567890qwerty1234567890qwerty","to":"0x1234567890qwerty1234567890qwerty","value":{"type":"BigNumber","hex":"0x2386f26fc10000"},"data":"0x3b4b13810000000000000000000000000000000000000000000000000000000000000003","accessList":null}, error={"name":"ProviderError","_stack":"ProviderError: execution reverted: Not enough ether to purchase NFTs.\n    at HttpProvider.request (C:\\Users\\john\\nft-collectible\\node_modules\\hardhat\\src\\internal\\core\\providers\\http.ts:88:21)\n    at processTicksAndRejections (node:internal/process/task_queues:95:5)\n    at EthersProviderWrapper.send (C:\\Users\\john\\nft-collectible\\node_modules\\@nomiclabs\\hardhat-ethers\\src\\internal\\ethers-provider-wrapper.ts:13:20)","code":3,"_isProviderError":true,"data":"0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000224e6f7420656e6f75676820657468657220746f207075726368617365204e4654732e000000000000000000000000000000000000000000000000000000000000"}, code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.7.2)
    at Logger.makeError (C:\Users\john\nft-collectible\node_modules\@ethersproject\logger\src.ts\index.ts:269:28)
    at Logger.throwError (C:\Users\john\nft-collectible\node_modules\@ethersproject\logger\src.ts\index.ts:281:20)
    at checkError (C:\Users\john\nft-collectible\node_modules\@ethersproject\providers\src.ts\json-rpc-provider.ts:78:20)
    at EthersProviderWrapper.<anonymous> (C:\Users\john\nft-collectible\node_modules\@ethersproject\providers\src.ts\json-rpc-provider.ts:642:20)
    at step (C:\Users\john\nft-collectible\node_modules\@ethersproject\providers\lib\json-rpc-provider.js:48:23)
    at Object.throw (C:\Users\john\nft-collectible\node_modules\@ethersproject\providers\lib\json-rpc-provider.js:29:53)
    at rejected (C:\Users\john\nft-collectible\node_modules\@ethersproject\providers\lib\json-rpc-provider.js:21:65)
    at processTicksAndRejections (node:internal/process/task_queues:95:5) {
  reason: 'execution reverted: Not enough ether to purchase NFTs.',
  method: 'estimateGas',
  transaction: {
    from: '0x1234567890qwerty1234567890qwerty',
    to: '0x1234567890qwerty1234567890qwerty',
    value: BigNumber { value: "10000000000000000" },
    data: '0x3b4b13810000000000000000000000000000000000000000000000000000000000000003',
    accessList: null
  error: ProviderError: execution reverted: Not enough ether to purchase NFTs.
      at HttpProvider.request (C:\Users\john\nft-collectible\node_modules\hardhat\src\internal\core\providers\http.ts:88:21)
      at processTicksAndRejections (node:internal/process/task_queues:95:5)
      at EthersProviderWrapper.send (C:\Users\john\nft-collectible\node_modules\@nomiclabs\hardhat-ethers\src\internal\ethers-provider-wrapper.ts:13:20)
  • show run script please. and the related functions in contract
    – Majd TL
    Commented Mar 15, 2023 at 9:28
  • @MajdTL I have added in the code you requested.
    – That_Coder
    Commented Mar 15, 2023 at 11:59
  • you are minting 3 NTFs but sending only the price of 1 . change this line to: txn = await contract.mintNFTs(3, { value: utils.parseEther('0.03') });
    – Majd TL
    Commented Mar 15, 2023 at 15:03

1 Answer 1


The Price of 1 NFT is hardcoded to 0.01Ether uint public constant PRICE = 0.01 ether;

But when you are buying/minting the NFTs, you are buying 3 and sending only the required ether for 1 -> txn = await contract.mintNFTs(3, { value: utils.parseEther('0.01') });

This will trigger this error:

require(msg.value >= PRICE.mul(_count), "Not enough ether to purchase NFTs.");

You need either to send 0.03 Ether with your transaction

txn = await contract.mintNFTs(3, { value: utils.parseEther('0.03') });

Or mint only 1 NFT with value: 0.01

txn = await contract.mintNFTs(1, { value: utils.parseEther('0.01') });

  • Thanks, that fixed it. As a follow up question, my tutorial said that I would now be able to see my NFT transaction on Etherscan (I was), and that I would be able to find them on OpenSeaTestnet if I searched for the contract address. I was not. Do you know why this is happening? I also tried to search for their contract address, which is 0x355638a4eCcb777794257f22f50c289d4189F245 But that didn't return any results either. I am searching for the wrong thing?
    – That_Coder
    Commented Mar 15, 2023 at 18:14
  • @That_Coder weird, are you sure you are using the correct API_URL and can you post the address of the account you use to deploy? and is it your account or have you found the private key somewhere in the tutorial?
    – Majd TL
    Commented Mar 16, 2023 at 7:59
  • No, it's my account. I can see it on Etherscan, and I have put in my API_URL. When I call the withdraw method from Etherscan the funds from the contract go into my wallet. This is my account address: 0xe7eE00Cb67c3eB80937669f593A9FF3a4d3e96b2 Also, I don't know if the testnet matters, but I'm on Sepolia.
    – That_Coder
    Commented Mar 16, 2023 at 12:15
  • @NalLuksic Could you please clarify what you mean in this post: ethereum.stackexchange.com/questions/143161/… I am currently having the same issue(using the same tutorial). Thanks!
    – That_Coder
    Commented Mar 16, 2023 at 17:17
  • @That_Coder the metadata of your NFT has no valid image URL. for example the metadata of NFT with Id = 1 can be found on IPFS -> ipfs.io/ipfs/QmfQHRsTrFN9tHVjsZ3aM2L225aUxk73LX2fFFa2GEPZ9y/… . If you check the image property you see only "1.png". 1.png is like only a placeholder and it must be a valid URL. So you need to upload your own metadata to IPFS or a public server and use your own "baseTokenURI"
    – Majd TL
    Commented Mar 17, 2023 at 8:08

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.