I have a simple nft contract and I want to create mint functions that if you press one or another that tokenId is bound to a URI I decide.

I already tried multiple ways to do it but I got an error that doesn't let me complete it.

The error is that when I mint in one or another mint function the URI is not the one I decided. So something is happening when the token is created but I don’t see the error.

Let's put a sample of the code

// SPDX-License-Identifier: MIT

pragma solidity >=0.8.9 <0.9.0;

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

contract Testing is ERC721, Ownable, ReentrancyGuard {

  using Counters for Counters.Counter;
  using Strings for uint256;

  mapping(address => bool) public whitelistedAddresses;

  string public uriPrefix;
  string public uriSuffix = '.json';

  Counters.Counter private _tokenIdCounter;

  enum TokenType { Type1, Type2 }

  mapping (uint256 => TokenType) tokenType;

  string tokenURI1 = 'ipfs://test1';
  string tokenURI2 = 'ipfs://test2';
  uint256 public maxSupply = 1000;
  uint256 public maxWhitelistSupply = 200;
  uint256 public maxPresaleSupply = 400;
  uint256 public maxMintAmountPerTx = 400;

  bool public paused = false;
  bool public revealed = false;

  address public a1;
  address public a2;

    string memory _tokenName,
    string memory _tokenSymbol,
    string memory _uriPrefix
  ) ERC721(_tokenName, _tokenSymbol) {

    function mint1(uint256 _mintAmount) public payable { 
      uint256 _tokenId = _tokenIdCounter.current(); 
      tokenType[_tokenId] = TokenType.Type1;
      _safeMint(_msgSender(), _mintAmount);   
    function mint2(uint256 _mintAmount) public payable { 
      uint256 _tokenId = _tokenIdCounter.current();
      tokenType[_tokenId] = TokenType.Type2;
      _safeMint(_msgSender(), _mintAmount); 

  function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
      if (tokenType[tokenId] == TokenType.Type1) {
          return string(abi.encodePacked(tokenURI1, tokenId.toString()));
      } else {
          return string(abi.encodePacked(tokenURI2, tokenId.toString()));

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

    string memory currentBaseURI = _baseURI();
    return bytes(currentBaseURI).length > 0
        ? string(abi.encodePacked(currentBaseURI, _tokenId.toString(), uriSuffix))
        : '';
  } */

  function setMaxMintAmountPerTx(uint256 _maxMintAmountPerTx) public onlyOwner {
    maxMintAmountPerTx = _maxMintAmountPerTx;

  function setUriPrefix(string memory _uriPrefix) public onlyOwner {
    uriPrefix = _uriPrefix;

  function setUriSuffix(string memory _uriSuffix) public onlyOwner {
    uriSuffix = _uriSuffix;

  function setPaused(bool _state) public onlyOwner {
    paused = _state;

        // Set team addresses
    function setAddresses(address[] memory _a) public onlyOwner {
        a1 = _a[0];
        a2 = _a[1];

  function withdraw() public onlyOwner {
    // This will pay another address 97% of the NFT sale.
    // =============================================================================
    (bool tw, ) = payable(a1).call{value: address(this).balance * 97 / 100}("");
    // =============================================================================
    // This will transfer the remaining contract balance to the owner.
    // Do not remove this otherwise you will not be able to withdraw the funds.
    // =============================================================================
    (bool va, ) = payable(a2).call{value: address(this).balance}("");
    // =============================================================================

  function _baseURI() internal view virtual override returns (string memory) {
    return uriPrefix;

The error is that I mint, let’s say, 2 tokens in mint1 function and 2 more in mint2 function, so when I check the URI of those tokens, the tokens number 1,3 and 4 have the tokenURI1 and just the 2nd token has the tokenURI2. This is an example of course but that is the error that is happening.

I need help, so anyone that can help me I will be very grateful.

  • Can you update the code, I dont think this code will run given that you are passing _tokenId as a parameter but also creating a new token id inside, and both variables are called the same, that will never work
    – Julissa DC
    Sep 13, 2022 at 13:26
  • Hey Julissa. It will work, it will just 'shadow' it. So there's no use in having that parameter there. But I guess he modified his real code to provide us with this example. But yes, we may need a better example to be able to help him. A compilable code on its own. @Pablo, we need to recreate your error to be able to help you. Could you provide us with the Counters code too and a code that compiles, so we don't have to add/remove anything from it to test it first. Sep 13, 2022 at 14:15
  • Hello, i just edited the post with the complete compiled code. Hope you can find what i´m missing!
    – Pablo
    Sep 13, 2022 at 23:07
  • @Pablo What is the purpose of _mintAmount? In the OZ library the second parameter of _safeMint() should be tokenId. If you are starting with solidity first create a function that mint a single token, then create a function that can mint in batch several tokens.
    – Ismael
    Sep 16, 2022 at 3:18
  • I already do that, and thats a modified _SafeMint. MintAmount is just the numbers of tokens you want to mint, but thats not the problem. The problem is that i want to have multiple mint functions with different tokenURI in them.
    – Pablo
    Sep 16, 2022 at 5:14


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.