0

I am new to web3 and smart contract development and I am stuck trying to call a function in my smart contract.

I have a mintToken function:

    function mintToken(uint256 tokenId, string memory _type, string memory _breed, uint256 _herdNum) 
    public returns(uint256) {

        NFT storage nft = id2NFT[tokenId];
        nft.id = tokenId;
        nft.animalType = _type;
        nft.breed = _breed;
        nft.herdNumber = _herdNum;
        nft.intervals.push(block.timestamp);

        _safeMint(msg.sender, tokenId);

        emit Mint(msg.sender, tokenId);

        return nft.id;
    }

The full contract is here:

// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.0.0
pragma solidity >=0.5.0 <0.9.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract ProductTracker is ERC721("HalalTrace", "HTrace") {

    address public owner;
    

    event Mint(address minter, uint256 tokenId);
    event Updated(address minter, string newURI);

    /**
     * @dev defines an event which occurs at the major control points of the supply chain
     */
    struct Event {
        address participant;
        string dataURI;
        uint256 timestamp;
    }

    /**
    * @dev defines the basic metadata of each animal NFT.
    */
    struct NFT {
        uint256 id;
        string animalType;
        string breed;
        uint256 herdNumber;
        Event[] trace;
        uint256[] intervals;
    }

    /**
    * @dev maps ids to products
    */
    mapping (uint256 => NFT) private id2NFT;

    constructor() {
        owner = msg.sender;
    }

    /**
     * @dev function to mint animal nft
     * @param tokenId the unique id of the animal on the farm
     * @param _type the type of animal
     * @param _breed the breed of the animal
     * @param _herdNum the herd number of the animal
     */
    function mintToken(uint256 tokenId, string memory _type, string memory _breed, uint256 _herdNum) 
    public returns(uint256) {

        NFT storage nft = id2NFT[tokenId];
        nft.id = tokenId;
        nft.animalType = _type;
        nft.breed = _breed;
        nft.herdNumber = _herdNum;
        nft.intervals.push(block.timestamp);

        _safeMint(msg.sender, tokenId);

        emit Mint(msg.sender, tokenId);

        return nft.id;
    }

    /**
     * @dev function to update the event metadata
     * @param tokenId the unique id of the animal
     * @param dataURI the new uri pointing to IPFS file
     */
    function updateTrace(uint256 tokenId, string memory dataURI) public {
        // ensure only the owner of the NFT can update it
        require(ownerOf(tokenId) == msg.sender);

        NFT storage nft = id2NFT[tokenId];
        nft.trace.push(Event(msg.sender, dataURI, block.timestamp));

        emit Updated(msg.sender, dataURI);
    }

    /**
    * @dev function to return the details for a given animal product
    */
    function getAnimalDetails(uint256 tokenId) 
        public 
        view 
        returns (
            string memory, 
            string memory, 
            uint256,
            Event[] memory
        ) 
    {
        return (
            id2NFT[tokenId].animalType,
            id2NFT[tokenId].breed,
            id2NFT[tokenId].herdNumber,
            id2NFT[tokenId].trace
        );
    }
}

This function for now does not require the minter to send any ether, hence why it is simply public and not payable.

When deploying using Remix IDE, I can use the UI to call this mint function, passing in the parameters the function requires.

However, when using a node script, I cannot call this function. I keep getting various errors. From my understanding, it has something to do with the gas.

Here's my mintToken.js

const { ethers } = require("ethers");
const contract = require('../../contract/artifacts/contracts/NFTTracker.sol/ProductTracker.json');
const API_KEY = process.env.POLYGON_AMOY_KEY
const ADDRESS = process.env.CONTRACT_ADDRESS
const PRIVATE_KEY = process.env.PRIVATE_KEY

  // provider - Alchemy
  const provider = new ethers.providers.JsonRpcProvider(API_KEY);


  // signer - me
  const signer = new ethers.Wallet(PRIVATE_KEY, provider);


  // contract instance
  const trackerContract = new ethers.Contract(ADDRESS, contract.abi, signer);



