Can the metadata for ERC1155 be saved on-chain?

:memo:Details
I’m implementing an ERC-1155 contract, and each NFT has a unique value. Can this be saved on-chain, instead having to save the metadata for each token on IPFS ?

1 Like

Hi @Aseme_Kifen,

Welcome to the community :wave:

You can add metadata on-chain. You would need to add functionality into the minting process to add metadata and functionality to retrieve metadata. Depending on what metadata you are storing this will increase gas costs during minting. Where possible you should consider keeping as little data on chain as possible due to cost.

The OpenZeppelin Contracts implementation of ERC1155 uses off chain metadata, with one token URI for metadata where clients replace {id} with the actual token ID:

_From: https://docs.openzeppelin.com/contracts/3.x/erc1155#constructing_an_erc1155_token_contract_
The uri can include the string {id} which clients must replace with the actual token ID, in lowercase hexadecimal (with no 0x prefix) and leading zero padded to 64 hex characters.

This means that token metadata is off-chain and doesn't support using IPFS hashes for each NFT. To use an IPFS has per NFT you could look at ERC721.

Let me know if you have further questions.

Hi @Aseme_Kifen,

Just wanted to followup to see if you needed more information?

A post was split to a new topic: Saving NFT metadata offchain

Hi @abcoathup ! Very interesting - I had a question following on from this - was wondering if you may be able to assist?
I'm creating an ERC721 contract for an NFT, and I've been following methodology to package my JSON data and store on IPFS, for Opensea etc to read from a URI. What I'm trying to also do is give a Token Owner the option to Name their NFT, or rename it, therefore having the "Name" as on-chain metadata. I was wondering how this can be done? Essentially, part of the metadata is from TokenURI, and the Name is stored on-chain. Is this possible?

Would greatly appreciate any help on this!

I understand that storing the metadata onchain cost more gas but what about a function that return a string formatted like the metadata json and populated by variable from structs in the contract. Eg:

function tokenURI(uint256 tokenId) public view override returns (string memory) {
        <Struct> memory item = _idsToStructs[tokenId];

        string memory json = Base64.encode(
            bytes(
                string(
                    abi.encodePacked(
                        '{"name": "',
                        item.name,
                        ' SYMBOL#',
                        Strings.toString(tokenId),
                        '", "description": "This NFT certifies his owner master this skill", "image": "',
                        item.imageURI,
                        '"}'
                    )
                )
            )
        );
        string memory output = string(abi.encodePacked('data:application/json;base64,', json));
        return output;
    }