What follows is a DRAFT proposed specification for standardizing or regularizing non-fungible tokens (NFTs) on the BitShares blockchain and similar blockchains. It is a work in progress, and comments and suggestions are welcomed and encouraged.
null-account
, whereby future asset update operations will become impossible.The asset description
field can accommodate arbitrary text. Current convention is to store a JSON blob allowing asset issuers to embed three distinct descriptive properties of the asset. This JSON blob has the following form: (whitespace added for visual clarity)
{
"main": "A magical asset that you will surely want to HODL",
"market": "BTS",
"short_name": "Magical Asset"
}
Where the fields have the following meanings:
main |
Main asset description. Asset issuers can write basically whatever they want. |
market |
"SYMBOL" — Client software uses this symbol to indicate a preferred, suggested, or default market this asset should trade against. |
short_name |
A short (max 32 chars) name of the asset. (E.g. "Bitcoin", for asset BTC.) |
To create a NFT, this document proposes the addition of two new fields to this JSON blob. The keys are nft_object
and nft_signature
, so that the blob will now have the following form:
{
"main": "A magical asset that you will surely want to HODL",
"market": "BTS",
"nft_object": { ... },
"nft_signature": "20ff....ea",
"short_name": "Magical Asset"
}
with the following meanings:
nft_object |
A JSON object containing NFT content and attributes, in a format and containing fields as described below |
nft_signature |
A signature (ECDSA or similar) from a well-known public key of the artist. The artist signs the ascii serialization of the contents of the nft_object to obtain the signature. Client software can verify that the signature is valid. |
The NFT object shall be represented as a canonicalized JSON blob containing all the of required fields and some combination of the optional fields described below. A canonicalized JSON blob is an ascii JSON serialization in which keys appear in lexicographically sorted order, and in which all non-quoted whitespace is removed (no space between keys and values, no linebreaks, no indentation, etc.). Additionally, quoted text should escape control sequences and special characters (such as linebreaks, tabs, unicode characters, etc.).
This document is not meant to impose a rigorous standard that "must" be followed. Rather, it is intended to establish common conventions that people will want to abide by. What exactly is to be included in the nft_object
may be situationally dependent, and NFT creators are entitled to the full freedom to experiment and alter or extend the suggested conventions here.
The following keys are the core attributes that are most strongly suggested for NFTs following this document. They declare what type of NFT is being constructed, establish a firm intentional linkage between the token and the embedded content, and identify the public key or address of the party that will digitally sign the NFT object. In the sections following this one, additional keys are suggested that vary based on the specific type of NFT being created.
type |
String beginning with "NFT/" composed of uppercase letters, the "/" character, and optionally "@" and numerals. Example values: "NFT/ART", "NFT/DOCUMENT",... (Others t.b.d.) Types can optionally be subspaced to convey extra context by appending "/SUBSPACE". (Possible examples: "NFT/ART/VISUAL", "NFT/ART/MUSIC".) They may also be versioned by appending "@x.y". |
attestation |
Here the artist or originator of the encapsulated material commits or dedicates the material to the blockchain, expressly naming the token or asset ID under which the work will live, and attests to its qualified or unqualified uniqueness. E.g., an artist may attest that no other NFT encapsulation of this work exists, and may declare intent as to future re-issues, or tokenization on other chains, etc. Example: "I, [Artist Name], originator of the work herein, hereby commit this piece of art to the BitShares blockchain, to live as the token named TOKEN.NAME, and attest that no prior tokenization of this art exists or has been authorized by me. The work is original, and is fully mine to dedicate in this way. The right to re-issue this artwork under other tokens is [reserved, disavowed]." |
pubkeyhex |
|
sig_pubkey_or_address |
Public key or address that will be used to sign the nft_object . The nft_signature will be checked to ensure it matches this field. If it does, the signature is considered to be valid. (NOTE: While this allows to validate the signature, it does not authenticate the signature. Establishing whether this is in fact the public key of the artist is a separate process.) Examples of what may go here: (1) a bitcoin address, (2) A BitShares, Steemit, or similar "memo" key with prefix, (3) an ECDSA public key in compressed or uncompressed form represented as hex digits, (4) an Ethereum address, (5) a PGP key fingerprint that can be looked up in public key servers or otherwise authenticated, (6) other... etc.Note: Signing an NFT with, say, a bitcoin address used by the artist to deploy previous NFTs on the Counterparty network provides an easy way to establish that an artist releasing NFTs on the BitShares network is the same artist whose work was previously known on other platforms. |
This document seeks only to build out a proposed convention for the "NFT/ART/VISUAL" type space. Other protocol spaces listed here are merely to suggest the possibility of other applications of NFTs. Whoever wishes to deploy NFTs using a protocol space other than "NFT/ART" or "NFT/ART/VISUAL" shall bear the responsibility of establishing and documenting sensible conventions.
NFT/ART |
Artistic works |
NFT/ART/VISUAL |
Visual artistic works. (Media types such as .png, .gif, .jpeg, etc.) |
NFT/ART/VISUAL@1.0 |
Visaul artistic works. Viewer must be capable of at least version 1.0 of the "NFT/ART/VISUAL spec. (Version number specifies a minimum compatible version, and should only be included in the type string if features are used that cannot be represented properly in an older viewer.) |
NFT/ART/VISUAL/SOMETHING |
Where "SOMETHING" is some label that establishes some agreed upon or conventional formatting or extensions to "NFT/ART/VISUAL" spec. NFT artists are encouraged to explore and play with such subspaces. It is expected that viewers that understand only "NFT/ART/VISUAL should in most cases display these NFTs more-or-less corrrectly, although perhaps missing some details or extra metadata that a subspace-specific viewer would understand. |
NFT/ART/MUSIC |
Songs, MIDI, etc. |
NFT/DOCUMENT |
Example: a journalist writes an article, or an author writes a short story, and the token conveys publication rights. |
NFT/DEED |
Property (virtual or real) deeds |
NFT/PASSPORT |
Token holder may obtain access to, say, a virtual reality "country" or other exclusive space. |
The following keys are conventional and expected for NFT's in the "ART" subspace. They are strongly suggested, however this spec does not specifically forbid omitting them.
title |
Title of the work |
artist |
Name or pseudonym of the artist. May also include aliases or online names or handles, to include blockchain account names or addresses which might facilitate authenticating a signing key. Example: "Arty McArtface (on BitShares as @artface)" |
narrative |
A personal statement from the artist describing the work, such as what the work means to them, or what inspired it. May include details of it's creation, etc. It's a freeform field, and can be adapted as appropriate for the piece. Example, if the work is an avatar, playing card, role playing character, etc., then this field may also include stats and abilities, strengths, weaknesses, etc. |
encoding |
Typically "base64", and indicates that the binary data of the media item or other binary fields have been serialized to ascii using base64 encoding |
media key(s) | (Described below.) |
Typically ONE of the following keys must be included to embed the media item if the value of the type
field is "NFT/ART". The particular key used indicates the file type. Note, the data contained in the value is serialized according to the value of the required encoding
key, unless the media is referenced by an ipfs multihash, in which case the encoding
key can be ignored. If MORE than one of the following keys are used, it SHOULD be a combination of one data type and a multihash of the same type. In this case, the embedded image is understood to be a preview or thumbnail of a full-resolution image referenced by multihash.
The following is not a comprehensive list, and additional media types may be defined.
media_png |
An image file in PNG format |
media_gif |
An image file in GIF format |
media_jpeg |
An image file in JPEG format |
media_png_multihash |
An ipfs multihash of an image file in PNG format |
media_gif_multihash |
An ipfs multihash of an image file in GIF format |
media_jpeg_multihash |
An ipfs multihash of an image file in JPEG format |
tags |
Comma-separated list of keywords to facilitate topic/interest searches. |
flags |
Comma-separated list of semistandardized FLAG keywords to indicate important information to viewers and parsers. Example: "NSFW". Subspacing may be used here, e.g. "NSFW/NUDITY", to convey a specific reason for the NSFW tag. This field could also accommodate a "TRIGGER" flag with subspaces to convey trigger warnings. |
acknowledgments |
Acknowledgments or additional credits for the digital token. E.g., "Artwork prepared for digital tokenization by Amalgamated Tokenworks, LTD." |
license |
License under which the artwork is released. Often, this will be a simple license identifier, such as "CC BY-NC-SA 2.0", though it can also be a fully specified verbose license. |
holder_license |
If the token grants additional license for the use of the creative work specifically to token holders, this can be specified here. An example of such a license might be granting to the holder of the NFT token the right print and sell physical copies of the tokenized artwork, or to collect royalties for commercial use of the artwork, etc. |
password_multihash |
If the media item and/or narrative fields are encrypted, e.g. with AES encryption, this field can contain the ipfs multihash of a file containing either the unlock passphrase or other instructions for how to decrypt the work. (Note that ipfs multihashes can be computed without necessarily publishing, so that this multihash provides a mechanism to reveal the decryption keys at a future date, and publish in such a way that an NFT viewer can easily retrieve the needed information for rendering. A standardized format for these password files is T.B.D.) |
Discussion can occur here: Issues.
NFTs impose a RAM burden on witness and API nodes by virtue of the fact that asset objects, including description field are kept in RAM. Token creators should do their utmost to reduce the storage footprints of their artwork, however, a storage burden in some form is inescapable. Aside from storing links to content instead of actual content data, one option to reduce the RAM hit might be to publish the NFT with full artwork, but then in a subsequent block to replace the nft_object field contents and replace with an object that refers to the block number in which the original publication occurred. Further discussion of this possibility is here: (issues/1).