# How to add public setURI on ERC1155?

**URL:** <https://forum.openzeppelin.com/t/how-to-add-public-seturi-on-erc1155/4675>\
**Category:** Contracts\
**Created:** [November 19, 2020, 2:19pm UTC](https://forum.openzeppelin.com/t/how-to-add-public-seturi-on-erc1155/4675 "2020-11-19T14:19:58Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Eibriel](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/eibriel/32/3597_2.png) [@Eibriel](https://forum.openzeppelin.com/u/Eibriel)\
**Post date:** [November 19, 2020, 2:19pm UTC](https://forum.openzeppelin.com/t/how-to-add-public-seturi-on-erc1155/4675/1 "2020-11-19T14:19:58Z")

</div>

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.

```auto
     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?

```auto
     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!

---

<div class="post-metadata">

**Author:** ![abcoathup](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/abcoathup/32/415_2.png) [@abcoathup](https://forum.openzeppelin.com/u/abcoathup)\
**Post date:** [November 20, 2020, 8:20am UTC](https://forum.openzeppelin.com/t/how-to-add-public-seturi-on-erc1155/4675/2 "2020-11-20T08:20:21Z")

</div>

Hi @Eibriel,

Welcome to the community 👋

The OpenZeppelin Contracts ERC1155 implementation uses a single `URI` for the entire contract. See the following example: [Create an ERC1155](https://forum.openzeppelin.com/t/create-an-erc1155/4433).

According to the EIP (see: [https://eips.ethereum.org/EIPS/eip-1155#metadata](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.

```auto
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`?

---

<div class="post-metadata">

**Author:** ![Eibriel](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/eibriel/32/3597_2.png) [@Eibriel](https://forum.openzeppelin.com/u/Eibriel)\
**Post date:** [November 20, 2020, 1:58pm UTC](https://forum.openzeppelin.com/t/how-to-add-public-seturi-on-erc1155/4675/3 "2020-11-20T13:58:20Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![abcoathup](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/abcoathup/32/415_2.png) [@abcoathup](https://forum.openzeppelin.com/u/abcoathup)\
**Post date:** [November 20, 2020, 7:55pm UTC](https://forum.openzeppelin.com/t/how-to-add-public-seturi-on-erc1155/4675/4 "2020-11-20T19:55:57Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![dagr](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/dagr/32/8188_2.png) [@dagr](https://forum.openzeppelin.com/u/dagr)\
**Post date:** [August 12, 2021, 5:17pm UTC](https://forum.openzeppelin.com/t/how-to-add-public-seturi-on-erc1155/4675/5 "2021-08-12T17:17:59Z")

</div>

What would you suggest when using IPFS? If I have a directory that contains all token metadata and a new token id is added later on, the hash of the directory would change. I could publish an IPNS entry and set it as the URI once, but the IPNS entry is created using a centralized private key. You could also use a mutable file storage with IPFS, but I feel like this is even more centralized.

---

<div class="post-metadata">

**Author:** ![skyone.nanshan](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/skyone.nanshan/32/12224_2.png) [@skyone.nanshan](https://forum.openzeppelin.com/u/skyone.nanshan)\
**Post date:** [January 13, 2022, 7:47am UTC](https://forum.openzeppelin.com/t/how-to-add-public-seturi-on-erc1155/4675/6 "2022-01-13T07:47:05Z")

</div>

Yep, I want to ask Can I set a URL for a specific ID?  
For example , this? make sense?

```auto
     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,id);
     }

```

---

<div class="post-metadata">

**Author:** ![Amxx](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/amxx/32/668_2.png) [@Amxx](https://forum.openzeppelin.com/u/Amxx)\
**Post date:** [January 13, 2022, 9:06am UTC](https://forum.openzeppelin.com/t/how-to-add-public-seturi-on-erc1155/4675/7 "2022-01-13T09:06:42Z")

</div>

The ERC1155 standard is designed with only one URI for all token ids.  
See [the "metadata" section](https://eips.ethereum.org/EIPS/eip-1155#metadata) of reference document

---

<div class="post-metadata">

**Author:** ![skyone.nanshan](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/skyone.nanshan/32/12224_2.png) [@skyone.nanshan](https://forum.openzeppelin.com/u/skyone.nanshan)\
**Post date:** [January 14, 2022, 8:35am UTC](https://forum.openzeppelin.com/t/how-to-add-public-seturi-on-erc1155/4675/8 "2022-01-14T08:35:16Z")

</div>

So,,, there is no way to set single ID for now , right?
