Enumerable拡張とは?
Enumerable拡張は、ERC-721非代替性トークン(NFT)規格の任意拡張です。オンチェーンのインデックスクエリを通じて、スマートコントラクトや暗号資産アプリケーションがNFTのトークンIDを検出できるようにします。一般に、インターフェース名の
公式のERC-721仕様では、この拡張を、コントラクトが有効なNFTの完全な一覧と、各アドレスが所有するトークンIDを公開する方法として定義しています。
この拡張は、
なぜ「Enumerable」と呼ばれるのか?
コレクションを列挙するとは、インデックスなどの体系化された方法を使って、その構成要素を1つずつ特定することです。ERC-721の基本インターフェースでは、既知のトークンIDを誰が所有しているかをアプリケーションが確認できます。また、あるアドレスが所有するNFTの数も確認できます。しかし基本インターフェースには、存在するすべてのトークンIDや、特定の所有者が持つすべてのトークンIDをオンチェーンで直接検出する関数はありません。Enumerable拡張は、コレクション全体と各所有者の保有分にインデックスによるアクセスを追加し、この不足を補います。アプリケーションはインデックス0から始め、対象となる供給量または所有者残高に達するまで、より大きなインデックスを順に照会できます。Enumerable拡張のインターフェースIDとは?
ERC-721 Enumerable拡張のERC-165インターフェースIDは
対応するコントラクトは、
ERC-165インターフェース検出規格を使うと、アプリケーションはスマートコントラクトに対し、どのインターフェースを実装していると表明しているかを問い合わせられます。
ERC-721の基本インターフェースには別のIDがあるため、基本機能とEnumerable拡張への対応を個別に確認できます。Enumerable拡張を実装するコントラクトは、ERC-721の基本インターフェースも実装する必要があります。インターフェース検出で肯定的な応答があれば互換性の確認に役立ちますが、実装の正しさ、安全性、誠実さを証明するものではありません。Enumerable拡張で追加される関数
Enumerable拡張が追加する公開クエリ関数は3つだけです。totalSupply関数
したがって、
tokenByIndex関数
有効なインデックスは、
tokenOfOwnerByIndex関数
インデックスは0から始まり、その所有者に対する
3つの関数の連携
アプリケーションは
その後、供給量未満となる0からの各インデックスについて、
返された各トークンIDについて
特定のアドレスの保有分を一覧表示するには、
列挙順序は保証されない
ERC-721仕様は、
Swap-and-Popによる列挙
トークンIDを配列から効率的に削除するため、一般的な実装ではswap and popという手法を使います。トークンを削除するとき、実装は最後のトークンを、削除対象のトークンが以前あった配列位置に移します。その後、配列の最後の要素を削除します。これにより、後続のすべてのトークンをずらす必要がなくなり、削除の計算量を比較的低く抑えられます。ただし、残りのトークンの順序は変わります。現在のOpenZeppelin ERC721Enumerable実装は、全体および所有者別のインデックスの両方にこの手法を採用しています。
そのため、長い列挙処理の途中で所有権が変化した場合、アプリケーションはページネーションを最初からやり直すか、慎重に整合性を取り直す必要があります。コレクション全体を列挙する例
ERC-721コントラクトが総供給量4を報告しているとします。アプリケーションは、インデックス0、1、2、3を指定して
各IDについて
所有者別の列挙例
Enumerable NFTコントラクトで、AliceがトークンID 9、30、88を所有しているとします。コントラクトの
アプリケーションは
Enumerable拡張とERC-721基本規格の違い
ERC-721基本規格は、所有権、転送、承認、イベント、安全な受取先の確認を提供します。既知のトークンIDが存在するか、誰が所有しているかを確認できます。すべてのトークンIDを列挙する標準化されたオンチェーン一覧は提供しません。Enumerable拡張は、この検出機能を追加します。列挙機能のないコレクションでも、通常どおりNFTを転送し、ERC-721対応ウォレットで利用できます。列挙機能がないからといって、NFTが無効または規格不適合になるわけではありません。幅広いERC-721互換性を確保するには、アプリケーションは列挙可能・不可能の両方のコレクションに対応する必要があります。Enumerable拡張とMetadata拡張の違い
Enumerable拡張は、既存のトークンIDと所有者の保有分を特定します。Metadata拡張は、コレクション名、シンボル、トークンURIを提供します。列挙機能は、NFTに紐づく画像、属性、タイトル、外部コンテンツを説明しません。メタデータ対応だけでは、トークンの完全な一覧は取得できません。コントラクトは、ERC-721基本機能を実装しつつ、いずれかの拡張、両方、またはどちらも実装しないことができます。アプリケーションは各インターフェースを個別に確認してください。Enumerable拡張とtotalSupply単独実装の違い
Enumerable拡張全体を実装せずに、独自の
よく知られた関数名があるからといって、
Enumerable拡張でガス代が増える理由
列挙には、コントラクトが追加のストレージ構造を維持する必要があります。一般的な実装では、存在するすべてのトークンIDの配列を保存します。また、各所有者のインデックス付きトークン一覧と、トークン位置を記録するマッピングも保存します。ミント時には、新しいトークンを全体リストと所有者リストの両方に追加する必要があります。転送時には、以前の所有者のリストからトークンを削除し、新しい所有者のリストに追加する必要があります。バーン時には、所有者リストと全体リストの両方からトークンを削除する必要があります。これらの追加ストレージ書き込みにより、状態を変更するトランザクションのガス代が増加します。現在のERC-721実装ガイダンスでは、大きなガスオーバーヘッドが生じるため、この拡張は省略されることが多いと説明されています。
列挙クエリは無料か?
ユーザーはブロックチェーントランザクションを送信せずに、RPCエンドポイントを通じてview関数を呼び出せます。その場合、ノードが読み取りをローカルでシミュレーションするため、オンチェーンのガス代は発生しません。ただし、ノードは計算を行い、レート制限やリクエスト制限を設ける場合があります。別のスマートコントラクトがトランザクション中に列挙関数を呼び出す場合、その計算にはトランザクションのガスが必要です。オンチェーンで数百、数千のトークンインデックスを照会するループは、実行コストが高くなりすぎる場合があります。ガス代のかからないオフチェーン読み取りと、無制限のオンチェーン計算を混同してはいけません。ループとブロックガス上限
スマートコントラクトでは、コレクション内の全NFT、または制限のないアドレスが所有する全NFTをループ処理する状態変更関数を避けるべきです。反復回数が時間とともに増え、最終的にトランザクションがブロックガス上限を超える可能性があります。Solidityのセキュリティ文書は、ストレージ依存のループによって、将来的にコントラクトの処理が完了できなくなる可能性を警告しています。
オフチェーンから呼び出すview関数では同じトランザクション手数料は発生しませんが、RPCプロバイダーに過剰な負荷をかける可能性はあります。大規模なデータセットでは、上限付きページ、個別のインデックスクエリ、またはオフチェーンインデックスを利用してください。代替手段としてのオフチェーンイベントインデックス
準拠したERC-721コントラクトは、NFTのミント、転送、バーン時に
Enumerable拡張とイベントインデックスの違い
オンチェーン列挙では、スマートコントラクトが標準化された方法でトークンインデックスに直接アクセスできます。イベントインデックスは、より豊富で拡張性の高いオフチェーン検出機能を提供します。外部データベースに頼らず、別のスマートコントラクトがトークンIDを検証または選択する必要がある場合、列挙が役立ちます。ウォレットのインターフェース、コレクションページ、分析、過去の検索には、通常、イベントインデックスの方が実用的です。プロジェクトは両方の方法に対応できます。最適な選択は、オンチェーンでの検出可能性が、ミント、転送、バーンのたびに発生する追加ガス代に見合うかどうかによって決まります。列挙機能はページネーションを提供するか?
この拡張には、トークンIDのページを返す関数は定義されていません。各インデックスのクエリに対して、トークンIDを1つ返します。オフチェーンアプリケーションは、限られた範囲のインデックスをリクエストすることでページネーションを実装できます。たとえば、1ページ目ではインデックス0~49、2ページ目では50~99を照会できます。ページ間の供給量や順序の変化を考慮する必要があります。転送やバーンによりトークンが別のインデックスへ移動すると、長時間のページネーション処理でIDが欠落または重複する可能性があります。RPCシステムが過去ブロックへの呼び出しに対応している場合、固定したブロック高のデータを使うと、一貫性の高いスナップショットを取得できます。列挙機能はすべての所有者を一覧表示するか?
この拡張は、トークンIDを全体として、また既知の所有者ごとに一覧表示します。一意の所有者アドレスをすべて返す関数はありません。アプリケーションは各トークンIDについて
列挙機能はトークンの真正性を証明するか?
いいえ。列挙機能が報告するのは、特定のスマートコントラクトが追跡するトークンIDだけです。誰でも、名称、画像、シンボル、メタデータをコピーしたEnumerable ERC-721コントラクトをデプロイできます。NFTを識別するには、ブロックチェーンネットワークと完全なコントラクトアドレスが不可欠です。Enumerableインターフェースが正しくても、発行者がアート作品を所有していること、主張する資産を管理していること、または誠実であることは証明されません。ユーザーは信頼できるプロジェクト情報でコントラクトを確認し、その権限を個別に調べてください。totalSupplyは希少性を証明するか?
現在の供給量は、恒久的な最大供給量を確定するものではありません。コントラクトには、公開ミント関数、管理者のミント権限、ブリッジによるミント機能、またはアップグレード権限が存在する場合があります。現在所有者のいないトークンIDが、後からミント可能な場合もあります。アップグレード可能なコントラクトでは、デプロイ後に供給ルールが変更される可能性があります。希少性の主張を信頼する前に、コードとアクセス制御の仕組みを確認してください。列挙により現在の供給量は照会しやすくなりますが、経済的な約束が履行される保証にはなりません。ミントと列挙
新しいNFTをミントする際、Enumerable実装はそのトークンIDを全体のインデックスと最初の所有者のインデックスの両方に追加する必要があります。これにより総供給量は1増加します。トークンIDは、実装が有効とする任意の全体インデックスに表示される可能性があります。連番でミントする方針でも、列挙インデックスがトークンIDと常に等しくなるとは限りません。独自のミントロジックでは、必要な列挙構造をすべて一貫して更新する必要があります。更新が不完全だと、残高、所有権記録、総供給量、列挙結果が食い違う可能性があります。転送と列挙
通常、転送によって総供給量は変わりません。トークンIDは以前の所有者の列挙から削除され、受取人の列挙に追加されます。通常、全体のトークン一覧には同じトークンIDが残ります。削除処理の一環として、所有者別インデックスの位置が変わる場合があります。送信者と受取人が同じアドレスになる自己転送は、慎重に実装する必要があります。レビュー済みの実装では、トークンを誤って削除または重複させないようこの条件を処理しています。バーンと列挙
バーンは、トークンを有効なERC-721所有権から除外します。Enumerable実装は、バーンされたトークンIDを所有者の一覧と全体のトークン一覧から削除します。総供給量は減少します。トークンの以前の全体インデックスと所有者インデックスは、以後使用できません。swap-and-popによる削除では、別のトークンがその位置に移動する場合があります。バーンされたNFTの履歴が必要なアプリケーションは、現在の列挙ではなくイベントを利用してください。バッチミントとの互換性
ERC-721実装によっては、コントラクトの構築中に圧縮形式または連続形式のバッチミントに対応しています。このようなシステムでは、通常の列挙更新ロジックを使って各トークンを記録せずに所有権を計算する場合があります。現在のOpenZeppelin実装は、連続ミント拡張が
列挙とアップグレード可能なコントラクト
アップグレード可能なNFTコントラクトは、ガバナンスシステムが認める場合、デプロイ後にロジックを追加または変更できます。多数のNFTがすでに存在する状態で列挙機能を追加する場合は、特に慎重な対応が必要です。コアコントラクトがすでに数千のトークンを追跡していても、新しい列挙用ストレージは空の状態から始まる場合があります。全体および所有者別のインデックスを作成する移行処理が必要になる場合があります。大規模なオンチェーン移行ループは、ガス上限を超える可能性があります。ストレージレイアウトの誤りによって、既存の所有権データや承認データが破損する場合もあります。アップグレード管理者は、テスト済みの移行手順、上限付きトランザクション、独立したセキュリティレビューを利用してください。列挙と独自のbalanceOfロジック
所有者別の列挙は、正確なERC-721残高情報に依存します。統合アプリケーションのセキュリティリスク
拡張関数を呼び出す前に、アプリケーションはEnumerable対応を確認する必要があります。以前に確認したインデックスが現在も有効だと決めつけず、範囲外エラーを処理してください。レアリティ、優先順位、金融計算に列挙順序を利用してはいけません。ページネーション中に状態が変わった場合の重複や欠落に備える必要があります。返されたすべてのトークンIDが、想定するコントラクトとネットワークに属することも確認してください。価値の高い判断では、一貫したブロックのスナップショットと適切なファイナリティレベルが必要になる場合があります。RPCとデータの整合性
RPCエンドポイントは、ネットワークとリクエスト設定に応じて、最新、安全、確定済み、または過去のブロックの列挙データを返す場合があります。異なるブロック高で行った2つの呼び出しでは、供給量や所有者一覧が異なる可能性があります。最近転送されたNFTが、同期されていないデータソース間で異なる所有者のもとに表示される場合があります。整合性が重要な複数回の列挙では、アプリケーションは使用したブロック番号を記録してください。重要なシステムでは、複数ノードを比較するか、独立して検証したノードを運用できます。列挙機能はコレクション固有APIへの依存を減らしますが、RPCへの信頼に関する懸念をすべてなくすわけではありません。Enumerable拡張のメリット
この拡張は、現在のすべてのトークンIDを検出する標準的な方法を提供します。外部インデクサーに頼らず、別のスマートコントラクトから所有者のNFT保有状況を照会できます。現在の供給量を取得する標準関数を利用できます。小規模コレクション、オンチェーンゲーム、会員制システム、トークンを直接選択する必要があるアプリケーションを簡素化できます。プロジェクトのウェブサイトや非公開データベースが利用できなくなっても、基本的なNFT一覧を照会できます。Enumerable拡張の制約
ミント、転送、バーンのガス代が増加します。トークンの順序は安定しません。ページネーション、ソート、フィルタリング、保有者の列挙機能は組み込まれていません。完全な履歴ではなく、現在のトークンを報告します。圧縮バッチミントや独自の残高システムと互換性がない場合があります。大規模なオンチェーンループには、引き続きトランザクションのガス上限が適用されます。メタデータ、ロイヤリティ、価格、真正性、供給上限の保証も提供しません。プロジェクトが列挙機能を使うべきケース
スマートコントラクトがオンチェーンでトークンIDを直接検出する必要がある場合、列挙機能が役立つ可能性があります。追加の転送コストを許容できる小規模コレクションにも適しています。コントラクトのロジックで、プレイヤーのNFTからインデックス指定で1つを選ぶ必要があるゲームにも利用できます。オンチェーン処理で保有者の現在の会員NFTを調べる必要がある場合、会員制コントラクトにも活用できます。ただし、ループには上限を設け、より単純なマッピングやアプリケーション固有のインデックスの方が効率的かを検討してください。プロジェクトが列挙機能を避けるべきケース
大規模なNFTコレクションでは、すべてのミント、転送、バーンのコストを抑えるため、列挙機能を避ける場合があります。検出や検索機能がすべてオフチェーンのイベントインデクサーに依存している場合も、採用を避けることがあります。圧縮バッチミントシステムでは、標準的な列挙ストレージと効率的に連携しない所有権モデルが使われる場合があります。オンチェーンのトークン一覧を必要としないプロジェクトでは、恒久的なオンチェーンインデックスの費用に見合うメリットが少ない可能性があります。任意拡張はすべて必要だという思い込みではなく、実際のアプリケーション要件に基づいて判断してください。開発者向けの実装方法
開発者は、まず保守・レビューが継続されているERC-721 Enumerable実装を選ぶべきです。不変条件テストでは、
さらに、各所有者の列挙可能なトークン数が
ユーザーがEnumerable対応を確認する方法
まず、NFTコントラクトのアドレスとブロックチェーンネットワークを確認します。次に、
所有者の
Enumerable拡張でよくある間違い
ERC-721コントラクトはすべて列挙に対応していると思い込むこと。列挙インデックスを恒久的なトークンIDとして扱うこと。トークンIDが数値順またはミント順に並ぶと考えること。独自の
FAQ
暗号資産におけるEnumerable拡張とは?
通常、アプリケーションが現在のすべてのNFTトークンIDと、指定アドレスが所有するトークンIDを一覧表示できるようにする、ERC-721の任意拡張を指します。ERC-721にEnumerable拡張は必須ですか?
いいえ。NFTコントラクトは列挙機能なしでも、ERC-721基本規格に準拠できます。Enumerable拡張のインターフェースIDは?
ERC-165インターフェースIDは
この拡張で追加される関数は?
totalSupplyが返す値は?
コントラクトが追跡している、現在有効なNFTの数です。totalSupplyは最大供給可能数を示しますか?
いいえ。現在の供給量を示すもので、将来のミントが不可能であることを証明しません。tokenByIndexが返す値は?
指定した全体列挙インデックスにあるトークンIDです。tokenOfOwnerByIndexが返す値は?
指定アドレスが所有するトークンのうち、指定した所有者インデックスにあるトークンIDです。列挙インデックスは0から始まりますか?
はい。有効なインデックスは0から始まり、対象となる供給量または残高の1つ手前で終わります。列挙インデックスとトークンIDは同じですか?
いいえ。インデックスは一時的なリスト位置であり、トークンIDはコントラクト内でNFTを識別します。トークンIDは数値順に返されますか?
いいえ。規格は特定の列挙順序を要求していません。列挙順序は変わることがありますか?
はい。特にswap-and-popで削除する実装では、転送やバーンによってインデックス位置が変わる場合があります。NFTをバーンするとtotalSupplyは減りますか?
はい。適切に実装されたEnumerableコントラクトはバーンされたNFTを削除し、現在の総供給量を減らします。NFTの転送でtotalSupplyは変わりますか?
いいえ。通常の転送では所有者別の列挙は変わりますが、存在するNFTの数は変わりません。この拡張のコストが高い理由は?
ミント、転送、バーン時に、全体および所有者別のトークンインデックスを維持する追加ストレージ書き込みが必要だからです。列挙呼び出しは無料ですか?
オフチェーンのRPC読み取りではオンチェーンのガス代はかかりませんが、トランザクション中のスマートコントラクト呼び出しにはガスが必要です。コントラクトは列挙可能なNFTをすべてループ処理できますか?
試みることはできますが、上限のないオンチェーンループは、最終的にブロックガス上限を超える可能性があります。この拡張はページネーションを提供しますか?
いいえ。アプリケーションが選択したインデックス範囲を照会してページネーションを実装します。すべてのNFT保有者を一覧表示しますか?
いいえ。トークンIDを全体として、また既知の所有者について一覧表示しますが、所有者アドレス全体の一意な一覧は返しません。イベントインデックスで列挙機能を代替できますか?
はい。オフチェーンインデクサーはERC-721のTransferイベントから供給量と所有権を再構築できます。この拡張にはNFTメタデータが含まれますか?
いいえ。メタデータは別の任意ERC-721拡張で提供されます。列挙機能はNFTの真正性を証明しますか?
いいえ。誰でもEnumerableコントラクトをデプロイできるため、ネットワーク、コントラクトアドレス、発行者、権限を確認する必要があります。デプロイ後に列挙機能を追加できますか?
アップグレード可能なコントラクトなら追加できる場合がありますが、既存トークンを新しいインデックス構造へ安全に移行する必要があります。ERC721EnumerableはすべてのERC-721拡張と互換性がありますか?
いいえ。圧縮バッチミントや独自の残高実装は、標準的な列挙ストレージと競合する可能性があります。Enumerable拡張が最も役立つのはどんな場合ですか?
コントラクトやアプリケーションが、現在のトークン一覧または所有者のトークンIDに標準化されたオンチェーンアクセスを必要とする場合です。まとめ
Enumerable拡張は、標準化されたオンチェーンクエリによってNFTのトークンIDを検出可能にする、ERC-721の任意機能です。インターフェースIDは
関連コンテンツ
WhatsMiner M30S++
Web3ドメイン
Web3プロジェクト
ホット
現在、市場で大きな注目を集めているトレンドの暗号資産
トップ取引高
取引高が最も多い暗号資産

