Cannot estimate gas; transaction may fail or may require manual gas limit

Hey everyone,

I am using Openzeppelin and Hardhat to build a Node.js server that can mint, transfer, and burn NFT’s. I am using Matic polygon testnet blockchain network to deploy my contracts

Here is my smart contract. (NFT.sol)

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyNFT is ERC721, Ownable {
    using Counters for Counters.Counter;
    using Strings for uint256;
    Counters.Counter private _tokenIds;
    mapping (uint256 => string) private _tokenURIs;
    string private _baseURIextended;

    constructor() ERC721("MyNFT", "MNFT") {}

    function _setTokenURI(uint256 tokenId, string memory _tokenURI)
        internal
        virtual
    {       
        _tokenURIs[tokenId] = _tokenURI;
    }

    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI query for nonexistent token"
        );

        string memory _tokenURI = _tokenURIs[tokenId];
        return _tokenURI;
    }

    function mint(address recipient, string memory uri)
        public
        returns (uint256)
    {
        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();
        _mint(recipient, newItemId);
        _setTokenURI(newItemId, uri);
        return newItemId;
    }

    function transfer(address _seller, address _buyer, uint256 _tokenId) external payable {
        // transfer assets from seller to buyer
        // seller pays the tx fees        
        setApprovalForAll(_seller, true);
        setApprovalForAll(_buyer, true);
        _transfer(_seller, _buyer, _tokenId);
    }

    function burn(uint256 _tokenId) public returns (bool) {
        _burn(_tokenId);
        return true;
    }
}

Here is my command to deploy the SC in blockchain.

const hre = require("hardhat");
async function main() {
  const NFT = await hre.ethers.getContractFactory("MyNFT");
  const nft = await NFT.deploy();
  await nft.deployed();
  console.log("NFT deployed to:", nft.address);
}
main().then(() => process.exit(0)).catch(error => {
  console.error(error);
  process.exit(1);
});

This script is working fine and giving me the contract address after I run this command.

npx hardhat run scripts/deploy-script.js --network matic   

Here is my Minting script.

const hre = require("hardhat");
async function main() {
  const NFT = await hre.ethers.getContractFactory("MyNFT");
  const URI = "ipfs://QmdnfzqwRuTmZwquauTxGs9hXzMaaVczmuSuQbpUU4pRng";
  const WALLET_ADDRESS = "my metamask wallet address -- its funded";
  const CONTRACT_ADDRESS = "contract address that I get from the command above";
  const contract = NFT.attach(CONTRACT_ADDRESS);
  const tokenId = await contract.mint(WALLET_ADDRESS, URI);
  console.log("NFT minted:", contract);
  console.log("TokenID:", tokenId);
}
main().then(() => process.exit(0)).catch(error => {
  console.error(error);
  process.exit(1);
});

This mints the token successfully and I get the response as well.

My problem arises when I am trying to transfer the NFT from one account to another or Burn the NFT.

Here is my transfer code.

const hre = require("hardhat");
async function main() {
  const NFT = await hre.ethers.getContractFactory("MyNFT");  
  const WALLET_ADDRESS = "my meta mask account address that owns NFT";
  const RECIEVER_ADDRESS = "the other meta mask account with 0 balance";
  const CONTRACT_ADDRESS = "the contract address I get";
  const TOKENID = "1";
  const contract = NFT.attach(CONTRACT_ADDRESS);
  await contract.transfer(WALLET_ADDRESS,RECIEVER_ADDRESS, TOKENID);
  console.log("NFT transferred:", contract);  
}
main().then(() => process.exit(0)).catch(error => {
  console.error(error);
  process.exit(1);
});

When i execute this script, i get this following error.

