You did not set the TokenURI for NFT, so when NFT gets the URI, BaseURI + TokenID is used.Look at the source code.
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = baseURI();
// If there is no base URI, return the token URI.
if (bytes(base).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(base, _tokenURI));
}
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
return string(abi.encodePacked(base, tokenId.toString()));
}
It returns the URI: https://gateway.pinata.cloud/ipfs/0
This, of course, is not ideal, the ideal URI should be: https://gateway.pinata.cloud/ipfs/Qmf43nycxRXdwdq3GqT7SKU3MvRyBvbpjzufzZR8ASkMGb
I think you see the reason for the problem here.
The next thing you need to do is call _setTokenUri to store the CID from IPFS so that you can get the correct IPFS link when reading the NFT.
/**
* @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
This function is an internal function, and you should provide an external function to use it, but security must be taken care of, or anyone can modify it!
Inside SimpleNFT.sol, instead of the bool public revealed
variable you could have a mapping (uint256 => bool) revealed
.
This maps each tokenId
to a boolean value (it is false by default). This boolean value specifies whether the token identified by tokenId
is revealed or not.
Then, inside the mint function we want to reveal tokens as they are minted:
function mint(uint256 _mintAmount) public payable {
// ...
for (uint256 i = 1; i <= _mintAmount; i++) {
_safeMint(msg.sender, supply + i);
// by adding the below line:
revealed[supply + i] = true;
}
}
Next we need to update the tokenURI function
function tokenURI(uint256 tokenId)
{
// ...
// change line to
if(revealed[tokenId] == false) {
return notRevealedUri;
}
// ...
}
Finally, remove the reveal function altogether.
Best Answer
https://ipfs.io/ipfs/QmPR6z3JM8vtUe1PNRsUD6CtBbu3yTt1PaKjNhkG3LWduH/
This is a directory or folder, not a json file.If you set tokenURI(0) to
ipfs://QmPR6z3JM8vtUe1PNRsUD6CtBbu3yTt1PaKjNhkG3LWduH/QmUvcr9d9XTgwTNYf9tBGcdpEcgGFdy5kCaqdVZEVmzKLL
ORipfs://QmUvcr9d9XTgwTNYf9tBGcdpEcgGFdy5kCaqdVZEVmzKLL
, you may be able to display the metadata.