Why doesn't OpenZeppelin ERC721 contain setTokenURI?

Doesn’t make sense to me at all.

We all agree that setTokenURI 's costs is just storing bytes32 hash into a storage for which each user pays only for his/her part in the storage. So I don’t see much costs here.

If we need to append something in tokenURI, it still is view function right because it just appends it and doesn’t modify storage. So, no costs here at all.

What’s the real deal ?

1 Like

Hi @novaknole,

I recommend trying it out on a public testnet and calculating the cost difference between storing an IPFS hash per token ID and not storing when minting.

@abcoathup @hantuzun @frangio

Hey ,

I compared the costs for both cases : 1. without using setTokenURI and using predefined metadata vs 2. using setTokenURI.

The very vague (might be wrong with 5,000 - 10,000 Gas, not that important) I found is this:

  1. without setTokenURI, and just using predefined metadata solution costs 154920 for creating new token.
  2. with setTokenURI, it costs 221474

The difference is 67,000 approximatelly.

My question now…

Question 1 : In my opinion, using predefined metadata solution, which means, we first upload a directory which contains 1, 2, 3 ,.e.t.c named files(these are metadatas) seems a very bad solution.

  • Reason 1: It’s bad because we can’t allow users to come in the future and mint new tokens, because their metadata is not in the ipfs. One can say that we can have the functionality of updating baseURI , but what guarantee do we have that whoever can update won’t set it to malicious.com. We can double check for sure, but he wil still be able to update it. which seems to be very wrong. Even using IPNS seems a very bad hack, because, now vice versa situation happens: we update the directory with new metadatas which means we can also upload totally different metadatas(even change the old ones) and now, contract’s tokenURI will return wrong metadatas. How is this for even a second good solution ? I think the only way this could be a good solution is if we don’t use IPNS and also we don’t have the updateBASEURI functionality in the contract. This means that with whatever baseURI we deploy contract, we already have the already predefined metadatas on that baseURI and that’s it.

I’d really much appreciate your final input on this and if there’s something you don’t agree with me about this. I just wanna 100% make sure that i understand every hidden detail…

Question 2

As we found the difference in gas costs which is 67,000, do you think this difference is really noticeable and worth changing the setTokenURI solution to predefined metadata solution ? In my opinion, it’s not. So, I’d also love to hear your opinions.

I really appreciate your follow ups on this question.

1 Like

Hi @novaknole,

It really depends on your use case and the value of the NFTs. If the cost of minting is significant compared with the value of each token then you should be optimizing for gas costs.

Question 1, It sounds like your use case requires metadata to be created at time of minting and cannot be determined at the time of deployment, so you can either use centralized (lower minting cost) or decentralized (higher minting cost).

Question 2, 67,000 gas, at a gas price of 150 gwei is ~0.01 ETH, ~$21 at current prices. It depends on the value of the NFT and your use case.

Would you suggest to deploy one ERC721 for every unique asset of one service or to deploy one contract and users mint against it for each unique asset? For example an art registry where users upload a PNG of their unique art and expect to have a NFT representing that artwork.

Sorry if this was mentioned, asked, or answered before. It has impact on my design under progress and want to make sure before making such a change.

It will be prohibitively expensive to deploy one ERC721 contract for every user, let alone for every piece of artwork.

This is one of the cases where using ERC721URIStorage may make more sense.

If you want to deploy a separate ERC721 contract per user for other reasons (e.g. so that each user has their own NFT contract address) it would be cheaper to do using Clones, and in this case you would also need something like ERC721URIStorage.

The way to do this without using ERC721URIStorage would be to have an IPNS address that you update with each new minted piece. I’m not sure how well this would scale.

1 Like