async function main() {
    // call a function to see if interaction works
    const owner = await trackerContract.owner()
    console.log(`The owner is ${owner}`)

    // call mint function
    const contractWallet = trackerContract.connect(signer)

    const tx = await contractWallet.mintToken(1, "testing", "testing", 1234)
    await tx.wait()

    console.log(tx)

}

main()

With this line of code:

const tx = await contractWallet.mintToken(1, "testing", "testing", 1234)

I get the following error:

Error: cannot estimate gas; transaction may fail or may require manual gas limit [ See: https://links.ethers.org/v5-errors-UNPREDICTABLE_GAS_LIMIT ] (error={"reason":"execution reverted","code":"UNPREDICTABLE_GAS_LIMIT","method":"estimateGas","transaction":{"from":"0x892D8dF4897f7126706946ec58aA2B7BE1F36573","maxPriorityFeePerGas":{"type":"BigNumber","hex":"0x59682f00"},"maxFeePerGas":{"type":"BigNumber","hex":"0x59682f1e"},"to":"0x16dc429c99945251B959B933f79bf96eE2E7Ec2e","data":"0x92566a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000004d20000000000000000000000000000000000000000000000000000000000000006636174746c6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005616e677573000000000000000000000000000000000000000000000000000000","type":2,"accessList":null},"error":{"reason":"processing response error","code":"SERVER_ERROR","body":"{\"jsonrpc\":\"2.0\",\"id\":51,\"error\":{\"code\":3,\"message\":\"execution reverted\",\"data\":\"0x73c6ac6e0000000000000000000000000000000000000000000000000000000000000000\"}}","error":{"code":3,"data":"0x73c6ac6e0000000000000000000000000000000000000000000000000000000000000000"},"requestBody":"{\"method\":\"eth_estimateGas\",\"params\":[{\"type\":\"0x2\",\"maxFeePerGas\":\"0x59682f1e\",\"maxPriorityFeePerGas\":\"0x59682f00\",\"from\":\"0x892d8df4897f7126706946ec58aa2b7be1f36573\",\"to\":\"0x16dc429c99945251b959b933f79bf96ee2e7ec2e\",\"data\":\"0x92566a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000004d20000000000000000000000000000000000000000000000000000000000000006636174746c6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005616e677573000000000000000000000000000000000000000000000000000000\"}],\"id\":51,\"jsonrpc\":\"2.0\"}","requestMethod":"POST","url":"https://polygon-amoy.g.alchemy.com/v2/gtILQ7A26pMUgtf-l9QqNMU_PSdUXZ-3"}}, tx={"data":"0x92566a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000004d20000000000000000000000000000000000000000000000000000000000000006636174746c6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005616e677573000000000000000000000000000000000000000000000000000000","to":{},"from":"0x892D8dF4897f7126706946ec58aA2B7BE1F36573","type":2,"maxFeePerGas":{"type":"BigNumber","hex":"0x59682f1e"},"maxPriorityFeePerGas":{"type":"BigNumber","hex":"0x59682f00"},"nonce":{},"gasLimit":{},"chainId":{}}, code=UNPREDICTABLE_GAS_LIMIT, version=abstract-signer/5.7.0)
    at Logger.makeError (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/logger/lib/index.js:238:21)
    at Logger.throwError (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/logger/lib/index.js:247:20)
    at /home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/abstract-signer/lib/index.js:365:47
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Promise.all (index 7) {
  reason: 'cannot estimate gas; transaction may fail or may require manual gas limit',
  code: 'UNPREDICTABLE_GAS_LIMIT',
  error: 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", method="estimateGas", transaction={"from":"0x892D8dF4897f7126706946ec58aA2B7BE1F36573","maxPriorityFeePerGas":{"type":"BigNumber","hex":"0x59682f00"},"maxFeePerGas":{"type":"BigNumber","hex":"0x59682f1e"},"to":"0x16dc429c99945251B959B933f79bf96eE2E7Ec2e","data":"0x92566a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000004d20000000000000000000000000000000000000000000000000000000000000006636174746c6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005616e677573000000000000000000000000000000000000000000000000000000","type":2,"accessList":null}, error={"reason":"processing response error","code":"SERVER_ERROR","body":"{\"jsonrpc\":\"2.0\",\"id\":51,\"error\":{\"code\":3,\"message\":\"execution reverted\",\"data\":\"0x73c6ac6e0000000000000000000000000000000000000000000000000000000000000000\"}}","error":{"code":3,"data":"0x73c6ac6e0000000000000000000000000000000000000000000000000000000000000000"},"requestBody":"{\"method\":\"eth_estimateGas\",\"params\":[{\"type\":\"0x2\",\"maxFeePerGas\":\"0x59682f1e\",\"maxPriorityFeePerGas\":\"0x59682f00\",\"from\":\"0x892d8df4897f7126706946ec58aa2b7be1f36573\",\"to\":\"0x16dc429c99945251b959b933f79bf96ee2e7ec2e\",\"data\":\"0x92566a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000004d20000000000000000000000000000000000000000000000000000000000000006636174746c6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005616e677573000000000000000000000000000000000000000000000000000000\"}],\"id\":51,\"jsonrpc\":\"2.0\"}","requestMethod":"POST","url":"https://polygon-amoy.g.alchemy.com/v2/gtILQ7A26pMUgtf-l9QqNMU_PSdUXZ-3"}, code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.7.2)
      at Logger.makeError (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/logger/lib/index.js:238:21)
      at Logger.throwError (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/logger/lib/index.js:247:20)
      at checkError (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:122:20)
      at JsonRpcProvider.<anonymous> (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:751:47)
      at step (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:48:23)
      at Object.throw (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:29:53)
      at rejected (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:21:65)
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
    reason: 'execution reverted',
    code: 'UNPREDICTABLE_GAS_LIMIT',
    method: 'estimateGas',
    transaction: {
      from: '0x892D8dF4897f7126706946ec58aA2B7BE1F36573',
      maxPriorityFeePerGas: BigNumber { _hex: '0x59682f00', _isBigNumber: true },
      maxFeePerGas: BigNumber { _hex: '0x59682f1e', _isBigNumber: true },
      to: '0x16dc429c99945251B959B933f79bf96eE2E7Ec2e',
      data: '0x92566a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000004d20000000000000000000000000000000000000000000000000000000000000006636174746c6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005616e677573000000000000000000000000000000000000000000000000000000',
      type: 2,
      accessList: null
    },
    error: Error: processing response error (body="{\"jsonrpc\":\"2.0\",\"id\":51,\"error\":{\"code\":3,\"message\":\"execution reverted\",\"data\":\"0x73c6ac6e0000000000000000000000000000000000000000000000000000000000000000\"}}", error={"code":3,"data":"0x73c6ac6e0000000000000000000000000000000000000000000000000000000000000000"}, requestBody="{\"method\":\"eth_estimateGas\",\"params\":[{\"type\":\"0x2\",\"maxFeePerGas\":\"0x59682f1e\",\"maxPriorityFeePerGas\":\"0x59682f00\",\"from\":\"0x892d8df4897f7126706946ec58aa2b7be1f36573\",\"to\":\"0x16dc429c99945251b959b933f79bf96ee2e7ec2e\",\"data\":\"0x92566a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000004d20000000000000000000000000000000000000000000000000000000000000006636174746c6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005616e677573000000000000000000000000000000000000000000000000000000\"}],\"id\":51,\"jsonrpc\":\"2.0\"}", requestMethod="POST", url="https://polygon-amoy.g.alchemy.com/v2/gtILQ7A26pMUgtf-l9QqNMU_PSdUXZ-3", code=SERVER_ERROR, version=web/5.7.1)
        at Logger.makeError (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/logger/lib/index.js:238:21)
        at Logger.throwError (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/logger/lib/index.js:247:20)
        at /home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/web/lib/index.js:313:32
        at step (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/web/lib/index.js:33:23)
        at Object.next (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/web/lib/index.js:14:53)
        at fulfilled (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/web/lib/index.js:5:58)
        at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
      reason: 'processing response error',
      code: 'SERVER_ERROR',
      body: '{"jsonrpc":"2.0","id":51,"error":{"code":3,"message":"execution reverted","data":"0x73c6ac6e0000000000000000000000000000000000000000000000000000000000000000"}}',
      error: Error: execution reverted
          at getResult (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/providers/lib/json-rpc-provider.js:191:21)
          at processJsonFunc (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/web/lib/index.js:356:22)
          at /home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/web/lib/index.js:288:46
          at step (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/web/lib/index.js:33:23)
          at Object.next (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/web/lib/index.js:14:53)
          at fulfilled (/home/ukush/HalalTrace/HalalTrace/server/node_modules/@ethersproject/web/lib/index.js:5:58)
          at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
        code: 3,
        data: '0x73c6ac6e0000000000000000000000000000000000000000000000000000000000000000'
      },
      requestBody: '{"method":"eth_estimateGas","params":[{"type":"0x2","maxFeePerGas":"0x59682f1e","maxPriorityFeePerGas":"0x59682f00","from":"0x892d8df4897f7126706946ec58aa2b7be1f36573","to":"0x16dc429c99945251b959b933f79bf96ee2e7ec2e","data":"0x92566a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000004d20000000000000000000000000000000000000000000000000000000000000006636174746c6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005616e677573000000000000000000000000000000000000000000000000000000"}],"id":51,"jsonrpc":"2.0"}',
      requestMethod: 'POST',
      url: 'https://polygon-amoy.g.alchemy.com/v2/gtILQ7A26pMUgtf-l9QqNMU_PSdUXZ-3'
    }
  },
  tx: {
    data: '0x92566a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000004d20000000000000000000000000000000000000000000000000000000000000006636174746c6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005616e677573000000000000000000000000000000000000000000000000000000',
    to: Promise { '0x16dc429c99945251B959B933f79bf96eE2E7Ec2e' },
    from: '0x892D8dF4897f7126706946ec58aA2B7BE1F36573',
    type: 2,
    maxFeePerGas: BigNumber { _hex: '0x59682f1e', _isBigNumber: true },
    maxPriorityFeePerGas: BigNumber { _hex: '0x59682f00', _isBigNumber: true },
    nonce: Promise { 37 },
    gasLimit: Promise { <rejected> [Circular *1] },
    chainId: Promise { 80002 }
  }
}

