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!

2 Likes

@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

I am having the same issue although setting gas: 2100000, gasPrice: 8000000000 in the hardhat config did not solve my burn functionality. I have the same error as you and I am on the same polygon test network. Has anyone found a way to solve this issue?

4 Likes

The most likely reason for this error is that you are using "string" data type for URIs, and so the compiler naturally cannot estimate the gas usage when calling the mint function as the uri parameter's length can be arbitrary. Solidity documentation recommends the following:

As a general rule, use bytes for arbitrary-length raw byte data and string for arbitrary-length string (UTF-8) data. If you can limit the length to a certain number of bytes, always use one of the value types bytes1 to bytes32 because they are much cheaper.

The solution with polygon did not work for me, is there a higher value to use with Avax? I have tried changing gas and gasPrice but it still doesn't work for me.

There is an option like allowUnlimitedContractSize: true,, you might find its usage below. In one place I found Error: cannot estimate gas; transaction may fail or may require manual gas limit might appear by different reasons and cannot estimate gas might throttle the main error -- can not prove it in my experience, when I had increased gas limit the issue was disappeared, but it is important to keep it in mind.

@Gelassen the option you mention did not work for me, nor did the ethereum stack exchange options

Thank you for sharing your feedback on this workaround. I believe your code sample is different from topic starter's one, by open your own topic with details regarding your own issue chances to get help from community should be higher.

Not much difference is the same configuration based on the hardhat.config.js and I think it's a good idea to mention that those methods didn't work for me. Maybe it will save someone else's time or you can help me here directly. I don't see a problem

Thanks, this solved it for me.