Structural Improvements to ERC-1155 Metadata

NFT metadata could easily be simpler to code, faster to load, less bug-prone, and easier to understand than with current specs. See example at the bottom. To comment, use GitHub Discussions.

ERC-1155 metadata has bits that are clumsy and inefficient.

  1. The decimals feature mixes presentation with data. ("The number of decimal places that the token amount should display - e.g. 18, means to divide the token amount by 1000000000000000000 to get its user representation"). This feature is a product design choice for front end developers. It's irrelevant to a contract and it relies on ultra-pricey on-chain real estate.

  2. The {id} interpolation feature violates the HATEOAS constraint of REST. The feature is defined as: "If the string {id} exists in any JSON value, it MUST be replaced with the actual token ID". Well designed APIs should use literal URIs generated by the servers that are generating the metadata JSON. (I bet the interpolation feature is not necessary.)

  3. The {id} interpolation feature reinvents the concept of server-side programming, like PHP. I doubt this was intentional. I think the data format was intended to be used within Solidity, and accidentally got incorporated into a new context.

  4. Localization support mixes non-localized data with localized data, has a weird extra field for a default locale, and requires a URI to be fetched for each locale. If locale-specific strings were inline, consuming these files would be faster and the code would be a simpler.

  5. Locales are defined by reference to, but this is not a list of locales, it is an organization that shepherds lists of locales.

  6. The example JSON in the published EIP has an obvious bug:

    "image": "https:\/\/\/your-bucket\/images\/{id}.png",

This is simply wrong. A ‘/’ character does not need to be escaped in JSON, and the resulting escaped strings are not legal URIs. The example value should be:

    "image": "{id}.png",
  1. There is no way to map from one of these external JSON documents to the token that it is annotating, so there is no way to know if they can be deleted except by searching every NFT that ever existed.

A future spec would:

  1. Nuke the decimals feature
  2. Nuke {id} interpolation
  3. Put localized data inline
  4. Separate localized and non-localized fields
  5. Eliminate the default locale - this belongs in the user-agent
  6. Fix the example data
  7. Require a locale name to be a subtag in

For the purposes of robustness, I'd also like to have:

  1. Ability to map from the metadata back to the token, so NFTs don't get hooked up to the wrong metadata. This requires a token ID in the JSON.

New and refactored example:

  "imageLink": "",
  "locales": {
    "en": {
      "name": "Advertising Space",
      "description": "Each token represents a unique ad space in the city."
    "es": {
      "name": "Espacio Publicitario",
      "description": "Cada token representa un espacio publicitario único en la ciudad."
    "fr ": {
      "name": "Espace Publicitaire",
      "description": "Chaque jeton représente un espace publicitaire unique dans la ville."
  "tokenID": "0x12f28e2106ce8fd8464885b80ea865e"

For comparison, see

Future topics:

  • I haven't figured out the properties object, which is a can of worms.
  • If the URI in an ERC1155 ERC1155Metadata_URI is IPFS, it is useless unless it is mutable, and it is only mutable if it is IPNS. Therefore, IPFS URIs with a non-IPNS path should be strongly discouraged.
  • Review for best practices
  • Much of the above is not related to metadata. It is about any sort of mutable data with a 1:1 relationship to an on-chain entity.

You'll only receive email when they publish something new.

More from Lucas Gonze
All posts