I'm looking to build an ERC1155 smart contract (I'm using OpenZeppelin) that will contain NFTs whose metadata will be hosted on IPFS. About 4,000 images for now, all unique (all amount of 1). An important requirement is the ability to add new NFTs regularly.
My issue is that if the IPFS uri
is being set in the constructor, I would need to update the uri every time I add files to that IPFS folder, which I don't want to do.
I've been looking for the best way to tackle this so here are the options I see so far:
- host all the files (metadata files + NFTs) in the cloud somewhere (but that's centralised and quite a weak solution)
constructor() public ERC1155("https://game.example/api/item/{id}.json") {
- host all the NFT files on IPFS but the metadata files in the cloud (still too centralised)
constructor() public ERC1155("https://game.example/api/item/{id}.json") {
but the metadata would look like
{
"description": "Friendly OpenSea Creature that enjoys long swims in the ocean.",
"external_url": "https://openseacreatures.io/3",
"image": "ipfs://bafybeic6o5aktpj53nhe3qninp2z7yl2aohxbrqiunc7kvmu57ulsoxjsj/dave.jpeg",
"name": "Dave Starbelly",
"attributes": [ ... ],
}
Put all the metadata files in the same IPFS folder and update the
uri
usingsetUri
every time I mint new items (not too sure people will be too happy if the URL to the metadata changes all the time). This seems to be the classic solution if the items set is fixed.
constructor() public ERC1155("ipfs:/bafybeic6o5aktpj53nhe3qninp2z7yl2aohxbrqiunc7kvmu57ulsoxjsj/items/{id}.json") {
Use IPNS (also quite centralised)
Use the solution described here: https://soenkeba.medium.com/truly-decentralized-nfts-by-erc-1155-b9be28db2aae where basically the NFTs and metadata files are pushed to IPFS, not necessarily in the same folder, and their CID is used to generate unique identifiers.
So for each CID, a unique token id is "calculated" and when theuri()
function is called, the token id is used to recalculate the CID and given to the client. Quite a cool solution and the only one that works, although it still feels a bit hacky.
constructor() public ERC1155("ipfs://f0{id}") {
I'm not convinced by any of these solutions, does anyone have any other ideas on how achieve what I want?