How to: ERC-1155 ID Substitution for Token URI

I haven’t encountered any issues yet. But I’m not sure I understand how to implement ID substitution for this token standard.

If I understand correctly, the metadata URI within the 1155 contract could be a string like "https://game.example/api/item/{id}.json" set in the constructor or after deployment for all token types created from this contract.

After the contract is deployed, say we mint a token with an id of 1. Does my JSON metadata need to be hosted at "https://game.example/api/item/0000000000000000000000000000000000000000000000000000000000000001.json"?

If I were to upload a JSON file to IPFS for hosting and received an IPFS hash like QmNeHgsWvoZHDjXJwH3uBev1M69GXGBHyHYZpjZxDkkGsr to locate it at https://ipfs.io/ipfs/QmNeHgsWvoZHDjXJwH3uBev1M69GXGBHyHYZpjZxDkkGsr, would my URI be https://ipfs.io/ipfs/{id} and the ID be QmNeHgsWvoZHDjXJwH3uBev1M69GXGBHyHYZpjZxDkkGsr?

This doesn’t seem right, so I thought maybe I need to map the token id to the IPFS hash or convert the IPFS hash into hex first before appending it to the URI from the contract. But the IPFS in hex extends past the 64 hex character length and mapping ids to IPFS hashes diminishes the gas savings from using this contract in the first place.

I’m not well-versed with server requests or database storage, so the relationship between the externally hosted metadata JSON identifier and the token ID confuse me a bit. It seems the token ID is subject to the metadata identifier I get from IPFS. But I feel like I’m missing an important piece in all this.

1 Like

Yes. Though please note it is the token ID in lowercase hexadecimal padded to 64 hex characters.

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.

For token ID 2 and uri https://game.example/api/item/{id}.json clients would replace {id} with 0000000000000000000000000000000000000000000000000000000000000002 to retrieve JSON at https://game.example/api/item/0000000000000000000000000000000000000000000000000000000000000002.json.

I have the following example:
https://abcoathup.github.io/SampleERC1155/api/token/0000000000000000000000000000000000000000000000000000000000000000.json


Unfortunately you can’t use this scheme with content addressing such as IPFS.

So you either need to implement a token URI mechanism (but would need the OpenZeppelin Contracts implementation to support, see: https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2154#issuecomment-657880427 otherwise you would need to create your own implementation) or you create a mechanism to redirect from the centralized URI to the decentralized IPFS hash address. I don’t know if IPNS would be an option for this?

1 Like

I see! Thank you very much. That clarifies a lot of my confusion. I didn’t realize the IPFS scheme was incompatible with the 1155 URI scheme.

I’ll look into IPNS and see if it would work for this. Otherwise, a centralized solution wouldn’t be a problem for my use at this stage.

1 Like

Hi @Jshanks21,

A single token URI using the {id} replacement is the most gas efficient but uses a centralized location based naming.

You could have your image locations in your metadata use IPFS hashes.

1 Like

Hi @abcoathup,

I love it. This was very helpful. I was trying to make 1155 ID substitution and IPFS hashes work together without being aware of this incompatibility. This was making any progress so much harder than necessary.

But now with a better understanding of how these can work together, I have a much clearer idea of what needs doing. I used the IPFS daemon to upload a directory of images I can use for tests, so I just need a centralized host for the rest of the metadata JSON.

1 Like

It is not completely true.
If the metadata is known ahead of time, you can create an ipfs folder with the filenames being the id as per the ERC1155 rules

if metadata is to be provided as part of a minting process, you can as @abcoathup mentioned implement the uri function yourself or emit the URI event. if you use uri you ll need to store the ipfs hash but can use folder to do so in batch (one hash per batch). This is how we do it for https://sandbox.game

2 Likes

That’s really clever @wighawag! Thank you for the tip. I’ll checkout the sandbox to explore this further and try implementing it myself.

2 Likes

Hi @wighawag,

Thank you :pray:

I didn’t realise that you could do [ipfs directory]/[padded token id in hex]

1 Like