ホームページ  >  記事  >  ソースコードの観点からTON Chain上にNFTを作成する方法

ソースコードの観点からTON Chain上にNFTを作成する方法

WBOY
WBOYオリジナル
2024-06-25 18:45:02678ブラウズ

EVMでのNFT開発とTON ChainでのNFT開発の違いは何ですか

通常、FTまたはNFTの発行はDApp開発者にとって最も基本的なニーズです。したがって、私はこれを学習の入り口としても使用します。まず、EVM テクノロジースタックでの NFT 開発と TON Chain の次の違いを理解しましょう。 EVM ベースの NFT は、多くの場合、ERC-721 標準を継承することを選択します。いわゆる NFT は、分割できないタイプの暗号化資産を指し、各資産は固有です。つまり、特定の排他的な特性を持っています。 ERC-721 は、このタイプの資産の一般的な開発パラダイムです。一般的な ERC721 契約で実装する必要がある機能と、どのような情報が記録されるかを見てみましょう。下の写真はERC721インターフェースです。 FT とは異なり、転送インターフェイスに入力する必要があるのは、金額ではなく、転送する tokenId であることがわかります。この tokenId は、NFT アセットの一意性の最も基本的な具体化でもあります。もちろん、より多くの属性を保持するために、通常、このメタデータは、NFT の他のスケーラブルなデータを保存する外部リンクです。 PFP イメージ、特定のプロパティの名前などへのリンクとして。

从源码角度看如何在TON Chain上创建一个NFT

Solidity に精通している開発者、またはオブジェクト指向に精通している開発者にとって、いくつかのキー マッピング関係など、コントラクトで必要なデータ型が定義されている限り、このようなスマート コントラクトを実装するのは簡単です。 NFTを実現するには、これらのデータに対応する変更ロジックを機能的に開発する必要があります。

