Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TIP-27 IOTA NFT standards #65

Merged
merged 35 commits into from
Nov 28, 2022
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f5f17c0
feat: add IOTA NFT tip
coodos Mar 4, 2022
74b233a
chore: update IRC-2 TIP
coodos Mar 4, 2022
eb0f15c
Update tip-0027.md
AdamEunson Mar 4, 2022
5eb75b4
Merge pull request #1 from Kami-Labs/AdamCroply-update
coodos Mar 4, 2022
8fd3655
Update tip-0027.md
AdamEunson Mar 4, 2022
32b6734
Update tip-0027.md
AdamEunson Mar 4, 2022
066e1cb
chore: bump standard name and commit suggested changes
coodos Mar 9, 2022
ecac842
Updated Section headers
AdamEunson Mar 9, 2022
edc7924
Merge pull request #2 from Kami-Labs/AdamCroply-headers-update
AdamEunson Mar 9, 2022
a1d9bd5
Added Versions as TIPs comment
AdamEunson Mar 9, 2022
4d5ea15
docs: added description for royalty system
coodos Mar 29, 2022
5e1939e
Create irc27.schema.json
coodos Mar 29, 2022
02c16b9
chore: fix royalties part
coodos Mar 29, 2022
f12a5eb
Edited out the registry section and updates
AdamEunson Apr 2, 2022
ae29bcf
Edited tip30 to tip31
AdamEunson Apr 2, 2022
bf3120c
Updated tip link and royalties
AdamEunson Apr 5, 2022
096eaed
Merge pull request #3 from Kami-Labs/AdamCroply-patch-removeregistry
AdamEunson Apr 5, 2022
4083ba4
Merge branch 'iotaledger:main' into main
AdamEunson Apr 5, 2022
c658d1e
Updated example royalties
AdamEunson Apr 5, 2022
5dbf829
Updated example royalties
AdamEunson Apr 5, 2022
481a359
Create tip-0033.md
AdamEunson Apr 5, 2022
259ed3a
Merge pull request #4 from Kami-Labs/AdamCroply-tip33
AdamEunson Apr 5, 2022
ba48997
fix: irc27 schema
coodos Apr 6, 2022
b748957
Update tip-0027.md
coodos Apr 6, 2022
c696eaa
chore: remove tip 33
coodos Apr 6, 2022
35ac461
chore: update INFT to IOTA NFT
coodos Apr 28, 2022
4c8783e
chore: update policyId to collecitonId
coodos Apr 28, 2022
197c87f
Replace policy with collection
lzpap Apr 28, 2022
41d828d
use Open Sea standart for attributes
huhn511 Jun 17, 2022
91cc339
Merge pull request #5 from huhn511/main
lzpap Jun 19, 2022
07510ab
Clean up JSON schema
lzpap Jun 21, 2022
ac9687f
Desscribe NFT Collections, add practical examples
lzpap Jun 21, 2022
cfa52f5
Removed from immutable metadata
robertf26 Nov 23, 2022
3a96412
Updated header file
robertf26 Nov 23, 2022
61b4c5d
Merge pull request #7 from iotaledger/Kami-Labs/main
AdamEunson Nov 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions tips/TIP-0027/irc27.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
// name of the standard
"standard" : "IRC27",
// type can be "image", "audio", "video", "document", "3dAsset"
"type": "image",
coodos marked this conversation as resolved.
Show resolved Hide resolved
// Version of IRC27 standard being used
"version": "v1.0",
// Object containing the actual NFT metadata
"object": {
// define the required utxo identifier for the NFT,
// the utxo identitfier for the issuer and the file location
"nftId": "vt7rye8tgvr7e89w",
// Link to the file
"tokenURI": "https://mywebsite.com/myfile.png",
// define the optional keys for the base schema

// name of the asset
"tokenName": "My NFT #0001",
// unique policy ID identifier
"policyId": "7f9e0rwf7e90w",
// human readable name for the collection
"policyName": "My Collection of Art",
// Key Value pair collection of royalty addresses, where address is mapped to the percentage of payout to be sent to it
"royalties": {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should consider index here. You might want to define sequence as not all royalties might be paid every time. For example, what happens if the royalty is below dust?

"iota1...a": 0.5,
"iota1...b": 0.5
},
// Name of the artist
"issuerName": "My Artist Name",
// description of the asset
"description": "A little information about my NFT collection",
// define optional attributes for NFT metadata
"attributes": {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend to get inspired from ERC-721 / ERC-1155 metadata standard:

  • for keys definitely should be all lower case
  • you should consider support for localizations, rich formatting ( display value, css) - as recommended standard ofc

Copy link
Contributor

@AdamEunson AdamEunson Apr 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are heavily inspired by the ER721 standards, camelCase or snake_case are acceptable in word separation as per JSON schema standards. For example the fromBlock key as defined by the ERC-721 Standard which is used regularly in examples on the Ethereum Foundation docs. If you are referring to the value, as this is simply a text string this is not an issue.

I am sure Merul can comment a little further in regard to the localisations.

image

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure what you mean by localization here but if you mean glyphs from other languages than that shall be covered by unicode already

"Background": "Purple",
"Element": "Water",
"Attack": "150",
"Health": "500"
}
}
}
318 changes: 318 additions & 0 deletions tips/TIP-0027/tip-0027.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,318 @@
---
tip: 27
title: IOTA NFT Standard IRC27
description: Define NFT metadata standard, policy registry and creator royalties
author: Adam Eunson (@AdamCroply) <[email protected]>, Merul Dhiman (@coodos) <[email protected]>
discussions-to: https://github.com/iotaledger/tips/discussions/59
status: Draft
type: Standards
layer: IRC
created: 2022-03-04
---

