Why is my NFT metadata not showing on Opensea?

I am developing a NFT contract on ETH using open Zeppelin, and reached the stage where, I am deploy on rinkeby. However there appears to an issue with the tokenURI and contractURI as the image and metadata is not showing on opensea.

I implement the tokenURI and ContractURI like this:

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

import "hardhat/console.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
//access control
import "@openzeppelin/contracts/access/Ownable.sol";

// Helper functions OpenZeppelin provides.
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

import "./libraries/Base64.sol";

contract MetropolisWorldGenesis is ERC721, Ownable {


string private _contractURI;

function contractURI() public view returns (string memory) {
        return _contractURI;

function tokenURI(uint256 _tokenId) public view override returns (string memory) {
        PropertyAttributes memory propAttributes = nftHolderAttributes[_tokenId];

        string memory json = Base64.encode(
                '{"name": "',
                '", "description": "',propAttributes.description,'", "image": "',
                '", "attributes": [ { "trait_type": "Tower", "value": ',propAttributes.properties.tower,', "trait_type": "District", "value":',propAttributes.properties.district, ', "trait_type": "neighborhood", "value":',propAttributes.properties.neighborhood,',]}'

        string memory output = string(
            abi.encodePacked("data:application/json;base64,", json)
        return output;

    function setContractURI(
        string memory name, string memory desc,
        string memory image,string memory link, 
        uint royalty) public onlyOwner() {

        string memory x = Base64.encode(
                '{"name": "',
                '", "description": "',
                '", "image": "', 
                '", "external_link": "', 
                '","seller_fee_basis_points":"', royalty, // 100 Indicates a 1% seller fee
                '", "fee_recipient": "0xA97F337c39cccE66adfeCB2BF99C1DdC54C2D721" }' // Where seller fees will be paid to.}
        _contractURI = string(abi.encodePacked(
                "data:application/json;base64,", x
        console.log("contract uri updated");

When run locally the return the tokenURI gives the following out put, which resolves to correct data in the browser:


Any Ideas where I am going wrong?

1 Like

Did you got it fixed?

May be the metadata have to be formatted like the below:


    "attributes": [


        "trait_type": "Zazu",

        "value": "Zue1"



        "trait_type": "Eye color",

        "value": "Grey"



    "description": "This is very interesting and learning",

    "image": "https://gateway.pinata.cloud/ipfs/QmXmRDvPAyEzC2kE3AJKR4z3Hxmc4YcUmsv3yURRXn8PVy",

    "name": "Shuku_Shuku"