Function _setTokenURI() in ERC721 is gone with pragma ^0.8.0

I have the same error, now it’s OK:

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

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract HarddiskCafe is ERC721URIStorage{
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;
    mapping(string => uint8) hashes;
    
    constructor() ERC721("HarddiskCafe", "HDC") {}
  
    function awardItem(address recipient, string memory hash, string memory metadata) public returns (uint256){
        require(hashes[hash] != 1);
        hashes[hash] = 1;
        _tokenIds.increment();
        uint256 newItemId = _tokenIds.current();
        _mint(recipient, newItemId);
        _setTokenURI(newItemId, metadata);
        
        return newItemId;
    }
}
2 Likes

Hi @samshi,

You can try with the Contracts Wizard: https://zpl.in/wizard

1 Like

I’m having trouble using ERC721URIStorage because I’m currently using ERC721Enumerable which both inherit from ERC721. Is there a way I can use both? It’d be great if you guys created an extension that implemented both of these into 1 file.

Take a look at Contracts Wizard and select both URI Storage and Enumerable to see how you can combine them into one contract.

Hey @sjuanati thank you for sharing this. Could you tell me in your mint method, what is the tokenURI_ syntax? What get’s input here, the return of tokenURI method? Scott

I mixed the following features at wizard: URI storage, mintable and ownable. It gave me back:
'''
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.2;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract PANA is ERC721, ERC721URIStorage, Ownable {
constructor() ERC721("PANA", "PANA") {}

function safeMint(address to, uint256 tokenId) public onlyOwner {
    _safeMint(to, tokenId);
}

function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
    super._burn(tokenId);
}

function tokenURI(uint256 tokenId)
    public
    view
    override(ERC721, ERC721URIStorage)
    returns (string memory)
{
    return super.tokenURI(tokenId);
}
} '''

My question is: why do we have _burn function? I see it returns super.TokenURI(tokenId) which executes the same function but from the contract that is inheriting. thanks beforehand.

This is an override that is required by Solidity even though it does nothing. Solidity basically requires you to explicitly say that you want the _burn implementation from your parent.

I've been compiling with and without _burn function. Compiler specifies the functions needed to override at error message.

Hey i'm trying to implement this code in my nft cause my NFT's are dynamically minted and i'd like to set the base URI myself but i'm getting this error instead

project:/contracts/DogeWars.sol:451:25: TypeError: Data location must be "calldata" for parameter in external function, but "memory" was given.
    function setBaseURI(string memory baseURI_) external onlyOwner() {
                        ^--------------------^

Hi Frangio, i'm using the contract wizard to implement the base uri function, but i'm getting this error, do i need to set the base uri directly in the ERC721 contract i'm inheriting from?

TypeError: Function has override specified but does not override anything.
   function _baseURI() internal pure override returns (string memory) {
                                     ^------^

Compilation failed. See above.

You seem to be using an older Solidity version and possibly an older OpenZeppelin Contracts version.

To implement the code in this thread, make sure you're using Solidity 0.8 and OpenZeppelin Contracts 4.x.