0

Hey everyone

I'm new to NFT development and I'm trying to develop a simple property ownership and marketplace using the ERC721 token standard. since I'm so unfamiliar with json I have some problems with the metadata.

I'm holding the property attributes in this struct :

struct PropSpec {
        uint256 height;
        uint256 width;
        uint256 x;
        uint256 y;
    }

and I want to have these attributes in the metadata (should I ??) and I tried to use the function below but the values are not shown correctly in the output because i'm not writing json correctly i guess.

function tokenURI(
        uint256 tokenId
    ) public view override returns (string memory) {
        uint256 height = tokenIdtoSpec[tokenId].height;
        uint256 width = tokenIdtoSpec[tokenId].width;
        uint256 x = tokenIdtoSpec[tokenId].x;
        uint256 y = tokenIdtoSpec[tokenId].y;
        
        return
            string(
                abi.encodePacked(
                    _baseURI(),
                    Base64.encode(
                        bytes(
                            abi.encodePacked(
                                '{"name":"',
                                name(),
                                '","describtion":"EProp is a decentralized property ownership system.","attributes":[{"height":"',
                                height,
                                '","width":"',
                                width,
                                '","x":"',
                                x,
                                '","y":"',
                                y,
                                '",}],"image":"',
                                s_imageUri,
                                '"}'
                            )
                        )
                    )
                )
            );
    }

the output of tokenURI() : data:application/json;base64,eyJuYW1lIjoiZVByb3AiLCJkZXNjcmlidGlvbiI6IkVQcm9wIGlzIGEgZGVjZW50cmFsaXplZCBwcm9wZXJ0eSBvd25lcnNoaXAgc3lzdGVtLiIsImF0dHJpYnV0ZXMiOlt7ImhlaWdodCI6IgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsIiwid2lkdGgiOiIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQSIsIngiOiIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASIsInkiOiIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASIsfV0sImltYWdlIjoiaXBmczovL1FtVlFmcXY1WU5YTDczeXBHMTI1QkJzb29XUmlWdWJGNW5tMmc5dFJ0UHR5eDgifQ==

my question is

1st: should I have my property specs in the metadata?

2nd: if I should, how should the json be in this case?

ps: I would appreciate any other advice or recommendation

UPDATE:

the problem was solved by converting variables to string

now I have a new problem I've minted the token and I can see it in the metamask but without its name and image the s_imageUri variable contains the IPFS CID of my image: "ipfs://QmVQfqv5YNXL73ypG125BBsooWRiVubF5nm2g9tRtPtyx8" and now the output of JSON is :

{"name":"eProp","describtion":"EProp is a decentralized property ownership system.","attributes":[{"height":"44","width":"65","x":"1","y":"1"}],"image":"ipfs://QmVQfqv5YNXL73ypG125BBsooWRiVubF5nm2g9tRtPtyx8"}

and here is what i see in the metamask :

enter image description here

the new function :

function tokenURI(
        uint256 tokenId
    ) public view override returns (string memory) {
        string memory height = Strings.toString(tokenIdtoSpec[tokenId].height);
        string memory width = Strings.toString(tokenIdtoSpec[tokenId].width);
        string memory x = Strings.toString(tokenIdtoSpec[tokenId].x);
        string memory y = Strings.toString(tokenIdtoSpec[tokenId].y);

        return
            string(
                abi.encodePacked(
                    _baseURI(),
                    Base64.encode(
                        bytes(
                            abi.encodePacked(
                                '{"name":"',
                                name(),
                                '","describtion":"EProp is a decentralized property ownership system.","attributes":[{"height":"',
                                height,
                                '","width":"',
                                width,
                                '","x":"',
                                x,
                                '","y":"',
                                y,
                                '"}],"image":"',
                                s_imageUri,
                                '"}'
                            )
                        )
                    )
                )
            );
    }

1 Answer 1

0

Q1: If you should have the property specifications in the metadata or not is totally up to you. Ask yourself if your use case requires you to do so?

Q2: However, if that is the case, then what you need to do in order for the JSON to show the correct output of the property specifications is, you need to convert the uint256 to strings.

First you need to make use of the "Strings" library from OpenZeppelin or an equivalent option to make uint256 into strings. You can get it right here. Then import it into your contract, and use the following code instead:

Place this at the top of your contract:

using Strings for uint256;

And then replace your code with this:

                abi.encodePacked(
                    _baseURI(),
                    Base64.encode(
                        bytes(
                            abi.encodePacked(
                                '{"name":"',
                                name(),
                                '","description":"EProp is a decentralized property ownership system.","attributes":[{"height":"',
                                height.toString(),
                                '","width":"',
                                width.toString(),
                                '","x":"',
                                x.toString(),
                                '","y":"',
                                y.toString(),
                                '"}],"image":"',
                                s_imageUri,
                                '"}'
                            )
                        )
                    )
                );

I hope this will help solve your issue. :)

1
  • Comments have been moved to chat; please do not continue the discussion here. Before posting a comment below this one, please review the purposes of comments. Comments that do not request clarification or suggest improvements usually belong as an answer, on Ethereum Meta, or in Ethereum Chat. Comments continuing discussion may be removed.
    – Ismael
    Sep 25, 2023 at 1:35

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.