NFT Tickets

NFT Registration Ticket

Ticket representation inside blockchain:

{
    "ticket": {
        "type": "nft-reg",
        "nft_ticket": bytes,     // NFT ticket (encoded with base64), see below
      	"version": integer,      // version, 0 now
        "signatures": object,    // signatures, see below
      	"key1": string,          // Unique key
      	"key2": string,          // Second unique key
        "creator_height": int,   // Block height at which NFT Ticket was created
                                 //   it is used to check if the SN that created 
                                 //   this ticket was indeed in the list of top 10 SN
                                 //   at the moment of registration
        "total_copies": int,     // Number of available copies in NFT
        "royalty": float,	 // Royalty %
        "royalty_address": string, // Address to pay royalty
        "green": boolean,	 // Indicate whether there green payment
      	"storage_fee": int,      // Registration fee, in PSL
    }
}

Where nft_ticket is base64 encoding of the following JSON, as a string:

This JSON is created by WalletNode during the New NFT Registration process

{
  "nft_ticket_version": integer // 1
  "author": string,            	// PastelID of the author (creator)
  "blocknum": integer,          // Block height at which NFT Ticket was created
                                //   it is used to check if the SN that created 
                                //   this ticket was indeed in the list of top 10 SN
                                //   at the moment of registration
  "block_hash": bytes           // Same as above, but block hash
  "copies": integer,            // Number of available copies in NFT
  "royalty": float,             // Royalty %
  "green": bool,    		// Indicate whether there green payment
  "app_ticket": bytes,          // Application specific ticket data (as ascii85)
}

Where app_ticket is ascii85 of the following JSON, as a string:

This JSON is created by WalletNode during the New Art Registration process

{
  "creator_name": string,
  "creator_website": string,
  "creator_written_statement": string,

  "nft_title": string,
  "nft_type": string,
  "nft_series_name": string,
  "nft_creation_video_youtube_url": string,
  "nft_keyword_set": string,
  "total_copies": integer,      // number of copies, same as in NFT Ticket

  "preview_hash": bytes,         // hash of the preview thumbnail !!!!SHA3-256!!!!
  "thumbnail1_hash": bytes,      // hash of the thumbnail 1 !!!!SHA3-256!!!!
  "thumbnail2_hash": bytes,      // hash of the thumbnail 2 !!!!SHA3-256!!!!
  "data_hash": bytes,            // hash of the image (or any other asset) that this ticket represents !!!!SHA3-256!!!!

  // dupe detection and fingerprints files IDs, these IDs link ticket to data in P2P storage
  "dd_and_fingerprints_ic": integer,  // initial value of the counter for dd_and_fingerprints files
  "dd_and_fingerprints_max": integer,  // maximum number of dd_and_fingerprints files (current default is 50)
  "dd_and_fingerprints_ids": [list of strings],  // list of IDs of dd_and_fingerprints files in Kademlia

  // raptorq ids files IDs, these IDs link ticket to data in P2P storage
  "rq_ic": integer,               // initial value of the counter for rq_ids files
  "rq_max": integer,              // maximum number of dd_and_fp files (current default is 50)
  "rq_ids": [list of strings],    // list of IDs of of rq-ids files in Kademlia
  "rq_oti": [array of 12 bytes],  // raptorq CommonOTI and SchemeSpecificOTI

}

Dupe detection and fingerprints files and IDs

Dupe detection service - dd-service outputs data as json (dd_and_fingerprints) in the following format

{
  "block": string     			// block_hash from NFT ticket 
  "principal": string 			// PastelID of the author from NFT ticket
  
  "dupe_detection_system_version": string,

  "is_likely_dupe": bool,
  "is_rare_on_internet": bool,

  "rareness_scores": {
      "combined_rareness_score": float,		    // 0 to 1
      "xgboost_predicted_rareness_score": float,    // 0 to 1
      "nn_predicted_rareness_score": float,	    // 0 to 1
      "overall_average_rareness_score": float,	    // 0 to 1
  },

  "internet_rareness": {
      "matches_found_on_first_page": uint32,
      "number_of_pages_of_results": uint32,
      "url_of_first_match_in_page": string,
  },

  "open_nsfw_score": float,	// 0 to 1
  "alternative_nsfw_scores": {
      "drawings": float,	// 0 to 1
      "hentai": float,		// 0 to 1
      "neutral": float,		// 0 to 1
      "porn": float,		// 0 to 1
      "sexy": float,		// 0 to 1
  },

  "image_fingerprint_of_candidate_image_file": [float],    // array with fingerprints values
  "fingerprints_stat": {
      "number_of_fingerprints_requiring_further_testing_1": uint32,
      "number_of_fingerprints_requiring_further_testing_2": uint32,
      "number_of_fingerprints_requiring_further_testing_3": uint32,
      "number_of_fingerprints_requiring_further_testing_4": uint32,
      "number_of_fingerprints_requiring_further_testing_5": uint32,
      "number_of_fingerprints_requiring_further_testing_6":  uint32,
      "number_of_fingerprints_of_suspected_dupes": uint32,
  },

  "hash_of_candidate_image_file": string,
  "perceptual_image_hashes": {
      "pdq_hash": string,
      "perceptual_hash": string,
      "average_hash": string,
      "difference_hash": string,
      "neuralhash_hash": string,
  },
  "perceptual_hash_overlap_count": uint32,

  "maxes": {
      "pearson_max": float,		// 0 to 1
      "spearman_max": float,		// 0 to 1
      "kendall_max": float,		// 0 to 1
      "hoeffding_max": float,		// 0 to 1
      "mutual_information_max": float,	// 0 to 1
      "hsic_max": float,		// 0 to 1
      "xgbimportance_max": float,	// 0 to 1
  },

  "percentile": {
      "pearson_top_1_bps_percentile": float,			// 0 to 1
      "spearman_top_1_bps_percentile": float,			// 0 to 1
      "kendall_top_1_bps_percentile": float,			// 0 to 1
      "hoeffding_top_10_bps_percentile": float,			// 0 to 1
      "mutual_information_top_100_bps_percentile": float,	// 0 to 1
      "hsic_top_100_bps_percentile": float,			// 0 to 1
      "xgbimportance_top_100_bps_percentile": float,		// 0 to 1
  },
}

