This m-NFT proposal covers the following functionalities.
- Publicity of the issuer information for authentication purpose
- Class definition for multiple NFT items with the same attribute
- Limited number definition for pre-defined issuance count
- Set definition for a suit of collectibles across different classes
- Claim action supported for ticket like scenarios
- Exchangablility, permenent lock, and self destructibility enable bits configuration
- Inscript by holders
- Extensible information definition
The basic m-NFT issurance logic is to create an
Issuer Cell first, which defines the issuer’s basic information. And then to create a
NFT Class Cell with it, which consistes of the specific information for a class of NFT items. With the
NFT Class Cell, one could issue
NFT Cell to the users.
Data: version: uint8 class_count: uint32 set_count: uint32 info_size: uint16 info: infomation in json format Type: code_hash: ISSUER_TYPE args: type_id Lock: --
version field is set to 0 for now, which indicates the data format version of this cell.
class_count field records the created class count for the issuer, which should be set to zero at creation, and auto increase when create new
NFT Class Cells.
set_count is almost the same as
class_count, only it is used for
set creation count.
info field is assumed to record the issuer’s public information, such as SNS account, images, etc. And the
info_size field should be set to the byte length of
typescript of Issuer Cell is set to
ISSUER_TYPE with args equals to
type_id follows the same rules of
Type ID script.
Here we define the
IssuerID = issuer_cell_typescript_hash[:20] for the future usage.
To make the
info field more compatible across different front-end services, here we give some suggested varible keys:
name: issuer’s name in UTF-8 encoding
website: issuer’s website URL
authentication: typically an SNS announcement about the issuance
image: image URL for issuer
NFT Class Cell
Every NFT Class Cell stands for a group of specific NFT itmes with the same properties. And different NFT Cells issued by the same NFT Class Cell will be marked with different
TokenID as its identity.
Data: // must version: uint8 total: uint32 issued: uint32 <<property: uint64>> // replaced by nft_cell.characteristic configure: uint8 name: <size:uint16> + <vartext> description: <size:uint16> + <vartext> renderer: <size:uint16> + <vartext> // optional data array extinfo_data: <size:uint16> + <vartext> extinfo_data: <size:uint16> + <vartext> ... Type: code_hash: NFT_CLASS_TYPE args: <IssuerID:byte20> | <class_id:uint32> Lock: --
typescript.args equals to
class_id, and the
class_id is an auto-increment variable according to the
class_count variable in the Issuer Cell.
total means the issurance number limitation, zero for unlimited.
issued means the item number that already issued for this class, it’s also used for the NFT Cell
TokenID variable, equals to zero when initally created.
property is a user defined variable to set up the NFT characteristics, we could consider it as the DNA of the items. (It’s removed, and replaced by
characteristic field in the NFT Cell with the same functionality.)
configure is a bitmap variable to constrain the behavior of the NFT items issued by this Class. The bitmap meaning table follows (the bit 0 or 1 means specific functionality enabled or disable).
|bit 1||lockability||permanent locked permit|
|bit 2||inscription||NFT holder could append inscript to the cell|
|bit 4||exchangable before claim|
|bit 5||exchangable after claim|
|bit 6||destructible before claim|
|bit 7||destructible after claim|
renderer are static informational fields for the tokens. But the front-end dApps could pass some specific data to the
renderer URL, such as
property to get runtime generated rich media data.
The RFC also allows user defined
extinfo_data array to provide more information.
Issuer Cell must be present at the input side of the transaction, and the NFT Class Cell could be batch created.
INPUT: Issuer_cell: Data: class_count: k Type: code_hash: ISSUER_TYPE args: type_id OUTPUT: Issuer_cell: Data: class_count: k + m Type: code_hash: ISSUER_TYPE args: type_id NFT_class_cell: Data: total: N_1 issued: 0 Type: code_hash: NFT_CLASS_TYPE args: IssuerID | <class_id = k> ... NFT_class_cell: Data: total: N_m issued: 0 Type: code_hash: NFT_CLASS_TYPE args: IssuerID | <class_id = k+m-1>
NFT Cell is issued by NFT Class Cell, with the same
configure and different
Data: // must version: uint8 characteristic: byte configure: uint8 state: uint8 // optional extinfo_data: <size:uint16> + <vartext> ... Type: code_hash: NFT_TYPE args: IssuerID | class_id | TokenID Lock: --
configure must be the same as
state is different for different NFT Cell, which is used for indication of current NFT state.
|bit 0||claim state||0/1 => unclaimed / claimed|
|bit 1||lock state||0/1 => free / locked|
typescript.args.IssuerID | class_id must be the same as that of
nft_class_cell, and the
TokenID field must be the issued index of
The typescript allows batch issuance of the NFT Cells.
INPUT: NFT_class_cell: Data: total: N issued: < k > property: P configure: C Type: code_hash: NFT_CLASS_TYPE args: IssuerID | class_id OUTPUT: NFT_class_cell: Data: total: N issued: < k + m <= N > property: P configure: C Type: code_hash: NFT_CLASS_TYPE args: IssuerID | class_id NFT_cell: Data: configure: C state: 0 Type: code_hash: NFT_TYPE args: IssuerID | class_id | <TokenID = k> ... NFT_cell: Data: configure: C state: 0 ... Type: code_hash: NFT_TYPE args: IssuerID | class_id | <TokenID = k+m-1>
NFT Set Cell
The issuer could create NFT Set Cell to define a suit of collectible of NFT Classes.
Data: // must version: uint8 set_id: uint32 set_name: <size:uint16> + <vartext> set_description: <size:uint16 + <vartext> item_list_size: uint16 item_list: <class_id:uint32> * item_list_size // optional extinfo_data: <size:uint16> + <vartext> ... Type: code_hash: NFT_SET_TYPE args: IssuerID