lzpap marked this conversation as resolved.
Show resolved Hide resolved

# iNFT Standard - IRC27

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tbh I'm not a big fun of the iNFT prefix. It wasn't even obvious to me that it's for IOTA....It's confusing. Why don't just call it NFT Standard - IRC27 ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love it! 💯



## Abstract


**IRC27** is a series of standards to support interoperable and universal NFT systems throughout the IOTA eco-system, to provide a more robust and secure system for creators and buyers.


### Introduction

This document aims to support a universal system that can provide dApp developers and creators with an interoperable foundation of standards to support ease-of-adoption and a connected NFT eco-system. To bring value, security, trust, and interoperability.

Focusing on the primary use case for digital assets as NFTs, this defined standard supports key aspects in the creation, trade, and exchange of different assets with a focus on image, video, audio, and 3d asset file types.

To support an easy-to-implement system the iNFT Standard supports:

- **Policy ID** system should define NFT origins by issuerId and policyId for authenticity and verification within the iNFT space.
- **Policy Registry** system to allow open-source verifiable collection details.
- **Creator Royalty** System that can support universal creator royalties throughout the eco-system.
- **NFT Schema Standard** allowing for easily definable keys and values for ease-of-integration.
- **Version Modelling** to allow for easy updates as well as backwards compatibility.
- **Modular System Design** to provide developers freedom to utilise only required elements, as well as for future standards expansion beyond the existing standard model.

The standard provides the foundation for future expansion, supporting a modular design to provide an opportunity for selective integration, as well as further use case expansion through additional modules as time goes by.


## Motivation


### Why iNFT Standards?

Non-Standardised NFT systems have caused concerns and issues across a number of areas in other eco-systems. The lack of interoperable standards present numerous awkward and complicated experiences and in some eco-systems has resulted in countless verification and API issues that segment the NFT community.

Early safeguards are possible to put in place to support a more secure and interoperable eco-system that puts creators and buyer security at the forefront, providing developers and dApp makers the grounds to build a more connected and consistent eco-system.

With the IOTA Tokenisation Framework in its infancy, the early adoption of an iNFT Standard can support a safer, more secure environment for creators and dApp providers, to allow an easily interoperable experience through-out the IOTA eco-system.

In this document we will present the iNFT Standard - IRC27.


## Specification


### Policy ID

The IOTA Tokenisation Framework allows for a unique and robust solution when defining the identity of a collection. The integration of such a system can support verification of the origins of the creation of an NFT. For example, an artist creating a collection of works that will be labelled under a single collection. This allows for ease of verification for buyers and 3rd party application developers to provide an easily observable system of authenticity for users navigating the iNFT space.

The standard is defined utilising the creation mechanism for NFTs.

