Links

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"