Skip to main content

NFT Item

This file provides traits for NFT items compliant with the TEP-0062 standard.

Reference:

Messages

Transfer

Initiates a transfer of the NFT item.

message(0x5fcc3d14) Transfer { 
query_id: Int as uint64;
new_owner: Address;
response_destination: Address;
custom_payload: Cell?;
forward_amount: Int as coins;
forward_payload: Slice as remaining;
}

OwnershipAssigned

Notifies about the assignment of ownership.

message(0x05138d91) OwnershipAssigned {
query_id: Int as uint64;
prev_owner: Address;
forward_payload: Slice as remaining;
}

Excesses

Handles any excesses in the process.

message(0xd53276db) Excesses {
query_id: Int as uint64;
}

GetStaticData

Requests static data of the NFT item.

message(0x2fcb26a2) GetStaticData {
query_id: Int as uint64;
}

ReportStaticData

Reports the requested static data.

message(0x8b771735) ReportStaticData {
query_id: Int as uint64;
index: Int as uint256;
collection: Address;
}

NftData Structure

Describes the data structure of an NFT.

struct NftData {
is_initialized: Bool;
index: Int;
collection_address: Address;
owner_address: Address;
individual_content: Cell;
}

NFTItemStandard Trait

Trait encompassing standards for an NFT item.

contract ExampleNFTItem with NFTItemStandard {
override const gasConsumption: Int = ton("0.03");

collection_address: Address;
index: Int;
owner: Address;
individual_content: Cell;
is_initialized: Bool = false;

init(collection_address: Address, index: Int, owner: Address, individual_content: Cell) {
self.collection_address = collection_address;
self.index = index;
self.owner = owner;
self.individual_content = individual_content;
}
}

Messages Handling、Internal Functions and Get Methods

Messages Handling

receive(msg: Transfer)

Handles a transfer message, initiating the mint or transfer process.

receive(msg: Transfer){
let ctx: Context = context();
let remain: Int = self._transfer_estimate_rest_value(ctx);
self._transfer_validate(ctx, msg, remain);
if (self.is_initialized == false) {
self.mint(ctx, msg);
} else {
self.transfer(ctx, msg, remain);
}
}

receive(msg: GetStaticData)

Handles a request for static data.

receive(msg: GetStaticData){
self._report_static_data(msg);
}

Internal Functions

_transfer_estimate_rest_value(ctx: Context): Int

Calculates the remaining value to be returned to the previous owner.

// @dev  _transfer_estimate_rest_value calculates the remain amount of nanotons that should be sent back to the old owner
inline fun _transfer_estimate_rest_value(ctx: Context): Int {
let remain: Int = ctx.value;
let tonBalanceBeforeMsg: Int = myBalance() - remain;
let storageFee: Int = self.minTonsForStorage - min(tonBalanceBeforeMsg, self.minTonsForStorage);
return remain - (storageFee + self.gasConsumption);
}

_transfer_validate(ctx: Context, msg: Transfer, remain: Int)

Validates the transfer request.

// @dev  _transfer_validate checks if the request is valid (e.g. the sender is the current owner of the NFT item)
// throws error if the request is invalid
// @note one may override this function to implement custom validation logicTransferked
virtual inline fun _transfer_validate(ctx: Context, msg: Transfer, remain: Int) {
require(ctx.sender == self.owner || ctx.sender == self.collection_address, "NFTItemStandard: Only the owner or collection can transfer the NFT item");
}

mint(ctx: Context, msg: Transfer)

Handles the minting process of an NFT item.

// @dev  mint usually performs the minting of the NFT item
// @note one may override this function to implement custom minting logic
virtual inline fun mint(ctx: Context, msg: Transfer) {
require(ctx.sender == self.collection_address, "NFTItemStandard: Only the collection can initialize the NFT item");
self.is_initialized = true;
self.owner = msg.new_owner;
send(SendParameters{
to: msg.response_destination,
value: 0,
mode: SendIgnoreErrors + SendRemainingValue,
body: Excesses { query_id: msg.query_id }.toCell()
});
}

transfer(ctx: Context, msg: Transfer, remain: Int)

Executes the transfer, sending appropriate notifications.

// @dev  transfer performs the transfer of the NFT item
// if available, it will send OwnershipAssigned message to the new owner
// then, it will send Excesses message to the response_destination (old owner) if needed.
// @note one may override this function to implement custom transfer logic
virtual inline fun transfer(ctx: Context, msg: Transfer, remain: Int) {
self.owner = msg.new_owner;
if (msg.forward_amount > 0) {
send(SendParameters{
to: msg.new_owner,
value: msg.forward_amount,
mode: SendIgnoreErrors,
bounce: false,
body: OwnershipAssigned{
query_id: msg.query_id,
prev_owner: ctx.sender,
forward_payload: msg.forward_payload
}.toCell()
});
}
remain = remain - ctx.readForwardFee();
if (msg.response_destination != newAddress(0, 0) && remain > msg.forward_amount) {
send(SendParameters{
to: msg.response_destination,
value: remain - msg.forward_amount,
mode: SendPayGasSeparately,
body: Excesses { query_id: msg.query_id }.toCell()
});
}
}

_report_static_data(msg: GetStaticData)

Responds with the static data of the NFT item.

// @dev  _report_static_data sends a response with the static data of the NFT item
virtual inline fun _report_static_data(msg: GetStaticData) {
let ctx: Context = context();
send(SendParameters {
to: ctx.sender,
value: 0,
mode: SendRemainingValue,
bounce: false,
body: ReportStaticData{
query_id: msg.query_id,
index: self.index,
collection: self.collection_address
}.toCell()
});
}

_get_nft_data(): NftData

Retrieves the NFT data in compliance with TEP-64.

// @dev  _get_nft_data returns the NFT data in the format that complies with TEP-64
virtual inline fun _get_nft_data(): NftData {
let builder: StringBuilder = beginString();
let collectionData: String = self.individual_content.asSlice().asString();
builder.append(collectionData);
builder.append(self.index.toString());
builder.append(".json");

return NftData {
is_initialized: self.is_initialized,
index: self.index,
collection_address: self.collection_address,
owner_address: self.owner,
individual_content: builder.toCell()
};
}

Get Methods

get_nft_data(): NftData

Gets the NFT data.

get fun get_nft_data(): NftData {
return self._get_nft_data();
}