`issuerId` (referred to as [Issuer Block in TIP-18](https://github.com/iotaledger/tips/pull/38)) is already defined in the framework, allowing every NFT created from the same source to be easily defined.

Each NFT in the IOTA Tokenization Framework has its own unique address, that allows the ability to define a **collection UTXO** that can subsequently mint each unique NFT within that collection.

The `nftId` of a collection NFT is defined as the `policyId`.

the policyId will act as a unique identifier for the collection and would allow the `policyNft` to control the NFTs in a collection. This allows for unprecedented amounts of control where you can lock a collection for some time. It also allows for the ability to transfer the `policyNft` (parent NFT of all the NFTs minted within a collection) on transfer of which the new holder will be able to add NFTs to the collection, lock the collection etc.

A creator should define the UTXO of their collection NFT as the sole minting source of an entire collection that is the 'policyId'.

A creator may choose to burn the collection NFT on completion of minting or retain the collection NFT to add further NFTs to the collection over time.

The UTXO of the collection NFT acts as the `policyId` for the collection and can be used in dApps to define the verified origin of an NFT.

To call the defined `policyId` you should request the `policyId` UTXO of the collection NFT and resolve to the Policy Registry for human identifiable verification.

### Policy Registry

An open-source human identifiable registry of UTXO `policyId`s will be established to allow individuals the ability to support API integrations into dApps and websites that can support the connection of human identifiable names to `policyId`s.

A creator should register their `policyId` UTXO to a human identifiable value (`policyName`) as a defined unique and verified collection.

Reference to their `policyId` should be publicly visible on an official website or social media page.

A `policyName` must be a unique string.

Proposed as a part of this TIP is a policy registry, the policy registry will be similar to [CNFT Policy IDs Repo](https://github.com/Cardano-NFTs/policyIDs) where a collection creator can open a pull request with their socials, policy ID and collection name and a committe of human verifiers will approve or reject the colleciton. Apart from being used for NFTs the registry will also serve as a token registry with similar mechanics for human verification. Before a merge to the registry there must be atleat 5 approving reviews by human validators. And CI checks to ensure that the socials contain the policyID and the collection name isn't already taken, another cautionary check for too similar of a name to an existing collection can exist, for example a CI check that raises an warning for a collection named "TanglleLabs" when "TangleLabs" is already a part of the registry, the rationale behind this check is to mitigate fake collections for popping up which steal the IP from another colleciton and use a very similar name.

The Committe of human validators will be managed and compensated with a DAO infratructure where we can setup multisig requirements for any vote to conclude.

An API to support the integration of the policy registry into dApps can be called from the open-source repository.

When submitting a `policyId` to the registry the following keys should be defined.

- `issuerId` must be the original issuerId UTXO string
- `policyId` must be the unique UTXO string of the policyNFT
- `policyName` must be a unique human identifiable string
- `websiteUrl` must be an official website or social media page url that illustrates publicly the `policyId`

```json
{
"registration": {
"issuerId": "s345d6f7g8h9ji07gy8h99",
"policyId": "a3s45dr6ft7gy87hu98ji09",
lzpap marked this conversation as resolved.
Show resolved Hide resolved
"policyName": "My iNFT Collection",
"websiteUrl": "https://mywebsite.com/policyid"
}
}
```

### Creator Royalties
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to include royalties in an NFT standard? From our side, we would like to support royalties, but there are scenarios where it is necessary to have them not immutable, or it is not enough to represent them as a percentage of a sales price traded against something that is not a currency.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Royalties as a standard is included as an optional key. These are not a must but having a standardised royalty schema makes an ecosystem royalty system a lot more interoperable between dApps. It is further possible to expand the royalty options for edge cases through Smart Contracts also.


A system to support interoperable royalty payments across dApps. Allowing universal secondary market reward systems to be integrated through-out the eco-system. Integration of such systems is at the choosing of the dApp developer but is encouraged to support creator royalties.

royalty addresses can be defined inside the royalty addresses
```js
// the key inside the royalties object must be a valid iota1 address where royalties will be sent too
// the value must be a numeric decimal representative of the percentage required ie. 0.05=5%

{
...
"royalties": {
"iota1...a": 0.5
}
}
```

In the event there are further royalty, multiple royalty addresses could be used in the form of an object where the address and percentage are mapped in a key value format inside the `royalties` field.

```json
lzpap marked this conversation as resolved.
Show resolved Hide resolved
{
...
"royalties": {
"iota1...a": 0.25,
"iota1...b": 0.25,
"iota1...c": 0.25,
"iota1...d": 0.25
}
}
```

The total decimal sum of all `royaltyPercentage` must never exceed 1 and is recommended not to exceed 0.5


if `royalties` exists, it is iterated over the keys and then all the royalties are paid out till there are no keys left to iterate over.



### NFT Schema

For ease of development and interoperability between applications within the eco-system an extendable schema standard is defined to support ease of integration of NFTs for developers.

Each schema is defined by three main keys:

- `standard` – the standard model
- `schema` – the defined schema type
- `version` – the version of the standard


**Universal schema**
Each NFT schema should consist of a collection of universal keys to define key properties of the NFT

The standard defined is:

- `IRC27`


The schema is defined by one of the following:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this just feels way to limiting and I would be really careful introducing your own system for this.

Copy link
Contributor

@AdamEunson AdamEunson Apr 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The schema is expandable and versioning is implemented from the offset, introducing schema definitions is extremely advantageous for interoperability, forward and backwards compatibility across dApps in the ecosystem


- `image` – ie. jpeg, gif, png, bmp, webp
- `video` – ie. avi, mp4, webm
- `audio` – ie. wav, mp3
- `3dAsset` – ie. obj, fbx, glb
- `document` – ie. doc, xls, pdf, txt



The version is defined by the version number used preceded with the letter v, current version:

- `v1.0`


```json
// Define the standard, the type, and the version
{
"standard" : "IRC27",
"type": "image",
"version": "v1.0",
"object": {
```

Additional keys that must be included in every NFT schema:
- `nftId` – UTXO string of the NFT
- `tokenURI` – url pointing to the NFT file location


```json
{
"standard" : "IRC27",
"type": "image",
"version": "v1.0",
"object": {
// define the required utxo identifier for the NFT,
// the utxo identitfier for the issuer and the file location
"nftId": "vt7rye8tgvr7e89w",
lzpap marked this conversation as resolved.
Show resolved Hide resolved
"tokenURI": "https://mywebsite.com/myfile.png",
```


Optional, but recommended keys, that may be included in NFT schema include:
- `tokenName` – alphanumeric text string defining the human identifiable name for the NFT
- `policyId` – UTXO string of the policy NFT
- `policyName` – alphanumeric text string defining the human identifiable collection name
- `royalties` - Object containing key value pair where payment address mapped to the payout percentage
- `issuerName` – alphanumeric text string to define the human identifiable name of the creator
- `description` – alphanumeric text string to define a basic description of the NFT


```json
{
"standard" : "IRC27",
"type": "image",
"version": "v1.0",
"object": {
// define the required utxo identifier for the NFT,
// the utxo identitfier for the issuer and the file location
"nftId": "vt7rye8tgvr7e89w",
"tokenURI": "https://mywebsite.com/myfile.png",

// define the optional keys for the base schema
"tokenName": "My NFT #0001",
"policyId": "7f9e0rwf7e90w",
"policyName": "My Collection of Art",
"royalties": {
"iota1...a": 0.5,
"iota1...b": 0.5
},
"issuerName": "My Artist Name",
"description": "A little information about my NFT collection",
```


In addition to the required and recommended schema, the inclusion of `attributes` allows for versatile expansion for NFT metadata.


`attributes` are defined as a unique key and string that can be referenced in dApps to display metadata as required.


```json
{
"standard" : "IRC27",
"type": "image",
"version": "v1.0",
"object": {
// define the required utxo identifier for the NFT,
// the utxo identitfier for the issuer and the file location
"nftId": "vt7rye8tgvr7e89w",
"tokenURI": "https://mywebsite.com/myfile.png",

// define the optional keys for the base schema
"tokenName": "My NFT #0001",
"policyId": "7f9e0rwf7e90w",
"policyName": "My Collection of Art",
"royalties": {
"iota1...a": 0.5,
"iota1...b": 0.5
},
"issuerName": "My Artist Name",
"description": "A little information about my NFT collection",

// define optional attributes for NFT metadata
"attributes": {
"Background": "Purple",
"Element": "Water",
"Attack": "150",
"Health": "500"
}
}
}
```


## Rationale


### Interoperable Standards

For a unified iNFT eco-system the standards have been designed to support ease of integration and cross-compatibility of NFTs throughout the IOTA network. Observations of undefined standards in other eco-systems has illustrated the importance of such developments in the early stages of the technology. Simple defined keys such as `nftId`, instead of `assetId` or `tokenId`, or `tokenURI`, instead of `nftUrl` or `fileLocation`can support a much more interoperable experience for creators and dApp developers with everyone working from the same foundations.

Supporting creators is also a key element in driving adoption for the technology, royalty integrations vary substantially in other blockchain eco-systems which remains a challenge for both 3rd party applications and creators in sustaining a consistent and reliable eco-system across different applications.

This standard also supports expansion, backwards compatibility, and a universal guideline for the eco-system to develop with. Allowing an immediate interoperable environment that can support ease-of-adoption in the early stages of iNFTs, whilst continually supporting feature expansion and future development.


## Backwards Compatibility


### Versioning

Expanding use-cases in the NFT space will present multiple requirements for different standards and schemas to be developed and over time alterations and updates will be presented to support an evolving technology and future developments.

Version is introduced from the start to allow dApp developers and creators to maintain backwards compatibility with differing versions of the standard, which can be defined as a numeric value proceeded with the letter v. All future versions will be submitted as separate TIPs.

Current version `v1.0`

### Modular Structure Expansion

A modular structure to the standard has been created to support use case expansion, file type extension, standards catalogue. Allowing creators to utilise minimalist implementations as well as the more advanced expanded standards.



## Copyright


Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).