After doing some searching on the Ethers docs, I understand I need to manually declare the gas price. So I changed the line to:

    const tx = await contractWallet.mintToken(1, "testing", "testing", 1234, {
      gasPrice: 31000000000,
      gasLimit: 1000000
    })

With this line, the tx.wait() never resolves.

Since my contract function is not payable, I don't need to send any ether to it right?

My contract is deployed to the Polygon Amoy testnet (0x16dc429c99945251B959B933f79bf96eE2E7Ec2e). I have verified that the contract is there.

I don't understand why I can call this mintToken function in RemixIDE and not with my own account. I have 0.3629 MATIC which should be enough to call the function considering the gasPrice is 31000000000 and the limit is only 100000 (I read somewhere that 25,000 is enough).

Unless I am misunderstanding the concept of gas and gas price?

edit: I provided the full contract just incase

2 Answers 2

1

Usually, this error message indicates that your transaction is going to fail.

Here's what you can do

  1. Call the same function from RemixIDE/Etherscan after deployment
  2. If the function is working fine make sure to console the parameters before giving a call to the function via JS code.
  3. Alternatively, if the function call from RemixIDE/Etherscan also fails, then there is something wrong with your smart contract most probably.
1
  • I've got this working now! There were a number of issues: 1) I was importing the wrong contract artifact, I think I was importing the one I deployed to polygon mumbai testnet (not sure if that actually makes a difference however) 2) I didn't have a check in my mint function to ensure the same tokenID was not being used more than once Once I fixed this, deployed again using hardhat ignition and updated my script to get the new contract artifact and point to the new deployed address, it worked a treat!
    – user134392
    Commented Apr 18 at 9:16
0

I've got this working now! There were a number of issues: 1) I was importing the wrong contract artifact, I think I was importing the one I deployed to polygon mumbai testnet (not sure if that actually makes a difference however) 2) I didn't have a check in my mint function to ensure the same tokenID was not being used more than once Once I fixed this, deployed again using hardhat ignition and updated my script to get the new contract artifact and point to the new deployed address, it worked a treat!

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.