How to add public setURI on ERC1155?

Hi! I would like to have setURI public on my ERC1155, I’m using ERC1155PresetMinterPauserUpgradeable.

I added the following function, but not sure if something is missing, and what to do with the emit requiring an additional parameter for the ID.

     function setURI(string memory newuri) public {
         require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "SoapPunkCollectibles: must have admin role to change uri");

         emit URI(newuri, 0);

         _setURI(newuri);
     }

Doing something like this, adding the ID parameter to setURI just for the emit would be fine?

     function setURI(string memory newuri, uint256 id) public {
         require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "SoapPunkCollectibles: must have admin role to change uri");

         emit URI(newuri, id);

         _setURI(newuri);
     }

Thank you!

1 Like

Hi @Eibriel,

Welcome to the community :wave:

The OpenZeppelin Contracts ERC1155 implementation uses a single URI for the entire contract. See the following example: Create an ERC1155.

According to the EIP (see: https://eips.ethereum.org/EIPS/eip-1155#metadata):

  • Changes to the URI MUST emit the URI event if the change can be expressed with an event (i.e. it isn’t dynamic/programmatic).
  • An implementation MAY emit the URI event during a mint operation but it is NOT mandatory. An observer MAY fetch the metadata uri at mint time from the uri function if it was not emitted.
  • The uri function SHOULD be used to retrieve values if no event was emitted.
  • The uri function MUST return the same value as the latest event for an _id if it was emitted.

I interpret this as changing the uri for the contract would require emitting the event for each token ID. Though I recommend reading the EIP on this detail.

event URI(string _value, uint256 indexed _id);

Do you want to use a different uri per token ID?
Under what circumstances would you want to change the uri?

Thank you for the response. Then the second version, the one that requires a call to setURI for each ID seems appropriate for my project (maybe I could add an extra function allowing to set the uri for an array of IDs, emitting several events in one call).

I’m building a small game that will have an organic growth, instead of having a predefined clear roadmap.
Server migrations and web domain changes are a possibility in the future and I would like to avoid having to upgrade the contract.

1 Like

Hi @Eibriel,

My thoughts would be to keep it simple. Use a domain name that is future proof and update the DNS if you need to change servers/hosts/implementation.

That way you don’t need to change the URI and emit events when you do so.

1 Like