{ Error: cannot estimate gas; transaction may fail or may require manual gas limit (error={"name":"ProviderError","code":-32000,"_isProviderError":true}, method="estimateGas", transaction={"from":"0xB705730CDdDb2Af877A92B8D21bee30A61C0a416","to":"0x6C1da88ACD16D6C3BCb0Fac3Fe2b4C7Aa95C68A0","data":"0x42966c680000000000000000000000003599fe1852aba39cf72d45f5b79f15fb0402eaed","accessList":null}, code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.2.0)
    at Logger.makeError (/home/shahidshaikh/projects/polygon-nfts/node_modules/@ethersproject/logger/src.ts/index.ts:213:28)
    at Logger.throwError (/home/shahidshaikh/projects/polygon-nfts/node_modules/@ethersproject/logger/src.ts/index.ts:225:20)
    at checkError (/home/shahidshaikh/projects/polygon-nfts/node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:76:16)
    at EthersProviderWrapper.<anonymous> (/home/shahidshaikh/projects/polygon-nfts/node_modules/@ethersproject/providers/src.ts/json-rpc-provider.ts:512:20)
    at step (/home/shahidshaikh/projects/polygon-nfts/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:48:23)
    at Object.throw (/home/shahidshaikh/projects/polygon-nfts/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:29:53)
    at rejected (/home/shahidshaikh/projects/polygon-nfts/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:21:65)
    at process.internalTickCallback (internal/process/next_tick.js:77:7)
  reason:
   'cannot estimate gas; transaction may fail or may require manual gas limit',
  code: 'UNPREDICTABLE_GAS_LIMIT',
  error:
   ProviderError: execution reverted
    at HttpProvider.request (/home/shahidshaikh/projects/polygon-nfts/node_modules/hardhat/src/internal/core/providers/http.ts:46:19)
    at LocalAccountsProvider.request (/home/shahidshaikh/projects/polygon-nfts/node_modules/hardhat/src/internal/core/providers/accounts.ts:142:34)
    at process.internalTickCallback (internal/process/next_tick.js:77:7),
  method: 'estimateGas',
  transaction:
   { from: '0xB705730CDdDb2Af877A92B8D21bee30A61C0a416',
     to: '0x6C1da88ACD16D6C3BCb0Fac3Fe2b4C7Aa95C68A0',
     data:
      '0x42966c680000000000000000000000003599fe1852aba39cf72d45f5b79f15fb0402eaed',
     accessList: null } }

Same error when I am trying to burn the NFT using this command.

const hre = require("hardhat");
async function main() {
  const NFT = await hre.ethers.getContractFactory("MyNFT");    
  const CONTRACT_ADDRESS = "contract address";
  const TOKENID = "1";  
  const contract = NFT.attach(CONTRACT_ADDRESS);
  await contract.burn(TOKENID);
  console.log("NFT burned:", contract);  
}
main().then(() => process.exit(0)).catch(error => {
  console.error(error);
  process.exit(1);
});

Please let me know where I am doing a silly mistake!

1 Like

@abcoathup Please have a look :slight_smile:

After adding this configuration parameters in hardhat configuration file, i am able to resolve this issue.

    matic: {
      url: "https://rpc-mumbai.maticvigil.com",
      accounts: [PRIVATE_KEY],
      gas: 2100000,
      gasPrice: 8000000000
    }
  },

However, now i am not able to successfully transfer the tokens to a different Matic account.

Here is my transfer code with contract address.

const hre = require("hardhat");
async function main() {
  const NFT = await hre.ethers.getContractFactory("MyNFT");  
  const WALLET_ADDRESS = "0xB705730CDdDb2Af877A92B8D21bee30A61C0a416";
  const RECIEVER_ADDRESS = "0xDF73E2c9D05bE9894E94dAD0BCc68FEBa4c2C7F9";
  const CONTRACT_ADDRESS = "0x6F0423B3F777C37E4613d20032173864734174d0";
  const TOKENID = "2";
  const contract = NFT.attach(CONTRACT_ADDRESS);
  const result = await contract.transfer(WALLET_ADDRESS,RECIEVER_ADDRESS, TOKENID);
  console.log("NFT transferred:", result);  
}
main().then(() => process.exit(0)).catch(error => {
  console.error(error);
  process.exit(1);
});

When i am running this i am getting this response.

NFT transferred: { hash:
   '0x62a85f7569096cef669fef461beecab1e4a34e1388c21574423ba2ef994c1f9b',
  type: 0,
  accessList: null,
  blockHash: null,
  blockNumber: null,
  transactionIndex: null,
  confirmations: 0,
  from: '0xB705730CDdDb2Af877A92B8D21bee30A61C0a416',
  gasPrice: BigNumber { _hex: '0x01dcd65000', _isBigNumber: true },
  gasLimit: BigNumber { _hex: '0x1127b8', _isBigNumber: true },
  to: '0x6F0423B3F777C37E4613d20032173864734174d0',
  value: BigNumber { _hex: '0x00', _isBigNumber: true },
  nonce: 36,
  data:
   '0xbeabacc8000000000000000000000000b705730cdddb2af877a92b8d21bee30a61c0a416000000000000000000000000df73e2c9d05be9894e94dad0bcc68feba4c2c7f90000000000000000000000000000000000000000000000000000000000000002',
  r:
   '0xbec8c54c7e4db82152cb85b2d14a4609d91b89dff51b9778c6656d41e6169833',
  s:
   '0x66ce4c0fee5d5763b882ea032365ffdfdf332647c41cfb877989fe0c7e175ace',
  v: 160037,
  creates: null,
  chainId: 80001,
  wait: [Function] }

When I view the transaction, i get this error in the explorer.

Error: (Awaiting internal transactions for reason)

Here is my Tx.

https://explorer-mumbai.maticvigil.com/tx/0x62a85f7569096cef669fef461beecab1e4a34e1388c21574423ba2ef994c1f9b/internal-transactions

Also, the to address is the contract address in the response. Shoud’nt it be the address I am passing?

1 Like