WalletNode calculates IDs for dd_and_fingerprints_ids field of app_ticket as:

Base58(SHA3_256(compressed(Base64(dd_and_fingerprints).Base64(signatureSN1).Base64(signatureSN2).Base64(signatureSN3).counter)))

Where:

  • dd_and_fingerpints, is data returned by dd-service

  • signatureSN1-3, is Supernode's signatures of dd_and_fingerpints data

  • counter, is number in the range from dd_and_fingerprints_ic to dd_and_fingerprints_ic + dd_and_fingerprints_max

All three parts are concatenated together using "." as separator

rq_ids files and IDs

raptorQ service - rq-service outputs rq-symbols's id's in the following format

BLOCK_HASH
PASTELID
raptroq id1				// raptorq symbol identifiers - ID of that symbol file in Kademlia - !!!!SHA3-256 of symbol block!!!!
...
raptroq idN

WalletNode calculates IDs for rq_ids field of app_ticket as:

Base58(SHA3-256(compress(Base64(rq_ids).Base64(signature).counter)))

Where:

  • rq-service-data, is data created by rq-service

  • signature, is creators signature over rq-service-data

  • counter, is number in the range from rq_ids_ic to rq_ids_ic + rq_ids_max

All three parts are concatenated together using "." as separator

And signatures are the following JSON object:

{
   "principal" : { "PastelID" : "signature" },
         "mn2" : { "PastelID" : "signature" },
         "mn3" : { "PastelID" : "signature" }
}

All signatures here are of nft_ticket

principalelement is created by WalletNode before sending ticket to SuperNodes for further processing

mn2 and mn3 elements are created by SuperNode 2 and SuperNode 3 respectfully

signature elements are created by cNode on the SuperNode 1 as part of cNode API call tickets register nft, and MUST not be passed into the call

Ticket is written into blockchain by the cNode API tickets register nft:

tickets register nft "nft_ticket" "{signatures}" "pastelid of MN 1" "passphrase" "key1" "key2" fee

here,

  • key1 is unique human readable extract from fingerprints

  • key2 is anything else that can be used as secondary key

NFT Activation Ticket

Ticket representation inside blockchain:

"ticket": {
    "type": "nft-act",
    "version": integer,	    // version of the blockchain representation of ticket, 0 now
    "pastelID": string,     // PastelID of the creator
    "reg_txid": string,     // tnx with registration ticket in it
    "creator_height": int,  // block at which artist created Art Ticket,
                            // is used to check if the MN that created art registration ticket was indeed the top MN when the artist created ticket
    "storage_fee": int,     // should match the storage fee from the Art Ticket
    "signature": bytes      // Signature of the ticket created using the MasterNode's private key
}

Ticket is written into the blockchain by the cNode API tickets register act:

tickets register act "txid-of-nft-reg-ticket" creator_height-fromart-reg-ticket fee "PastelID-of-the-creator" "passphrase"

NFT Sell Ticket

Ticket representation inside blockchain:

"ticket": {
    "type": "nft-sell",
    "version": integer,		// version of the blockchain representation of ticket, 0 now
    "pastelID": string,     	// PastelID of the nft owner - either 1) the original creator; or 2) a previous buyer,
		                //   should be the same in either 1) art activation ticket or 2) trade ticket
    "nft_txid": int,     	// txid with either 1) art activation ticket or 2) trade ticket in it
    "copy_number": int, 
    "asked_price": int,
    "valid_after": int,
    "valid_before": int,
    "signature": bytes
}

Ticket is written into the blockchain by the cNode API tickets register sell:

tickets register sell "txid-of-art-to-sell-act-or-trade" price "PastelID-of-the-seller-artist-or-owner" "passphrase"

NFT Buy Ticket

Ticket representation inside blockchain:

"ticket": {
    "type": "nft-buy",
    "version": integer,    // version of the blockchain representation of ticket, 0 now
    "pastelID": string,    //PastelID of the buyer
    "sell_txid": int,      //txid with sale ticket
    "price": int,
    "signature": bytes
},

Ticket is written into the blockchain by the cNode API tickets register buy:

tickets register buy "txid-of-sell-ticket" price "PastelID-of-the-buyer" "passphrase"

NFT Trade Ticket

Ticket representation inside blockchain:

"ticket": {
    "type": "nft-trade",
    "version": integer,		 // version of the blockchain representation of ticket, 0 now
    "pastelID": string,    	// PastelID of the buyer
    "sell_txid": bytes,    	// txid with sale ticket
    "buy_txid": bytes,     	// txid with buy ticket
    "nft_txid": bytes,     	// txid with either 1) art activation ticket or 2) trade ticket in it
    "registration_txid": bytes,	// txid of nft-reg ticket
    "copy_serial_nr": int,
    "signature": ""
},

Ticket is written into the blockchain by the cNode API tickets register trade:

tickets register trade "txid-of-art-to-sell-ticket" "txid-of-art-to-buy-ticket" "PastelID-of-the-buyer" "passphrase"

Last updated