機能
検証済みコレクション
検証済みコレクションにより、NFT(および一般的なトークン)をグループ化し、その情報をオンチェーンで検証することができます。さらに、コレクション用のデータをオンチェーンに割り当てることで、これらのコレクションの管理を容易にします。
この機能は以下の利点を提供します:
- 追加のオンチェーン呼び出しを行うことなく、任意のNFTがどのコレクションに属しているかを簡単に識別できます。
- 特定のコレクションに属するすべてのNFTを見つけることが可能です(方法についてはガイドをご覧ください)。
- コレクションのメタデータ(名前、説明、画像など)を簡単に管理できます。
コレクションはNFTです
NFT(または任意のトークン)をグループ化するには、まず、そのコレクションに関連するメタデータを保存することが目的のCollection NFTを作成する必要があります。そうです、NFTのコレクションは、それ自体がNFTなのです。オンチェーンでは他のNFTと同じデータレイアウトを持っています。
Collection NFTと通常のNFTの違いは、前者によって提供される情報は含まれるNFTのグループを定義するために使用されるのに対し、後者はNFT自体を定義するために使用されることです。
Collection NFTへのNFTの関連付け
Collection NFTと通常のNFTは、Metadataアカウントの**「Belong To」関係を使用してリンク**されます。MetadataアカウントのオプションのCollectionフィールドがその目的のために作成されています。
CollectionフィールドがNoneに設定されている場合、そのNFTはコレクションの一部ではありません。Collectionフィールドが設定されている場合、そのNFTはそのフィールド内で指定されたコレクションの一部です。
そのため、Collectionフィールドには2つのネストされたフィールドが含まれています:
Key: このフィールドは、NFTが属するCollection NFTを指します。より正確には、Collection NFTのMintアカウントの公開鍵を指します。このMintアカウントはSPL Tokenプログラムによって所有されている必要があります。Verified: このブール値は、NFTが指すコレクションの真の一部であることを確認するために使用されるため、非常に重要です。詳細は後述します。
NFTとCollection NFTの区別
Collectionフィールドだけでは、NFTとコレクションをリンクすることはできますが、特定のNFTが通常のNFTかCollection NFTかを識別するのに役立ちません。そのため、CollectionDetailsフィールドが作成されました。これはCollection NFTに追加のコンテキストを提供し、通常のNFTと区別します。
CollectionDetailsフィールドがNoneに設定されている場合、そのNFTは通常のNFTです。CollectionDetailsフィールドが設定されている場合、そのNFTはCollection NFTであり、このフィールド内に追加の属性を見つけることができます。
CollectionDetailsは、現在V1オプションのみを含むオプションの列挙型です。このオプションは以下のフィールドを含む構造体です:
Size: コレクションのサイズ、すなわち、このCollection NFTに直接リンクされているNFTの数です。この数はToken Metadataプログラムによって自動的に計算されますが、移行プロセスを促進するために手動で設定することもできます。なお、このSize属性を非推奨にするMIPが現在実施されています。
Collection NFTの作成
Collection NFTの作成は、通常のNFTの作成と非常に似ています。唯一の違いは、前のセクションで見た通り、CollectionDetailsフィールドを設定する必要があることです。一部のSDKでは、NFTを作成する際にisCollection属性を要求することでこれをカプセル化しています。
1import { generateSigner, percentAmount } from '@metaplex-foundation/umi';
2import { createNft } from '@metaplex-foundation/mpl-token-metadata';
3
4// Assuming umi is set up with mplTokenMetadata plugin
5
6const collectionMint = generateSigner(umi);
7
8await createNft(umi, {
9 mint: collectionMint,
10 name: 'My Collection',
11 uri: 'https://example.com/my-collection.json',
12 sellerFeeBasisPoints: percentAmount(5.5), // 5.5%
13 isCollection: true,
14}).sendAndConfirm(umi);
15
16console.log('Collection NFT created:', collectionMint.publicKey);
1import { generateKeyPairSigner } from '@solana/kit';
2import { createNft } from '@metaplex-foundation/mpl-token-metadata-kit';
3
4// Assuming rpc, rpcSubscriptions, sendAndConfirm, and authority are set up
5
6const collectionMint = await generateKeyPairSigner();
7
8// Create a Collection NFT
9const [createIx, mintIx] = await createNft({
10 mint: collectionMint,
11 authority,
12 payer: authority,
13 name: 'My Collection',
14 uri: 'https://example.com/my-collection.json',
15 sellerFeeBasisPoints: 550, // 5.5%
16 tokenOwner: authority.address,
17 isCollection: true,
18});
19
20await sendAndConfirm({
21 instructions: [createIx, mintIx],
22 payer: authority,
23});
24
25console.log('Collection NFT created:', collectionMint.address);
ネストされたCollection NFT
コレクションとNFTが「Belong To」関係を通じてリンクされているため、設計上、ネストされたコレクションを定義することが可能です。このシナリオでは、CollectionとCollectionDetailsフィールドを組み合わせて使用して、ルートコレクションNFTとネストされたCollection NFTを区別できます。
Collection NFTの検証
上記で述べたように、Collectionフィールドには、NFTが指すコレクションの真の一部であるかを判断するために使用されるVerifiedブール値が含まれています。このフィールドがなければ、誰でも自分のNFTが任意のコレクションの一部であると偽ることができます。
Verifiedブール値をTrueに変更するには、Collection NFTのAuthorityがNFTに署名して、それがコレクションの一部になることが許可されていることを証明する必要があります。
極めて重要
エクスプローラー、ウォレット、マーケットプレイスは、Verifiedがtrueであることを必ずチェックしなければなりません。Verifiedがtrueに設定されるのは、Collection NFTのAuthorityがNFTに対してToken MetadataのVerify命令の1つを実行した場合のみです。
これはCreatorsフィールドと同じパターンで、NFTを検証するにはVerifiedがtrueである必要があります。
NFTでコレクションが有効かをチェックするには、以下が設定されたコレクション構造体が必要です:
- 適切なコレクション親のmintアドレスと一致する
keyフィールド。 trueに設定されたverifiedフィールド。
これらの2つのステップに従わない場合、実際のコレクションで詐欺的なNFTを露出させる可能性があります。
検証
NFTにCollection属性が設定されると、Collection NFTの権限がToken MetadataにVerify命令を送信して、そのverify属性をfalseからtrueに変更できます。この命令は以下の属性を受け取ります:
- Metadata: NFTのMetadataアカウントのアドレス。これは、コレクション内で検証したいNFTです。
- Collection Mint: Collection NFTのMintアカウントのアドレス。これは、NFTのMetadataアカウントに既に設定されているが、まだ検証されていないCollection NFTです。
- Authority: 署名者としてのCollection NFTの権限。これは、Collection NFTのUpdate Authorityまたは適切な役割を持つ承認された委任先である可能性があります(「委任された権限」ページを参照)。
以下は、Token MetadataでCollection NFTを検証するためのSDKの使用方法です。
1import { publicKey } from '@metaplex-foundation/umi';
2import { verifyCollectionV1, findMetadataPda } from '@metaplex-foundation/mpl-token-metadata';
3
4// Assuming umi, collectionMint, and collectionAuthority are set up
5
6const mintAddress = publicKey('mintAddress...');
7
8// First find the metadata PDA to use later
9const metadata = findMetadataPda(umi, {
10 mint: mintAddress,
11});
12
13await verifyCollectionV1(umi, {
14 metadata,
15 collectionMint,
16 authority: collectionAuthority,
17}).sendAndConfirm(umi);
18
19console.log('Collection verified on NFT');
1import {
2 getVerifyCollectionV1InstructionAsync,
3 findMetadataPda,
4} from '@metaplex-foundation/mpl-token-metadata-kit';
5
6// Assuming rpc, rpcSubscriptions, sendAndConfirm, and collectionAuthority are set up
7
8const mintAddress = 'mintAddress...'; // The NFT to verify
9const collectionMintAddress = 'collectionMintAddress...'; // The collection NFT
10
11// Find the metadata PDA
12const [metadata] = await findMetadataPda({ mint: mintAddress });
13
14// Verify the collection on the NFT
15const verifyIx = await getVerifyCollectionV1InstructionAsync({
16 metadata,
17 collectionMint: collectionMintAddress,
18 authority: collectionAuthority,
19 payer: collectionAuthority,
20});
21
22await sendAndConfirm({
23 instructions: [verifyIx],
24 payer: collectionAuthority,
25});
26
27console.log('Collection verified on NFT');
未検証
相互に、Collection NFTの権限は、そのコレクションの一部である任意のNFTを未検証にすることができます。これは、Token MetadataプログラムにUnverify命令を送信することで行われ、その属性はVerify命令と同じです。
1import { publicKey } from '@metaplex-foundation/umi';
2import { unverifyCollectionV1, findMetadataPda } from '@metaplex-foundation/mpl-token-metadata';
3
4// Assuming umi, collectionMint, and collectionAuthority are set up
5
6const mintAddress = publicKey('mintAddress...');
7
8// First find the metadata PDA to use later
9const metadata = findMetadataPda(umi, {
10 mint: mintAddress,
11});
12
13await unverifyCollectionV1(umi, {
14 metadata,
15 collectionMint,
16 authority: collectionAuthority,
17}).sendAndConfirm(umi);
18
19console.log('Collection unverified on NFT');
1import {
2 getUnverifyCollectionV1InstructionAsync,
3 findMetadataPda,
4} from '@metaplex-foundation/mpl-token-metadata-kit';
5
6// Assuming rpc, rpcSubscriptions, sendAndConfirm, and collectionAuthority are set up
7
8const mintAddress = 'mintAddress...'; // The NFT to unverify
9const collectionMintAddress = 'collectionMintAddress...'; // The collection NFT
10
11// Find the metadata PDA
12const [metadata] = await findMetadataPda({ mint: mintAddress });
13
14// Unverify the collection on the NFT
15const unverifyIx = await getUnverifyCollectionV1InstructionAsync({
16 metadata,
17 collectionMint: collectionMintAddress,
18 authority: collectionAuthority,
19 payer: collectionAuthority,
20});
21
22await sendAndConfirm({
23 instructions: [unverifyIx],
24 payer: collectionAuthority,
25});
26
27console.log('Collection unverified on NFT');
