Alert Source Discuss
📢 Last Call Standards Track: ERC

ERC-4955: Vendor Metadata Extension for NFTs

Add a new field to NFT metadata to store vendor specific data

Authors Ignacio Mazzara (@nachomazzara)
Created 2022-03-29
Last Call Deadline 2023-02-01
Requires EIP-721, EIP-1155

Abstract

This EIP standardizes a schema for NFTs metadata to add new field namespaces to the JSON schema for EIP-721 and EIP-1155 NFTs.

Motivation

A standardized NFT metadata schema allows wallets, marketplaces, metaverses, and sililar applications to interoperate with any NFT. Applications such as NFT marketplaces and metaverses could usefully leverage NFTs by rendering them using custom 3D representations or any other new attributes.

Some projects like Decentraland, TheSandbox, Cryptoavatars, etc. need their own 3D model in order to represent an NFT. These models are not cross-compatible because of distinct aesthetics and data formats.

Specification

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

Schema

(subject to “caveats” below)

A new property called namespaces is introduced. This property expects one object per project as shown in the example below.

{
    "title": "Asset Metadata",
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
            "description": "Identifies the asset to which this NFT represents"
        },
        "description": {
            "type": "string",
            "description": "Describes the asset to which this NFT represents"
        },
        "image": {
            "type": "string",
            "description": "A URI pointing to a resource with mime type image/* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive."
        },
        "namespaces": {
          "type": "object",
          "description": "Projects that needs specific properties to use the NFT"
        }
    }
}

Example

{
  "name": "My NFT",
  "description": "NFT description",
  "image": "ipfs://QmZfmRZHuawJDtDVMaEaPWfgWFV9iXoS9SzLvwX76wm6pa",
  "namespaces": {
    "myAwesomeCompany": {
      "prop1": "value1",
      "prop2": "value2",
    },
    "myAwesomeCompany2": {
      "prop3": "value3",
      "prop4": "value4",
    },
  }
}

// Or by simply using a `URI` to reduce the size of the JSON response.

{
  "name": "My NFT",
  "description": "NFT description",
  "image": "ipfs://QmZfmRZHuawJDtDVMaEaPWfgWFV9iXoS9SzLvwX76wm6pa",
  "namespaces": {
    "myAwesomeCompany": "URI",
    "myAwesomeCompany2": "URI",
  }
}

Rationale

There are many projects which need custom properties in order to display a current NFT. Each project may have its own way to render the NFTs and therefore they need different values. An example of this is the metaverses like Decentraland or TheSandbox where they need different 3d models to render the NFT based on the visual/engine of each. NFTs projects like Cryptopunks, Bored Apes, etc. can create the 3d models needed for each project and therefore be supported out of the box.

The main differences between the projects that are rendering 3d NFTs (models) are:

Armatures

Every metaverse uses its own armature. There is a standard for humanoids but it is not being used for every metaverse and not all the metaverses use humanoids. For example, Decentraland has a different aesthetic than Cryptovoxels and TheSandbox. It means that every metaverse will need a different model and they may have the same extension (GLB, GLTF)

Metadata (Representations Files)

For example, every metaverse uses its own metadata representation files to make it work inside the engine depending on its game needs.

This is how a wearable looks like in Decentraland in terms of the config file:

"data": {
  "replaces": [],
  "hides": [],
  "tags": [],
  "category": "upper_body",
  "representations": [
    {
      "bodyShapes": [
        "urn:decentraland:off-chain:base-avatars:BaseMale"
      ],
      "mainFile": "male/Look6_Tshirt_A.glb",
      "contents": [
        {
          "key": "male/Look6_Tshirt_A.glb",
          "url": "https://peer-ec2.decentraland.org/content/contents/QmX3yMhmx4AvGmyF3CM5ycSQB4F99zXh9rL5GvdxTTcoCR"
        }
      ],
      "overrideHides": [],
      "overrideReplaces": []
    },
    {
      "bodyShapes": [
        "urn:decentraland:off-chain:base-avatars:BaseFemale"
      ],
      "mainFile": "female/Look6_Tshirt_B (1).glb",
      "contents": [
        {
          "key": "female/Look6_Tshirt_B (1).glb",
          "url": "https://peer-ec2.decentraland.org/content/contents/QmcgddP4L8CEKfpJ4cSZhswKownnYnpwEP4eYgTxmFdav8"
        }
      ],
      "overrideHides": [],
      "overrideReplaces": []
    }
  ]
},
"image": "https://peer-ec2.decentraland.org/content/contents/QmPnzQZWAMP4Grnq6phVteLzHeNxdmbRhKuFKqhHyVMqrK",
"thumbnail": "https://peer-ec2.decentraland.org/content/contents/QmcnBFjhyFShGo9gWk2ETbMRDudiX7yjn282djYCAjoMuL",
"metrics": {
  "triangles": 3400,
  "materials": 2,
  "textures": 2,
  "meshes": 2,
  "bodies": 2,
  "entities": 1
}

replaces, overrides, hides, and different body shapes representation for the same asset are needed for Decentraland in order to render the 3D asset correctly.


Using namespaces instead of objects like the ones below make it easy for the specific vendor/third-parties to access and index the required models. Moreover, styles do not exist because there are no standards around for how an asset will be rendered. As I mentioned above, each metaverse for example uses its own armature and aesthetic. There is no Decentraland-style or TheSandbox-style that other metaverses use. Each of them is unique and specific for the sake of the platform’s reason of being. Projects like Cryptoavatars are trying to push different standards but without luck for the same reasons related to the uniquity of the armature/animations/metadata.

{
    "id": "model",
    "type": "model/gltf+json",
    "style": "Decentraland",
    "uri": "..."
},

// Or

{
    "id": "model",
    "type": "model/gltf+json",
    "style": "humanoide",
    "uri": "..."
},

With namespaces each vendor will know how to render an asset by doing:

fetch(metadata.namespaces["PROJECT_NAME"].uri).then(res => render(res))

The idea behind extending the EIP-721 metadata schema is to have backward compatibility as much as possible with existing projects. Chances are that the asset’s smart contracts are not upgradeable and therefore if a project wants to be compatible with this EIP, it will need to redeploy and migrate the current contracts. This is very time- and money-consuming. Creating a new token standard that stores the data needed on-chain: 3D models and config files are not the right paths. There are protocols already used for the EIP-721 metadata standard like IPFS (the token URI is an IPFS hash). The idea is to leverage this and require as few changes as possible. Moreover, the current metadata standard uses a 2D representation field: image. It seems reasonable to have all the representations of an asset in the same place.

Backwards Compatibility

Existing projects that can’t modify the metadata response (schema), may be able to create a new smart contract that based on the tokenId returns the updated metadata schema. Of course, the projects may need to accept these linked smart contracts as valid in order to fetch the metadata by the tokenURI function.

Security Considerations

The same security considerations as with EIP-721 apply related to using http gateways or IPFS for the tokenURI method.

Copyright and related rights waived via CC0.

Citation

Please cite this document as:

Ignacio Mazzara (@nachomazzara), "EIP-4955: Vendor Metadata Extension for NFTs [DRAFT]," Ethereum Improvement Proposals, no. 4955, March 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-4955.