Overview
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.
Issuer Cell
Data structure
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 info.
The typescript of Issuer Cell is set to ISSUER_TYPE with args equals to type_id, where 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 -
email: email address -
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 Structure
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:
--
Where typescript.args equals to IssuerID join 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 index | meaning | notes |
|---|---|---|
| bit 0 | claimable | |
| bit 1 | lockability | permanent locked permit |
| bit 2 | inscription | NFT holder could append inscript to the cell |
| bit 3 | reserved | |
| bit 4 | exchangable before claim | |
| bit 5 | exchangable after claim | |
| bit 6 | destructible before claim | |
| bit 7 | destructible after claim |
name, description, and 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.
Creation Transaction
The 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
NFT Cell is issued by NFT Class Cell, with the same configure and different TokenID and state field.
Data Structure
Data:
// must
version: uint8
characteristic: byte[8]
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 nft_class_cell.configure. And state is different for different NFT Cell, which is used for indication of current NFT state.
| bit index | meaning | note |
|---|---|---|
| bit 0 | claim state | 0/1 => unclaimed / claimed |
| bit 1 | lock state | 0/1 => free / locked |
| other | reserved | – |
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 nft_class_cell.issued field.
Issuance Transaction
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 Structure
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

