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.
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.
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?
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.
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
Hello @abcoathup ,
sorry to revive this topic but I was wondering how to deal with the initializer of ERC1155Upgradeable when you override the uri() function.
Let’s say you use IPFS for your URI and then can’t really have a common base URI because we are in situation 2 of what @wighawag describes.
Then OZ implementation of setUri() and string private _uri are not longer relevant because each batch of the minted tokens will have its specific IPFS URI.
What should be done then? set URI with a null value? Ovveride the initalizer of ERC1155Upgradeable and getting rid off this setter?
Hey @mpng yes I agree with that part.
But if one needs to mint tokens later, the folder won’t accept new json files unless we use IPNS. Yet in that case why bother lol.
So each batch will have a different base folder path and set_uri won’t work that well.
Alternative is to store just the IPFS:// tag but it’s not sparing much data.
I think I found a way to do this. But it is a bit hackish. The trick is to use a non-default hash for the CID that encodes to 65 characters in base16 and use the hash minus the leading "f" as token-id. Both sha3-224 and blake2b-208 should do the trick. Example with "Hello World" as content:
This is a really cool approach, actually our team is messing with this.
From this V1 using hash blake2b-208 = we get bafkzvzacdkm3bu3t266ivacqjowxqi3hvpqsyijxhsb23rv7nj7a
then from base16 we get f01559ae4021a99b0d373d7bc8a80504bad782367abe12c21373c83adc6bf6a7e
The question is:
From base16 and removing the "f" we get 01559ae4021a99b0d373d7bc8a80504bad782367abe12c21373c83adc6bf6a7e, then we need pass to hex from this? i mean how to handle this function in contract function mint(address account, uint256 cid).
CID is a uint256 need to hex(01559ae4021a99b0d373d7bc8a80504bad782367abe12c21373c83adc6bf6a7e) ?
NOTE: i am using python so i guess this type need to be casted to int(hex(01559ae4021a99b0d373d7bc8a80504bad782367abe12c21373c83adc6bf6a7e), 0).
Just put the "0xHEXNUMBER" to call the mint function. It is then changed to base10 integer. Open Sea, etc. will call the URI function with that number which will be changed back to a hex string with the uint2heststring ...
Hello guys, I'm having erc1155 smart contract which is using following base url: https://token-cdn-domain/{id}.json . When i try to get the uri for token with id 5 for example i receive this: https://token-cdn-domain/5.json but in ipfs they are stored with leading zero padded to 64 hex characters length and 5 looks like this 0000000000000000000000000000000000000000000000000000000000000005.json any idea how to provide the correct uri?