lesson-4_NFTの情報を確認できるようにしよう
🫣 NFT の情報を確認できるようにしよう
まずはNFT1つ1つの情報を見るための関数をつくります。nft_core.rsに移動して下のコードを追加しましょう。
[nft_core.rs]
+ use crate::*;
+
+ pub trait NonFungibleTokenCore {
+ fn nft_token(&self, token_id: TokenId) -> Option<JsonToken>;
+ }
+
+ #[near_bindgen]
+ impl NonFungibleTokenCore for Contract {
+ // get specified token info
+ fn nft_token(&self, token_id: TokenId) -> Option<JsonToken> {
+ if let Some(token) = self.tokens_by_id.get(&token_id) {
+ let metadata = self.token_metadata_by_id.get(&token_id).unwrap();
+ Some(JsonToken {
+ owner_id: token.owner_id,
+ metadata,
+ })
+ } else {
+ None
+ }
+ }
+ }
ひとつずつ見ていきましょう。まずはNonFungibleTokenCore
というトレイトにnft_token
という関数があることを宣言する。ここでは引き数と返り値だけで大丈夫です。
pub trait NonFungibleTokenCore {
fn nft_token(&self, token_id: TokenId) -> Option<JsonToken>;
}
次の部分ではnft_token関数
の中身を記述します。ここでは引数であるtokenのidに対してmetadataが存在するのかを確かめて、ある場合はそれを返すという処理をしています。
#[near_bindgen]
impl NonFungibleTokenCore for Contract {
// get specified token info
fn nft_token(&self, token_id: TokenId) -> Option<JsonToken> {
if let Some(token) = self.tokens_by_id.get(&token_id) {
let metadata = self.token_metadata_by_id.get(&token_id).unwrap();
Some(JsonToken {
owner_id: token.owner_id,
metadata,
})
} else {
None
}
}
}
これによってそれぞれのtokenのmetadataを見れるようになりましたが、walletがNFTを表示できるようにするための関数であるnft_tokens_for_owner関数
がまだ実装できていないのでenumeration.rs
に移動して下のコードを追加しましょう。
[enumeration.rs]
+ use crate::*;
+
+ #[near_bindgen]
+ impl Contract {
+ pub fn nft_total_supply(&self) -> U128 {
+ U128(self.token_metadata_by_id.len() as u128)
+ }
+
+ pub fn nft_tokens(&self, from_index: Option<U128>, limit: Option<u64>) -> Vec<JsonToken> {
+ let start = u128::from(from_index.unwrap_or(U128(0)));
+ self.token_metadata_by_id
+ .keys()
+ .skip(start as usize)
+ .take(limit.unwrap_or(50) as usize)
+ .map(|token_id| self.nft_token(token_id.clone()).unwrap())
+ .collect()
+ }
+
+ // get number of tokens for specified owner
+ pub fn nft_supply_for_owner(&self, account_id: AccountId) -> U128 {
+ let tokens_for_kind_set = self.tokens_per_owner.get(&account_id);
+ if let Some(tokens_for_kind_set) = tokens_for_kind_set {
+ U128(tokens_for_kind_set.len() as u128)
+ } else {
+ U128(0)
+ }
+ }
+
+ pub fn nft_tokens_for_owner(
+ &self,
+ account_id: AccountId,
+ from_index: Option<U128>,
+ limit: Option<u64>,
+ ) -> Vec<JsonToken> {
+ let tokens_for_owner_set = self.tokens_per_owner.get(&account_id);
+ let tokens = if let Some(tokens_for_owner_set) = tokens_for_owner_set {
+ tokens_for_owner_set
+ } else {
+ return vec![];
+ };
+
+ let start = u128::from(from_index.unwrap_or(U128(0)));
+ tokens
+ .iter()
+ .skip(start as usize)
+ .take(limit.unwrap_or(50) as usize)
+ .map(|token_id| self.nft_token(token_id.clone()).unwrap())
+ .collect()
+ }
+ }
最初のnft_total_supply関数
ではコントラクトに保存されているNFTの数を取得できます。
次のnft_tokens
ではコントラクトに保管されている全てのNFTのmetadataが得られます。
pub fn nft_total_supply(&self) -> U128 {
U128(self.token_metadata_by_id.len() as u128)
}
pub fn nft_tokens(&self, from_index: Option<U128>, limit: Option<u64>) -> Vec<JsonToken> {
let start = u128::from(from_index.unwrap_or(U128(0)));
self.token_metadata_by_id
.keys()
.skip(start as usize)
.take(limit.unwrap_or(50) as usize)
.map(|token_id| self.nft_token(token_id.clone()).unwrap())
.collect()
}