跳至主要内容

NFT Collection

這個智能合約為遵守TEP-0062 標準的NFT Collection提供了一個框架。

Overview

在 TEP-0062 標準中,每個 NFT collection 都會關聯一個 NFT Collection smart contract,該合約會儲存關於該 collection 的基本資訊,包括下一個 item 的 index、collection content、owner address。

CollectionData Structure

struct CollectionData {
next_item_index: Int; // collection should issue NFT with sequential indexes starting from 1. -1 value implies non-sequential collections.
collection_content: Cell; // collection content format should comply with TEP64
owner_address: Address; // collection owner address, zero address if no owner
}

NFTCollectionStandard Trait

contract ExampleNFTCollection with NFTCollectionStandard, NFTRoyaltyStandard, Estimatable, Deployable {
next_item_index: Int as uint32 = 0; // if next_item_index is not -1, means sequential minting is enabled. We want a sequential minting in this example so we set it to uint32.
collection_content: Cell; // collection_content may be the prefix of individual_content
owner_address: Address; // owner_address is the address of the owner of the collection
royalty_params: RoyaltyParams; // royalty_params is the params of royalty

init(owner_address: Address, collection_content: Cell, royalty_params: RoyaltyParams) {
self.owner_address = owner_address;
self.collection_content = collection_content;
self.royalty_params = royalty_params;
}

// @dev Mint is not the standard function of NFTCollection, so we need to define it by ourselves
receive("Mint") {
let ctx: Context = context();
let nftItemInit: StateInit = self._get_nft_item_state_init(self.next_item_index);
send(SendParameters{
to: contractAddress(nftItemInit),
value: self.estimate_rest_value(ctx),
bounce: false,
mode: SendIgnoreErrors,
body: Transfer {
query_id: 0,
new_owner: ctx.sender,
response_destination: ctx.sender,
custom_payload: emptyCell(),
forward_amount: 0,
forward_payload: emptySlice()
}.toCell(),
code: nftItemInit.code,
data: nftItemInit.data
});
self.next_item_index = self.next_item_index + 1;
}

// @dev _get_nft_item_state_init returns the initCode of NFTItem
override inline fun _get_nft_item_state_init(index: Int): StateInit {
return initOf ExampleNFTItem(myAddress(), index, self.owner_address, self.collection_content);
}
}

Internal Functions and Get Methods

Internal Functions

_get_nft_item_state_init(index: Int): StateInit

透過 NFT Item Index 計算 NFT item contract 的 init code,這個 function 必須要被 override

abstract inline fun _get_nft_item_state_init(index: Int): StateInit;

_get_nft_content(index: Int, individual_content: Cell): Cell

透過 NFT item 的 index 拿到 NFT item 的 content,回傳符合 TEP-64 的 NFT item content。

// @dev _get_nft_content gets the serial number of the NFT item of this collection and the individual content of this NFT item.
// returns the full content of the NFT item in format that complies with standard TEP-64.
// @note one MUST override this function to provide full NFT item content
virtual inline fun _get_nft_content(index: Int, individual_content: Cell): Cell {
let builder: StringBuilder = beginString();
let idvStr: String = individual_content.asSlice().asString();
builder.append(idvStr);
return builder.toCell();
}

_get_collection_data(): CollectionData

回傳 NFT collection 的資訊。

// @dev get_collection_data returns nft collection data
virtual inline fun _get_collection_data(): CollectionData {
let builder: StringBuilder = beginString();
let urlPrefix: String = self.collection_content.asSlice().asString();
builder.append(urlPrefix);
builder.append(self.NFT_COLLECTION_STANDARD_METADATA);
return CollectionData {
next_item_index: self.next_item_index,
collection_content: builder.toCell(),
owner_address: self.owner_address
};
}

Get Methods

get_collection_data(): CollectionData

回傳 NFT collection 的資訊。

get fun get_collection_data(): CollectionData {
return self._get_collection_data();
}

get_nft_address_by_index(index: Int): Address

透過 NFT item 的 index 拿到 NFT item 的 address。

// @dev get_nft_address_by_index gets the serial number of NFT item of this collection and returns its address
get fun get_nft_address_by_index(index: Int): Address {
let initCode: StateInit = self._get_nft_item_state_init(index);
return contractAddress(initCode);
}

get_nft_content(index: Int, individual_content: Cell): Cell

呼叫 _get_nft_content 並回傳符合 TEP-64 的 NFT item content。

// @dev get_nft_content calls _get_nft_content and returns the full content of the NFT item in format that complies with standard TEP-64.
get fun get_nft_content(index: Int, individual_content: Cell): Cell {
return self._get_nft_content(index, individual_content);
}

Usage

Basic Usage

想要使用這個 NFT Collection Standard,你需要實作一個 NFT Collection 合約,並且 override _get_nft_item_state_init_get_nft_content

// Your contract should look something like this
contract YourNFTCollection with NFTCollectionStandard {
// ... your custom properties and methods ...

override inline fun _get_nft_item_state_init(index: Int): StateInit {
// ... your implementation ...
}

override inline fun _get_nft_content(index: Int, individual_content: Cell): Cell {
// ... your implementation ...
}
}