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