0

I am trying to create a smart contract that gives the user an NFT in exchange of some MATIC tokens in the Polygon testnet. I am using Remix IDE and the environment used for teh deployment is the "Injected Provider - Metamask". When I deploy the smart contract, the MATIC token transaction happens succesfully, but my Metamask account doesn´t recieve any NFT. When I try to use the "ownerOf" function the terminal answers with the following error:

call to ERC721.ownerOf errored: Returned error: {"jsonrpc":"2.0","error":"execution reverted: ERC721: invalid token ID"

I have tried with two different contracts. This is one of them:

pragma solidity ^0.8.9; //define version

import "@openzeppelin/contracts@4.8.3/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts@4.8.3/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts@4.8.3/security/Pausable.sol";
import "@openzeppelin/contracts@4.8.3/access/Ownable.sol";
import "@openzeppelin/contracts@4.8.3/utils/Counters.sol";

contract Example_credential1 is ERC721, ERC721Enumerable, Pausable, Ownable {

    event Log(string message);

    // Propoerty variables
    using Counters for Counters.Counter;

    Counters.Counter private _tokenIdCounter;
    //uint256 private _tokenIdCounter;

    uint256 public MINT_PRICE = 0.005 ether;
    uint256 public MAX_SUPPLY = 10000; //we define the max amount of NFTs that can be created

    // Lifecycle Methods
    constructor() ERC721("Example_credential1", "EC1") {
        _tokenIdCounter.increment();
    }

    //Function withdraw
    function withdraw() public onlyOwner() {
        require(address(this).balance > 0, "Balance is zero");
        payable(owner()).transfer(address(this).balance);
    }


    // Pausable Functions
    function pause() public onlyOwner {
        _pause();
    }

    function unpause() public onlyOwner {
        _unpause();
    }


    //Minting functions
    function safeMint(address to) public payable {
        require(msg.value >= MINT_PRICE, "not enough ether sent");
        require(totalSupply() <= MAX_SUPPLY, "No more tokens can be minted");
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _safeMint(to,tokenId);
    }


    // Other functions
    function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize)
        internal
        whenNotPaused
        override(ERC721, ERC721Enumerable)
    {
        super._beforeTokenTransfer(from, to, tokenId, batchSize);
    }

    // The following functions are overrides required by Solidity.

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

And this is the other one. It is a simpler contract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

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

contract Example_credential2 is ERC721 {

    uint256 public MINT_PRICE = 0.005 ether;


    uint256 public tokenCounter;
    constructor() public ERC721("Example_credential2", "EC2") {
        tokenCounter = 0;
    }

    function createCollectible(string memory tokenURI) public returns (uint256){
        uint256 newItemId = tokenCounter;
        _safeMint(msg.sender, newItemId);
        tokenCounter = tokenCounter + 1;
        return newItemId;
    }

}

I keep on getting the same error. Can you help me identify the cause and solve it?

Thank you very much in advanced

Frenom
  • 21
  • 4
  • Just some feedback: declare `tokenId` like this `uint256 public tokenCounter = 1`. In your `createCollectible` function, save gas by not creating `newItemId` and just do `_safeMint(msg.sender, tokenCounter++)` which will assign `1` as your first item's ID and will increment it at the same time. Then `return tokenCounter` – Madbreaks Jun 14 '23 at 16:55

1 Answers1

0

For contract 1, the id starts from 1. So be sure to pass the id from 1 to get ownership of the NFT. For contract 2, the id starts from 0, so be sure to pass the id from 0 to get the ownership of the NFT

In addition, you need to call the mint function after deployment. In case of contract 2, you need to call the createCollectible function to get NFT, with the random string param in the Remix function, for example: createCollectible(foo)

After that you can call ownerOf(0).

Here is my succesful test with call createCollectible function: https://sepolia.etherscan.io/tx/0x45c96fcf1b183871afc3ce20d40e47f0bccc68a201d7181caf7dfcaf7f393f25 and get the token at: https://sepolia.etherscan.io/token/0xbd96ab68b3f292b79b9ff6be4461c7ef157f08d9?a=0

Alex
  • 359
  • 3
  • 15