ただし、これは TON Chain では同じではありません。その違いには主に 2 つの理由があります:

  • TON では、データのストレージは Cell に基づいており、同じアカウントの Cell はディレクテッドと を通じて実装されます。無向リング図を実現します。これは、有向非巡回グラフの場合、クエリ コストがデータの深さによって決定されるため、保存する必要があるデータが境界なく増加することがないことを意味します。深さが無限に広がると、クエリ コストが高くなりすぎて、次のような問題が発生する可能性があります。契約は行き詰まりの問題に陥っています。

  • 高い同時実行パフォーマンスを追求するために、TON はシリアル実行アーキテクチャを放棄し、代わりに並列処理に特化して設計された開発パラダイムであるアクター モデルを採用して実行環境を再構築しました。これには影響があります。また、スマート コントラクトは、いわゆる内部メッセージを送信することによってのみ非同期で呼び出すことができます。これは、状態変更タイプであっても、読み取り専用タイプの呼び出しであっても、この原則に従う必要があります。非同期呼び出しが失敗した場合にデータのロールバックを処理する方法を慎重に検討する必要があります。

    もちろん、他の技術的な違いについては前の記事で詳しく説明しましたので、この記事ではスマートコントラクトの開発に焦点を当てたいと考えていますので、説明しません。上記の 2 つの設計原則は、TON と EVM でのスマート コントラクト開発に大きな違いをもたらします。最初の議論では、NFT 関連データを保存するには、NFT コントラクトでいくつかのマッピング関係、つまりマッピングを定義する必要があることがわかりました。それらの中で最も重要なのは所有者です。このマッピングには、特定の tokenID に対応する NFT 所有者アドレスのマッピング関係が保存され、これによって NFT の所有権が変更されます。これは理論上無制限になり得るデータ構造であるため、可能な限り回避する必要があります。したがって、無制限のデータ構造の存在をシャーディングの標準として使用することが公式に推奨されています。つまり、同様のデータ ストレージ要件がある場合は、マスター/スレーブ コントラクト パラダイムが代わりに使用され、各キーに対応するデータはサブコントラクトを作成することによって管理されます。また、メイン コントラクトを通じてグローバル パラメーターを管理したり、サブコントラクト間の内部情報のやり取りの処理を支援したりできます。

    これは、TONのNFTも同様のアーキテクチャを使用して設計する必要があることを意味します。各NFTは、所有者のアドレス、メタデータなどの排他的なデータを保存し、メインコントラクトを通じて管理されます。 NFT名、シンボル、総供給量などのグローバルデータ

    アーキテクチャを明確にしたら、次はコアとなる機能要件を解決する必要があります。このマスタースレーブ契約方式を採用しているため、どの機能をメインコントラクトが担うのか、どの機能をサブコントラクトが担うのかを明確にする必要があります。コントラクトとサブコントラクトがどの機能を実行するか、サブコントラクトがどの機能を実行するか、それらの間の通信にどのような内部情報が使用されるか、実行エラーが発生した場合に以前のデータをロールバックする方法。通常、複雑な大規模プロジェクトを開発する前に、クラス図を渡して相互間の情報の流れを明確にし、内部呼び出しが失敗した後のロールバックロジックを慎重に検討する必要があります。 もちろん、上記のNFT開発は単純です。ですが、同様の検証を行うこともできます。

    从源码角度看如何在TON Chain上创建一个NFT

    ソース コードから TON スマート コントラクトの開発方法を学びましょう

    TON はスマート コントラクト開発言語として Func という C 風の静的型付け言語を設計することを選択しました。次に、ソース コードから開発方法を学びましょうTON スマート コントラクトについては、TON 公式ドキュメントにある NFT の例を選択して紹介しました。興味のある友人は自分で確認してください。この場合、単純な TON NFT の例が実装されています。コントラクト構造を見てみましょう。コントラクト構造は 2 つの機能コントラクトと 3 つの必要なライブラリに分かれています。

    从源码角度看如何在TON Chain上创建一个NFT

    これら 2 つの主要な機能コントラクトは、上記の原則に従って設計されています。まず、メイン コントラクト nft-collection のコードを見てみましょう:

    从源码角度看如何在TON Chain上创建一个NFT

    これは、TON Persistent の使用方法という最初の知識ポイントを紹介します。スマート コントラクトでのデータの保存 通常、スマート コントラクトの状態変数は、実行後の最新の値に従って自動的に保存されることがわかっています。ストレージ、開発者はこのプロセスを考慮する必要はありません。しかし、これは Func には当てはまりません。開発者は対応する処理ロジックを自分で実装する必要があります。この状況は、C および C++ が GC プロセスを考慮する必要があるのと似ていますが、他の新しい開発言語では通常、ロジックのこの部分が自動化されます。 。コードを見てみましょう。まず、必要なライブラリをいくつか紹介します。次に、最初の関数load_dataが永続的に保存されたデータを読み取るために使用されていることがわかります。そのロジックは、最初にget_dataを通じて永続的なコントラクトストレージセルを返すことです。これはライブラリ stdlib.fc によって実装された標準によって行われ、通常、関数の一部はシステム関数として使用できます。

    この関数の戻り値の型は cell で、TVM のセル型です。前回の紹介で、TON ブロックチェーン内のすべての永続データがセル ツリーに保存されていることはすでにわかりました。各セルには、最大 1023 ビットの任意のデータと、他のセルへの最大 4 つの参照があります。セルはスタックベースの TVM のメモリとして使用されます。セルに格納されるのは、コンパクトに暗号化されたデータであり、特定の平文データを取得するには、セルをスライスと呼ばれる型に変換する必要があります。 begin_parse 関数を使用してセルをスライス タイプに変換し、スライスからデータ ビットと他のセルへの参照をロードすることでセル内のデータを取得できます。 15 行目の呼び出しメソッドは、最初の関数の戻り値で 2 番目の関数を直接呼び出す関数内の糖衣構文であることに注意してください。そして最後に、データの永続化順序に従って、対応するデータを順番にロードします。このプロセスは Solidity とは異なり、ハッシュマップに基づいて呼び出されないため、呼び出しの順序を間違えることはできないことに注意してください。

    save_data 関数では、ロジックは似ていますが、これが逆のプロセスである点が異なり、次の知識ポイントであるセル ビルダーのタイプである新しいタイプ ビルダーが導入されます。データ ビットと他のセルへの参照はビルダーに保存でき、その後、それを新しいセルに完成させることができます。まず、標準関数 begin_cell を使用してビルダーを作成し、次にストア関連関数を使用して関連関数を保存します。上記の呼び出し順序は、ここでの保存順序と一致している必要があることに注意してください。最後に、end_cell を使用して新しいセルの構築を完了します。このとき、セルはメモリ内で管理され、最後に、最も外側の set_data を通じてセルの永続的な保存が完了します。

    从源码角度看如何在TON Chain上创建一个NFT

    次に、ビジネス関連の機能を見てみましょう。まず、次の知識ポイントである、マスター/スレーブ アーキテクチャで頻繁に使用される、コントラクトを通じて新しいコントラクトを作成する方法を紹介する必要があります。紹介された。 TON では、スマート コントラクト間の呼び出しが内部メッセージの送信によって実装されることがわかっています。これは、send_raw_message というメッセージを通じて実現されます。最初のパラメータはメッセージでエンコードされたセルであり、2 番目のパラメータはトランザクションの実行方法の違いを示すために使用される識別ビットであることに注意してください。異なる内部設定が設定されます。 TON には現在、メッセージ送信の実行モードとして 3 つのメッセージ モードと 3 つのメッセージ フラグがあります。単一のモードを複数の (おそらくなしの) フラグと組み合わせて、目的のモードを取得できます。単に結合するとは、それらの値の合計を埋めることを意味します。モードとフラグの説明表は以下のとおりです:

    从源码角度看如何在TON Chain上创建一个NFT

    それでは、最初のメイン関数、deploy_nft_item を見てみましょう。名前が示すように、これはエンコード後のいくつかの操作の後、新しい NFT インスタンスを作成またはキャストするために使用される関数です。メッセージを送信し、send_raw_message を通じて内部コントラクトを送信し、フラグ 1 の送信フラグを選択します。エンコーディングで指定された料金のみが、この実行のガス料金として使用されます。上記の導入後、このコーディング ルールは新しいスマート コントラクトを作成する方法に対応する必要があることが容易に理解できます。それでは、それがどのように実装されているかを見てみましょう。

    51行目を直接見てみましょう。上記の2つの関数は、メッセージに必要な情報を生成するために使用される補助関数です。これは、スマートコントラクトの内部メッセージを作成するためのエンコードプロセスです。中央は実際には、内部メッセージの要件を記述するために使用されるいくつかの識別ビットでもあります。次の知識ポイントは、メッセージの実行モードを記述するために TL-B と呼ばれるバイナリ言語を選択し、異なるフラグを設定します。特定の関数の内部メッセージを実装する場合、最も簡単に考えられる 2 つの使用シナリオは、新しいコントラクトの作成とデプロイされたコントラクト関数呼び出しです。 51行目のメソッドは前者に相当し、新たなnftアイテムコントラクトを作成するもので、主に55行目、56行目、57行目で規定されています。まず、55 行目の大きな一連の数字は一連の識別ビットです。store_uint の最初の入力パラメータは値で、2 番目は内部メッセージがコントラクトによって作成されたかどうかを決定するビット長であることに注意してください。 、最後の 3 つのマーキング ビット、および対応するバイナリ値ビットは 111 (10 進数は 4+2+1) で、最初の 2 つは、メッセージに StateInit データが伴うことを示します。このデータは、ソース コードです。新しい契約と初期化に必要なデータ。後者のフラグ ビットは、内部メッセージの添付ファイルを示します。つまり、関連するロジックと必要なパラメーターが実行されることが予想されます。したがって、コードの 66 行目では 3 桁のデータが設定されていないことがわかります。これは、デプロイされたコントラクトへの関数呼び出しを示しています。詳細なコーディング規則はここで参照できます。

    StateInit のエンコード ルールは、calculate_nft_item_state_init によって計算された 49 行のコードに対応します。stateinit データのエンコードには、いくつかのフラグ ビットに加えて、主に 2 つの部分が含まれることに注意してください。新しい契約と初期化されたデータ。データのエンコード順序は、新しい契約で指定された永続セルの格納順序と一致している必要があります。 36 行目にあるように、初期化データには、ERC721 の tokenId に似た item_index と、標準関数 my_address によって返される現在のコントラクト アドレス (collection_address) が含まれています。このデータの順序は、次の宣言と一致しています。 nftアイテム。

    次の知識ポイントは、TON では、すべての未生成のスマート コントラクトが生成されたアドレスを事前に計算できるということです。これは、TON の新しいアドレスの生成は 2 つの部分で構成されます。前回の紹介で、前者は TON 無限シャーディング アーキテクチャに対応するために指定する必要があることがわかっています。標準関数ワークチェーンから取得します。後者は標準関数 cell_hash によって取得されます。この例に戻りますが、calculate_nft_item_address は、新しい契約アドレスを事前に計算する関数です。そして、生成された値を内部メッセージの受信アドレスとして 53 行目のメッセージにエンコードします。 nft_content は、作成されたコントラクトへの初期化呼び出しに対応します。具体的な実装については、次の記事で紹介します。

    send_royalty_params に関しては、読み取り専用リクエストの内部メッセージに対する応答である必要があります。前の紹介では、TON の内部メッセージにはデータを変更する可能性のある操作だけでなく、読み取りも含まれていることを特に強調しました。これを渡す必要があるのはオペレーションのみです。 このように実装されているため、コントラクトはこのようなオペレーションになります。 まず、67 行目はリクエストに応答した後のリクエスターのコールバック関数のマークを表していることに注意してください。返されたデータ (要求された商品インデックスと対応するロイヤルティ データ) を取得します。

    次のナレッジ ポイントを紹介します。TON には、recv_internal と recv_external という名前の統合された入口が 2 つだけあります。前者はすべての内部メッセージの統合呼び出し入口であり、後者はすべての外部メッセージの統合呼び出し入口です。メッセージを使用する場合、開発者は、要件に応じて関数内のメッセージで指定されたさまざまなフラグ ビットに基づいて、スイッチのようなメソッドを使用してさまざまなリクエストに応答する必要があります。ここでのフラグ ビットは、上記の 67 行目のコールバック関数フラグです。この例に戻ります。最初にメッセージの空きチェックを実行し、次にメッセージ内の情報をそれぞれ解析して、sender_address を取得します。このパラメータは以降の権限チェックに使用されることに注意してください。ここは別の構文シュガーに属します。ここでは詳しく説明しません。次に、op 操作のフラグ ビットが解析され、対応するリクエストがさまざまなフラグ ビットに従って処理されます。このうち、上記の関数はそれぞれ一定のロジックに従って呼び出されます。たとえば、ロイヤルティ パラメータのリクエストに応答したり、新しい nft を作成してグローバル インデックスをインクリメントしたりします。

    次のナレッジポイントは 108 行目です。この関数の処理ロジックも、Solidity の require 関数と同様に、標準関数 throw_unless を通じてスローされます。 2 番目の方法は、ビットのブール値を確認することです。ビットが false の場合は、エラー コードとともに例外がスローされます。この行では、equal_slicesを用いて上記で解析したsender_addressがコントラクトの永続ストレージのowner_addressと等しいかどうかを判定し、許可判定を行っています。

    从源码角度看如何在TON Chain上创建一个NFT

    最後に、コード構造をより明確にするために、永続性情報を取得するのに役立つ一連の補助関数が開発されました。開発者はこの構造を参照して独自のスマート コントラクトを開発できます。

    从源码角度看如何在TON Chain上创建一个NFT

    TONエコシステムでのDApp開発は非常に興味深く、EVMの開発パラダイムとは大きく異なるため、一連の記事を通じてTON ChainでDAppを開発する方法を紹介します。

    以上がソースコードの観点からTON Chain上にNFTを作成する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。