CHIP Number | 0005 |
---|---|
Title | NFT1 Standard |
Description | A standard for implementing non-fungible tokens (NFTs) on Chia's blockchain |
Author | Dan Perry |
Editor | Will Riches |
Comments-URI | Chia-Network#19 |
Status | Final |
Category | Standards Track |
Sub-Category | Chialisp |
Created | 2022-06-05 |
Requires | Singleton Standard, Offer Standard |
Replaces | None |
Superseded-By | None |
Non-Fungible Tokens (NFTs) are unique assets that can be bought, sold and exchanged online. NFT1 is the first standard to enable NFTs on Chia's blockchain. This standard prioritizes independence from marketplaces, strong provenance and digital permanence. It optionally incorporates Chia Decentralized Identifiers (DIDs), as well as cryptographically verifiable royalties, built into the tokens themselves.
Throughout this document, we'll use the following terms:
- Minter -- The person or entity who creates an NFT. This could be the original artist or someone working on their behalf. Once an NFT has been created, its Minter never changes
- Owner -- The person or entity who currently controls an NFT. This could be either the Minter or someone who has purchased the NFT. An NFT's Owner changes each time it is transferred
- DIDs – Decentralized IDentifiers. On Chia’s blockchain, these enable on-chain proof of identity
- Collection - The name given to a group of NFTs that are intentionally organized together. For example,
Fruits of the World
- Series - Unique NFTs that belong together in a Collection. For example if
Fruits of the World
has images of ten types of fruit, the most common way to name them isFruits of the World #1
(this might be an image of an apple),Fruits of the World #2
(this might be an image of a banana), etc. A Series may contain a pre-set total number of NFTs; it also may choose not to specify the total number in the Series, and instead add NFTs to the Series over time - Edition - Identical copies of the same NFT in a Collection. For example, if there are ten copies of the same image of an apple, these could be labeled
Apple #1 of 10
,Apple #2 of 10
, etc - Must, required, shall – These words indicate an absolute requirement of the specification
- Must not, shall not – These phrases indicate an absolute prohibition of the specification
- Should, recommended – These words indicate something that is not a requirement of the specification, but the implications of not following it should be carefully considered beforehand
- Should not, not recommended – These phrases indicate something that is not a prohibition of the specification, but the implications of following it should be carefully considered beforehand
- May - This word indicates something that is optional. Interoperability between implementations must not be broken because of the choice to implement, or not to implement, this feature
As NFTs have grown in popularity on other blockchains, several common issues with their designs have been exposed. On most blockchains:
- Royalties are settled off-chain. This typically requires trust in the centralized marketplace on which an NFT exists. For example:
- NFTs only use a URL link to prove ownership. If a malicious actor changes the link, the NFT also changes. If the link is broken, the NFT disappears. For example:
- NFT fraud is rampant -- it's easy for someone to copy artwork and mint their own NFTs, posing as the original artist. For example:
- Provenance is difficult, if not impossible, to trace. For example:
Chia NFTs solve all of these problems. They focus on three key features:
-
Independence
- An NFT may be custodied by an individual, a group or a marketplace
- Custody of an NFT may be transferred between individuals, groups and marketplaces
- An NFT's Minter may require the use of a DID instead of an XCH address. If the Minter chooses to require a DID, then the NFT must always have a DID associated with it
- The Minter may define a permanent royalty structure, embedded into the NFT
- The Minter may define one address, derived from a puzzle hash, to be the recipient of royalty payments. This address may correspond to a smart coin with any functionality that Chialisp is capable of providing
- For example, the receive address may be a singleton that pays half of the royalty to the Minter and half to a specific charity
- Offers to purchase an NFT may be made on a marketplace. They also may come from an individual user, using a Chia wallet or a third-party wallet
-
Provenance
- Each NFT may be owned by one DID, based on Chia's DID1 Standard
- If an NFT is minted using a DID, then the NFT's provenance must be traceable to the DID of the NFT's Minter
-
Permanence
- Required: 3 URI lists must be included with each NFT, which map to:
- The NFT's main content
- The NFT's metadata
- The NFT's licensing and legal requirements
- The Owner may prepend links as needed; the Owner may not modify or remove links
- Upon minting an NFT, a SHA-256 hash shall be embedded within the NFT itself. This is recommended to be the hash of the file being linked to. This gives a permanent way to verify the NFT's contents, even if each of the links is broken
- Minters may optionally create an NFT with a content link that does not point to the correct version of the image upon minting. This could be done in the case of a "delayed reveal", where the minter does not wish to reveal the contents of the NFT right away. In this case, the contents of the link are recommended to be updated to the correct contents before revealing the NFT
- Required: 3 URI lists must be included with each NFT, which map to:
Other features:
- Edition numbers: These may be included in an NFT's on-chain metadata upon the NFT's minting. This is not a way to guarantee provenance, but NFT Minters and/or Owners can use the edition number for tracking purposes. This number may not change after the NFT's minting
- Series numbers: These may be included in the NFT's off-chain metadata upon the NFT's minting. For example,
#100 of 1000
. They may also be specified in the NFT's title. For example,Fruits of the World #100
. This number may not change after the NFT's minting - Offers: Any combination of XCH, CATs and NFTs may be bought, sold and traded using offers
- Marketplace custody: With the Owner's consent, central marketplaces may custody an Owner's NFT(s). This consent may not be withdrawn once given. The owner must trust the marketplace to return the NFT upon request
- Marketplace payments: Owners may also sell their NFTs on a central marketplace. It is optional for the marketplace on which the NFT is sold to include their own fees with the sale. These fees exist outside of the NFTs themselves and should be enforced through Offers
- Auditability: NFT sales shall be recorded on Chia's public blockchain. The NFT's metadata shall be discoverable by blockchain explorers. This enables data analytics, tax accounting, and airdrops of XCH, CATS and NFTs. In addition to the normal information available with each transaction, the on-chain metadata must include:
- The DIDs of the buyer and seller (where applicable)
- The NFT's file hash
- All links associated with the NFT
Use cases for Chia NFTs include, but are not limited to:
- Selling artwork with permanent built-in royalties
- Maintaining a cryptographically verifiable provenance for digital or physical assets
- Reducing the fraudulent sale, or outright theft, of artwork
- Transferring digital assets between marketplaces
- Creating a permanent method to verify a digital asset's originality
- Storing metadata for an asset permanently
NFT1 does not introduce any breaking changes to Chia.
We chose the design for NFT1 because it significantly improves upon existing NFTs. For the first time, NFTs will be available to be minted, purchased, sold and exchanged on a decentralized network. We included Offers to obviate the need for intermediaries and centralized custodians. The incorporation of DIDs will ensure strong provenance. By using multiple links and hashes, we'll increase the likelihood of digital permanence.
Despite all of these advantages, NFT1 will likely only be the first NFT spec on Chia's blockchain. The rest of this section will detail the design decisions made for NFT1.
- Each NFT may be owned by exactly one DID, based on Chia's DID1 Standard
- A Transfer Program is required for all NFTs. This program sets the rules of transferring an NFT’s ownership and DID information
- The Minter may limit who can own the NFT by including a demand that any recipient present a DID. For the Transfer Program included in this CHIP, there are no restrictions on what that DID may be
- NFT Owners must be able to view a list of NFTs they own. This includes both ownership scenarios for NFTs – those owned by a DID, and those owned by an XCH address
- The Minter must include a Transfer Program with the NFT upon its minting. This program sets the standard governing how the NFT will be transferred throughout its life. The Transfer Program may not be modified after the NFT's minting
- NFTs must support transaction fees upon gifting, selling, transferring or swapping NFTs. These fees are paid to Chia's farmers and are completely separate from royalty payments
- Wallets that implement NFT1 must automatically discover new NFTs owned by the wallet’s owner – whether via a DID or an XCH address – and add them to the wallet
- Wallets that implement NFT1 should not display the contents of NFTs if the hash of the contents does not match the Data Hash
- Users of wallets that implement NFT1 must be able to view a gallery of the NFTs they own
- Users of wallets that implement NFT1 must be able to view the metadata and license information for all NFTs they own
- NFT1 NFTs may be of any media format, including (but not limited to) images, audio and video. Each implementation may choose which formats to support for previewing and/or viewing
A Transfer Program may contain a wide variety of functionality. NFT1 will ship with one recommended Transfer Program, which allows the following types of transfer:
NFTs may be sold for XCH and/or CATs. NFT Owners are recommended to use Offers in order to facilitate the trustless peer-to-peer sale of NFTs.
The buyer of the NFT must pay the required royalty, if applicable. This remains true whether the buyer is the Maker or the Taker of the offer.
Each time an NFT is sold, each of the following shall be made discoverable by blockchain explorers:
- ID of the NFT being sold
- Seller's DID (if applicable)
- Buyer's DID (if applicable). However, because the NFT is not assigned to the buyer’s DID until the next time the coin moves, the most recent Owner might not be visible to blockchain explorers
- Sale price
- Royalty payment (if applicable)
- Optional: Upon minting an NFT, the Minter may allow Owners to gift the NFT. This feature must be enabled by allowing zero-royalty transfers in the Transfer Program
- If gifting is allowed, then in order for the transfer to be considered a gift:
- The current Owner must send the NFT with a royalty payment of zero to the new Owner
- The current Owner must send the NFT using a wallet that supports NFTs
- The current Owner must not send the NFT using an Offer
- When an NFT is gifted, each of the following shall be made discoverable by blockchain explorers:
- ID of the NFT being gifted
- Sender's DID (where applicable)
- Receiver's DID (where applicable). However, because the NFT is not assigned to the receiver’s DID until the next time the coin moves, the most recent Owner might not be visible to blockchain explorers
- Zero sale price
- Zero royalty
- One or more NFT(s) may be swapped for one or more NFT(s)
- Royalties must be zero for all swaps
- When NFTs are swapped, each of the following shall be made discoverable by blockchain explorers:
- IDs of all NFTs being swapped
- Sender's DID (where applicable)
- Receiver's DID (where applicable). However, because the NFT is not assigned to the receiver’s DID until the next time the coin moves, the most recent Owner might not be visible to blockchain explorers
- Zero sale price
- Royalty payment(s) when applicable
- An NFT's owner may transfer their NFT to a DID or XCH address that they own.
- When an NFT is transferred, each of the following shall be made discoverable by blockchain explorers:
- ID of the NFT being transferred
- Sender's DID (where applicable)
- Receiver's DID (where applicable)
- Zero sale price
- Zero royalty
Custom Transfer Programs with different functionality optionally may be deployed. They shall be considered conformant with this CHIP.
Each NFT that follows the NFT1 standard is required to be implemented as a singleton. Because of this, users are required to spend a minimum of 1 mojo to create an NFT.
Each NFT must contain the following information:
- NFT Address: An NFT's ID shall be its launcher, which is a bech32-encoded address with a prefix of "nft"
- Data URI list: A list of URIs that map to the NFT's main content
- This list shall be stored as bytes, which may be encoded in any format
- This list must contain at least one URI
- The Owner optionally may prepend to this list, such that the newest URI will always be the list’s first element. The Owner shall not modify or remove the list
- Each URI may be a:
- Decentralized storage link, such as IPFS, Arweave, Storj, etc
- Web URL
- Upon the NFT's minting, the content of the first item in this list is recommended to hash to the Data Hash (defined below)
- Metadata URI list: A list of URIs that map to the NFT's metadata
- This list shall be stored as bytes, which may be encoded in any format
- This list must contain at least one URI
- The Owner optionally may prepend to this list, but they shall not modify or remove it
- This list must be curried into the NFT's puzzle
- Upon the NFT's minting and sale, the content of the first item in this list is recommended to hash to the Metadata Hash (defined below)
- There will be multiple off-chain metadata formats, each of which will have its own Process CHIP. These CHIPs shall specify a list of required, recommended, and/or optional fields. If a formalised specification can be produced (such as a JSON schema dialect), then this should be included in the CHIP's assets directory to enable schema verification
- In order for an NFT to conform to a specific off-chain metadata CHIP, it must specify
"format": "CHIP-XXXX"
within the metadata (or the equivalent key-value data structure in the chosen file format), whereXXXX
shall be the corresponding CHIP number - License URI list: A list of URIs that map to the NFT's licensing and legal requirements
- This list shall be stored as bytes, which may be encoded in any format
- This list must contain at least one URI
- The Owner optionally may prepend to this list, but they shall not modify or remove it
- Upon the NFT's minting, the content of the first item in this list is recommended to hash to the License Hash (defined below)
- Data Hash: The SHA-256 hash of the NFT’s content. For example, if the NFT is a .jpeg file, then the Data Hash is the hash of that file. Upon the NFT's minting, this hash is recommended to match the hash of the content of the first item of the Data URI list (defined above). This hash shall not be modified after the NFT's minting
- Metadata Hash: A SHA-256 hash of the contents of the first item of the Metadata URI list. This hash shall not be modified after the NFT's minting
- License Hash: A SHA-256 hash of the contents of the first item of the License URI list. The Transfer Program shall dictate whether this hash may be modified after the NFT's minting
- Royalty structure: This must be created upon minting, with the following options
- Royalties may be disabled
- If royalties are enabled, the NFT must contain a single royalty recipient and percentage. The royalty percentage is represented by an unsigned int with the two least significant digits representing values past the decimal point. For example, a royalty of 312 would equal 3.12%
- The royalty address must take in a puzzle hash as input
- The royalty address may correspond to a singleton. It may be a coin that further distributes the royalty to multiple destinations
- Edition information:
- Each NFT may contain an Edition number
- If an NFT contains an Edition number, then it must also contain the Edition's total count (though this will not be enforced at the RPC level)
- If an NFT does not contain an Edition number, then it must not contain the Edition's total count (though this will not be enforced at the RPC level)
- Transfer Program: Required for all NFTs, explained in detail in the next section
The JSON response coming from the RPC endpoint shall be formatted as
{
"data_url": ["https://..."],
"data_hash": "...",
"metadata_url": ["https://..."],
"metadata_hash": "...",
"license_url": ["https://..."],
"license_hash": "...",
"edition_number": 1,
"edition_count": 1
}
All values are recommended to be used as shown above. However, they may optionally be empty (for the lists and strings) or null (for the strings and numbers).
The Minter shall set the Transfer Program by currying its tree hash into the NFT's inner puzzle.
NFT1 will ship with one example Transfer Program, which is recommended for Minters to use. In this Transfer Program:
- Royalties may be directed to an XCH address. This address is derived from the puzzlehash of any Chialisp puzzle
- The Minter may choose to allow royalty-free transfers by leaving trade_price_list empty
- The NFT may be swapped for one or more NFTs
- The solution may include a list of trade prices, which must be signed the NFT's seller, whether the seller is the Maker or the Taker
This puzzle prepends to the list of rules governing an NFT’s metadata. The minter may set this list to anything. It is located in GitHub, under https://github.com/Chia-Network/chia-blockchain/blob/main/chia/wallet/puzzles/nft_metadata_updater_default.clvm
The metadata updater program can also update itself by using this puzzle: https://github.com/Chia-Network/chia-blockchain/blob/main/chia/wallet/puzzles/nft_metadata_updater_updateable.clvm
This puzzle defines the primary characteristics of the NFT. It is located in GitHub, under https://github.com/Chia-Network/chia-blockchain/blob/main/chia/wallet/puzzles/nft_state_layer.clvm
The NFT1 standard includes Offer 2.0, which builds on top of the Offer 1.0 standard to enable the buying, selling and trading of XCH, CATs and NFTs.
Offer 2.0 is backward compatible with Offer 1.0. Therefore, all wallets that implement NFT1 must allow all functionality included with Offer 1.0. Additionally, these wallets must allow the following functionality, organized by the offers’ Makers and Takers:
Makers
- May include any combination of XCH, CATs and NFTs with the offer. This includes the assets being offered, as well as the assets they will be exchanged for
- Must be shown all royalties associated with all NFTs being offered
- Must specify the NFT ID of any NFTs they want to offer
- Must be shown a visual image of all NFTs they are offering to send and receive
- May see their Open and Accepted NFT offers, including the creation date of all offers
Takers
- Must be shown all royalties associated with all NFTs being offered
- Must be shown a visual image of any NFTs they will send and receive in the offer
- May see their Open and Accepted NFT offers, including creation date of all offers
Wallets that implement NFT1 may optionally include the following RPCs in their implementation. For more information on using these RPCs, see Chia Network Inc's documentation (search for NFT RPCs
).
Functionality: Mint a new NFT
Usage: chia rpc wallet [OPTIONS] nft_mint_nft [REQUEST]
Options:
Short Command | Long Command | Type | Required | Description |
---|---|---|---|---|
-j | --json-file | TEXT | False | Instead of REQUEST, provide a json file containing the request data |
-h | --help | None | False | Show a help message and exit |
Request Parameters:
Parameter | Required | Description |
---|---|---|
wallet_id | True | The Wallet ID in which to mint an NFT |
uris | True | A list of URIs to mark the location(s) of the NFT |
hash | True | The hash of the NFT's data. This should use sha256 for proper verification against the URI list |
meta_uris | False | A list of URIs to mark the location(s) of the NFT's metadata |
meta_hash | False | The hash of the NFT's metadata |
license_uris | False | A list of URIs to mark the location(s) of the NFT's license |
license_hash | False | The hash of the NFT's license |
royalty_address | False | The wallet address of the NFT's artist. This is where royalties will be sent. It be derived from a puzzle hash |
royalty_percentage | False | The royalty that will go to the original artist each time the NFT is sold. The percentage is multiplied by 100 -- for example, to set a 15% royalty, set this value to 1500. The default value is 0 |
target_address | False | The wallet address of the initial owner of the NFT. This may be the same as the royalty address |
edition_number | False | If this NFT has multiple Editions, then this indicates the Edition number of this NFT |
edition_count | False | If this NFT has multiple Editions, then this indicates the total number of Editions for this NFT |
fee | False | The one-time blockchain fee to be used upon minting the NFT |
Functionality: Show all NFTs in a given wallet
Usage: chia rpc wallet [OPTIONS] nft_get_nfts [REQUEST]
Options:
Short Command | Long Command | Type | Required | Description |
---|---|---|---|---|
-j | --json-file | TEXT | False | Instead of REQUEST, provide a json file containing the request data |
-h | --help | None | False | Show a help message and exit |
Request Parameters:
Parameter | Required | Description |
---|---|---|
wallet_id | True | The Wallet ID from which to retrieve the NFTs |
Functionality: Transfer an NFT to a new wallet address
Usage: chia rpc wallet [OPTIONS] nft_transfer_nft [REQUEST]
Options:
Short Command | Long Command | Type | Required | Description |
---|---|---|---|---|
-j | --json-file | TEXT | False | Instead of REQUEST, provide a json file containing the request data |
-h | --help | None | False | Show a help message and exit |
Request Parameters:
Parameter | Required | Description |
---|---|---|
wallet_id | True | The Wallet ID of the NFT to transfer |
target_address | True | The address to transfer the NFT to. For NFT0 this must be an XCH address. For NFT1 this could also be a DID address |
nft_coin_id | True | The coin ID of the NFT to transfer |
fee | False | The one-time blockchain fee to be used upon transferring the NFT |
Functionality: Get info about an NFT
Usage: chia rpc wallet [OPTIONS] nft_get_info [REQUEST]
Options:
Short Command | Long Command | Type | Required | Description |
---|---|---|---|---|
-j | --json-file | TEXT | False | Instead of REQUEST, provide a json file containing the request data |
-h | --help | None | False | Show a help message and exit |
Request Parameters:
Request Parameters:
Parameter | Required | Description |
---|---|---|
wallet_id | True | The Wallet ID of the NFT from which to retrieve info |
coin_id | True | The coin ID of the NFT about which to retrieve info |
Functionality: Add a new URI to the location URI list
Usage: chia rpc wallet [OPTIONS] nft_add_uri [REQUEST]
Options:
Short Command | Long Command | Type | Required | Description |
---|---|---|---|---|
-j | --json-file | TEXT | False | Instead of REQUEST, provide a json file containing the request data |
-h | --help | None | False | Show a help message and exit |
Request Parameters:
Request Parameters:
Parameter | Required | Description |
---|---|---|
wallet_id | True | The Wallet ID of the DID wallet to transfer |
nft_coin_id | True | The coin ID of the NFT on which to add a URI |
key | True | Must be either u (data URI), mu (metadata URI), or lu (license URI) |
uri | True | The URI to add |
Test cases for Chia NFTs are located in the main branch of the chia-blockchain GitHub repository, in the /tests/wallet/nft_wallet folder.
The reference implementation for Chia NFTs is located in the main branch of the chia-blockchain GitHub repository, under chia/wallet/nft_wallet.
Chia Network, Inc. has conducted an internal review of the code involved with this CHIP.
None
- 2023-08-08 -- After this CHIP was finalized, the definitions of CHIP Sub-categories were modified. Please note that while this CHIP is sub-categorized as
Chialisp
, under the modern definitions it would be sub-categorized asPrimitive
.
Copyright and related rights waived via CC0.