ETM_MULTIASSET_v1.0.0
ETM Multi-Asset Extension
| Authors | Zack Pantely, Kavan Sikand |
| Contributors | Justin Bloomer, David Ceballos, Thomas Lisankie, Madrone, Spencer Obstinik, Eric Struhl, Tasheme Thomas, Florian Uhde, Andy Watson |
| Discussions To | https://github.com/ETM-Standard/etm-standard.github.io/discussions/3 |
| Type | ETM Extension |
| Extension Name | ETM_MULTIASSET_v1.0.0 |
| Created | 2022-06-06 |
Table of contents
- Summary
- Abstract
- Motivation
- Specification
- Metadata Examples
- Backwards Compatibility
- Security Considerations
- Copyright
Summary
With the expansion in use cases for Non-Fungible Tokens (NFTs), there has arisen a need to standardize the organization of assets represented by an NFT. Here, we define a standard by which an NFT can represent multiple assets of varying media types.
Abstract
This standard is an extension of ETM and provides a decentralized approach to representing multiple digital assets with a single NFT in a scalable and maintainable way.
The goal is to provide a streamlined approach to the following:
- Associating multiple assets with an NFT such that custom or centralized tooling is not required
- Supporting NFTs with heterogeneous media types (e.g. 3D models, animations, etc.)
- Providing a clear definition of the file type for files associated with an NFT
Motivation
As the use cases for NFTs have expanded, the need for an NFT to represent multiple files has grown and been addressed in several ways. However, the inconsistency in these varied approaches has rendered assets beyond images and videos unable to be ingested by NFT consumers in a streamlined way. This has forced consumers to create custom centralized tooling to access specific assets - a path that is not scalable or maintainable in the long-term.
Here's an example of the current method by which a user might bring an NFT representing multiple assets, including a 3D model, into a game:
Existing Ingestion Path Example
- User purchases an NFT
- User navigates to NFT creator's website
- User downloads the associated assets for the NFT
- User interacts with game-specific tooling to upload these assets to the game
This procedure necessitates a lot of manual interaction by the user, because there is no standard way by which an automated system can access all of the assets associated with this NFT. This approach also requires trust that the user actually owns the NFT that they uploaded.
For NFTs which adhere to our proposed metadata standard, the path to ingesting assets into a game world looks like:
Proposed Ingestion Path Example
- User purchases an NFT
- Game verifies that the user owns the NFT
- Game parses NFT's metadata to ingest appropriate assets into the game world
The clear benefit of this approach is that with no custom project-level support from the game developer and no manual action from the NFT owner, the user is able to use their assets in-game.
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.
Top-Level Metadata:
This specification adds the assets key to the top level of ETM metadata JSON.
{
"metadata_standard": "ETM_v1.0.0",
"extensions": [ "ETM_MULTIASSET_v1.0.0" ],
"assets": []
}
In the above metadata, the assets array is left empty in order to show the minimum valid implementation of this extension. For a non-trivial example, refer to the Metadata Examples section.
Extended Top-Level Data Types:
The below table defines the fields that are added to the top-level metadata JSON.
| Field Name | Data Type | Inclusion |
|---|---|---|
| assets | Asset[] | REQUIRED |
The assets key provides an array of Asset data types, defined below.
Asset Data Type:
The Asset data type is a JSON object which defines all media representing a specific asset. The fields for this data type are defined in the table below.
| Field Name | Data Type | Inclusion |
|---|---|---|
| name | string | OPTIONAL |
| description | string | OPTIONAL |
| media_type | string (MediaType enum) | REQUIRED |
| asset_type | string | OPTIONAL |
| files | File[] | REQUIRED |
The name and description fields MAY be omitted (likely if there is only one Asset in the array), in which case the metadata interpreter might choose to fall back to the metadata's top-level name and description fields.
The media_type key provides a MediaType enum which is used to convey how the asset should be interpreted. Example values include "image", "video", or "model". Valid MediaType values are detailed in the Standard MediaType Definitions section.
The asset_type key allows creators to more-specifically define the usage of the asset. Example values include "preview", "avatar", "pistol", or "shirt". This extension does not specify a set of valid entries for the asset_type and instead leaves that definition to a subsequent extension. If omitted, the asset can only be interpreted as a generic asset of the defined MediaType.
The file key provides an array of File data types, defined below.
File Data Type:
The File data type is a JSON object which represents a single file. The fields for this data type are defined in the table below.
| Field Name | Data Type | Inclusion |
|---|---|---|
| name | string | OPTIONAL |
| description | string | OPTIONAL |
| url | string (URL) | REQUIRED |
| file_type | string (MIME type) | REQUIRED |
The name and description fields MAY be omitted (likely if there is only one File in the array), in which case the metadata interpreter might choose to fall back to the name and description fields of the Asset (or, if that is omitted, the metadata's top-level name and description fields).
The url key provides a URL to the file to be downloaded. This URL is NOT REQUIRED to contain a file extension since that is provided by the file_type value.
The file_type key provides media type and a file extension in a MIME type format. This is helpful during interpretation because some URLs, such as many InterPlanetary File System (IPFS) URLs, do not contain a file extension. For convenience in interpreting this standard, we note here that the nomenclature of MIME types is [type]/[subtype] where the type is a media type and the subtype is a file extension.
Assets and Files:
It should be understood that an Asset represents some thing and a File gives a representation of that thing (of which there may be one or more).
Each Asset REQUIRES that at least one File in the files array is of a file_type with a MIME type that matches the asset's MediaType (e.g. a "model" MediaType requires at least one file with a file_type of "model/[any subtype]").
Multiple files with the same MIME type as the Asset's MediaType MAY be included if they have different MIME subtypes and represent the same asset (in the example of a model, a "model/fbx" and a "model/obj" could both be included in the same files array if they represent the same asset with different file types, but two "model/fbx" files are not allowed in the same files array because this would cause ambiguity; in this case, a different Asset should be used to host each File). This restriction allows the metadata interpreter to assume that any File with the same MIME type as the Asset's MediaType can equally be used to represent the asset and offers the choice of which file to use.
For files with MIME types that are not the same as the Asset's MediaType, there are no restrictions on the number that can be included. These can be considered previews or supporting materials of the asset that refers to them. In the example of a model, such supporting materials may be animations that are relevant to that model asset.
This standard makes no restrictions to the MIME subtypes that can be used. The compatibility and handling of file types is dependent on the services that ingest NFT assets.
Standard MediaType Definitions
This standard defines a set of standardized MediaType values in order to provide a known interpretation for common types of assets. The MediaType MUST be a value from this list. These definitions and their requirements are defined below.
-
model: The "model"
MediaTypedescribes a single model, any previews of that model, and any supporting files (such as animations). ThisMediaTypeREQUIRES at least one file in thefilesarray with afile_typethat has a a model MIME type (e.g. model/fbx). -
image: The "image"
MediaTypedescribes an image asset. ThisMediaTypeREQUIRES at least one file in thefilesarray with afile_typethat has an image MIME type (e.g. image/png). In some cases, an image will be provided by the top-levelimagekey, so the use-case for thisMediaTypemay be to provide a higher-resolution version of the asset provided by the top-levelimagekey. -
video: The "video"
MediaTypedescribes a video asset. ThisMediaTypeREQUIRES at least one file in thefilesarray with afile_typethat has a video MIME type (e.g. video/mp4). In some cases, a video will be provided by the top-levelimagekey, so the use-case for thisMediaTypemay be to provide a higher-resolution version of the asset provided by the top-levelimagekey. -
animation: The "animation"
MediaTypedescribes a single animation and any previews of that animation. ThisMediaTypeREQUIRES at least one file in thefilesarray with afile_typethat has an animation MIME type (e.g. animation/fbx). -
audio: The "audio"
MediaTypedescribes a single audio track and any previews of that track. ThisMediaTypeREQUIRES at least one file in thefilesarray with afile_typethat has an audio MIME type (e.g. audio/wav). -
text: The "text"
MediaTypedescribes a single body of text and any previews of that text. ThisMediaTypeREQUIRES at least one file in thefilesarray with afile_typethat has a text MIME type (e.g. text/txt). -
font: The "font"
MediaTypedescribes a single font and any previews of that font. ThisMediaTypeREQUIRES at least one file in thefilesarray with afile_typethat has a font MIME type (e.g. font/ttf). -
application: The "application"
MediaTypedescribes a single application and any previews of that application. ThisMediaTypeREQUIRES at least one file in thefilesarray with afile_typethat has an application MIME type (e.g. application/exe).
Metadata Examples
Multiple Assets
The following is an example of this extension including data for an NFT that consists of two assets: a 3D model of glasses and a 3D model of a hat. Each asset includes a single 3D model file.
{
"name": "Clever Disguise",
"description": "Glasses and a hat.",
"image": "https://coolnfts.com/clever-disguse-preview.png",
"metadata_standard": "ETM_v1.0.0",
"extensions": [ "ETM_MULTIASSET_v1.0.0" ],
"assets": [
{
"name": "Glasses",
"description": "An unassuming pair of glasses.",
"media_type": "model",
"files": [
{
"url": "https://ipfs.io/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",
"file_type": "model/fbx"
}
]
},
{
"name": "Hat",
"description": "A suspicious-looking hat.",
"media_type": "model",
"files": [
{
"url": "https://ipfs.io/idzbf55yqtglco3fbaqlyufe3fn62y7hu67uh7mdu7pfs5tzrydgiebyfab",
"file_type": "model/fbx"
}
]
}
]
}
Multiple Files
The following is an example of this extension including data for an NFT that consists of one asset with three files: an image, a video, and a 3D model of a shirt. Here, the top-level image field is omitted.
{
"name": "Snazzy Shirt",
"description": "A shirt to wear to the jazz club.",
"metadata_standard": "ETM_v1.0.0",
"extensions": [ "ETM_MULTIASSET_v1.0.0" ],
"assets": [
{
"media_type": "model",
"files": [
{
"name": "Shirt Image",
"description": "A high-res render of a snazzy shirt.",
"url": "https://ipfs.io/idzbf55yqtglco3fbaqlyufe3fn62y7hu67uh7mdu7pfs5tzrydgiebyfab",
"file_type": "image/png"
},
{
"name": "Shirt Video",
"description": "A rendered video of a snazzy shirt.",
"url": "https://ipfs.io/beyzbafgdiryt5sfp7udm7hu76uh7y26nf3eblfyaquf3otqlgcy55fbdzi",
"file_type": "video/mp4"
},
{
"name": "Shirt Model",
"description": "A rigged model of a snazzy shirt.",
"url": "https://ipfs.io/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",
"file_type": "model/fbx"
}
]
}
]
}
This also serves as an example of where the media_type field may be necessary to interpret the asset. Because the asset consists of an image, a video, and a model, some assumptions about the intention of the asset would otherwise have to be made. Since the media_type is defined as a model, the included image and video can be considered previews or ignored at the discretion of the metadata interpreter.
Complete Example: Multiple Files Per Asset
The following is an example of the metadata for an NFT representing an entire outfit. Each asset in the outfit is a 3D model, but also includes a supplementary image file. In addition, the top-level image field is used here to provide a preview of the entire outfit.
{
"name": "Snazzy Outfit",
"description": "A whole outfit to wear to the jazz club!",
"image": "https://coolnfts.com/entire-outfit-preview.png",
"metadata_standard": "ETM_v1.0.0",
"extensions": [ "ETM_MULTIASSET_v1.0.0" ],
"assets": [
{
"media_type": "model",
"files": [
{
"name": "Shirt Image",
"description": "A high-res render of a snazzy shirt.",
"url": "https://ipfs.io/idzbf55yqtglco3fbaqlyufe3fn62y7hu67uh7mdu7pfs5tzrydgiebyfab",
"file_type": "image/png"
},
{
"name": "Shirt Model",
"description": "A rigged model of a snazzy shirt.",
"url": "https://ipfs.io/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",
"file_type": "model/fbx"
}
]
},
{
"media_type": "model",
"files": [
{
"name": "Pants Image",
"description": "A high-res render of sweet pants.",
"url": "https://ipfs.io/idzbf55yqtglco3fbaqlyufe3fn62y7hu67uh7mdu7pfs5tzrydgiebyfab",
"file_type": "image/png"
},
{
"name": "Pants Model",
"description": "A rigged model of sweet pants.",
"url": "https://ipfs.io/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",
"file_type": "model/fbx"
}
]
}
]
}
Backwards Compatibility
This extension to the metadata standard is backwards compatible with existing metadata suggestions proposed in ERC-721 and ERC-1155, as well as ETM.
Copyright
Copyright and related rights waived via CC0.