Heim >web3.0 >Tutorial zur TON-Projektentwicklung (1): So erstellen Sie ein NFT auf der TON-Kette aus Quellcode-Perspektive

Tutorial zur TON-Projektentwicklung (1): So erstellen Sie ein NFT auf der TON-Kette aus Quellcode-Perspektive

WBOY
WBOYOriginal
2024-06-25 07:51:291200Durchsuche

Zusammenfassung: Nach dem vorherigen Artikel über die Einführung der TON-Technologie habe ich die offiziellen TON-Entwicklungsdokumente in diesem Zeitraum eingehend studiert. Ich habe das Gefühl, dass es immer noch einige Hindernisse für das Lernen gibt Entwicklungsdokument, das für Neulinge nicht sehr freundlich ist, daher versuche ich, eine Reihe von Artikeln über die TON-Chain-Projektentwicklung basierend auf meinem eigenen Lernverlauf zusammenzustellen. Ich hoffe, dass es für alle schnell hilfreich ist begann mit der TON DApp-Entwicklung. Sollten sich beim Schreiben Fehler eingeschlichen haben, können Sie mich gerne korrigieren und gemeinsam lernen.

Was sind die Unterschiede zwischen der Entwicklung von NFT in EVM und der Entwicklung von NFT auf TON Chain?

Die Ausstellung eines FT oder NFT ist normalerweise das grundlegendste Bedürfnis für DApp-Entwickler. Deshalb nutze ich dies auch als Einstiegspunkt zum Lernen. Lassen Sie uns zunächst die folgenden Unterschiede zwischen der Entwicklung eines NFT im EVM-Technologie-Stack und in der TON-Kette verstehen. EVM-basierte NFTs entscheiden sich normalerweise dafür, den ERC-721-Standard zu erben. Das sogenannte NFT bezieht sich auf eine unteilbare Art von Kryptowährungs-Asset, und jedes Asset ist einzigartig, das heißt, es weist bestimmte exklusive Eigenschaften auf. ERC-721 ist ein gängiges Entwicklungsparadigma für diese Art von Vermögenswerten. Schauen wir uns an, welche Funktionen ein gemeinsamer ERC721-Vertrag implementieren muss und welche Informationen aufgezeichnet werden. Das Bild unten zeigt eine ERC721-Schnittstelle. Es ist ersichtlich, dass im Gegensatz zu FT nicht der Betrag, sondern die zu übertragende TokenId in die Übertragungsschnittstelle eingegeben werden muss. Diese Token-ID ist auch die grundlegendste Manifestation der Einzigartigkeit von NFT-Assets. Um mehr Attribute zu tragen, werden normalerweise Metadaten für jede Token-ID aufgezeichnet. Diese Metadaten sind ein externer Link, der andere skalierbare Daten des NFT speichert als Links zu PFP-Bildern, bestimmten Attributnamen usw.

TON项目开发教程(一):源码角度看如何在TON Chain上创建一个NFT

Für Entwickler, die mit Solidity oder objektorientiert vertraut sind, ist es einfach, einen solchen intelligenten Vertrag zu implementieren, solange die im Vertrag erforderlichen Datentypen definiert sind, z. B. einige wichtige Zuordnungsbeziehungen Basierend auf den erforderlichen Anforderungen ist es erforderlich, die entsprechende Modifikationslogik für diese Daten funktional zu entwickeln, um ein NFT zu realisieren.

In der TON-Kette ist dies jedoch nicht dasselbe. Es gibt zwei Hauptgründe für den Unterschied:

  • In TON basiert die Datenspeicherung auf der Zelle, und die Zelle desselben Kontos wird durch gerichtete azyklische Zahlen erreicht . Dies bedeutet, dass die zu speichernden Daten nicht unbegrenzt wachsen können, da bei einem gerichteten azyklischen Diagramm die Abfragekosten durch die Tiefe der Daten bestimmt werden. Wenn sich die Tiefe ins Unendliche erstreckt, können die Abfragekosten zu hoch sein Der Vertrag steckt in einem Deadlock-Problem fest.
  • Um eine hohe Parallelitätsleistung zu erzielen, hat TON die serielle Ausführungsarchitektur aufgegeben und stattdessen ein speziell für Parallelität entwickeltes Entwicklungsparadigma, das Actor-Modell, übernommen, um die Ausführungsumgebung zu rekonstruieren. Dies hat Auswirkungen. Smart Contracts können nur asynchron aufgerufen werden, indem sogenannte interne Nachrichten gesendet werden. Beachten Sie, dass dieses Prinzip auch befolgt werden muss, unabhängig davon, ob es sich um einen Statusänderungstyp oder einen schreibgeschützten Typ handelt Es muss sorgfältig überlegt werden, wie mit einem Daten-Rollback umgegangen wird, wenn ein asynchroner Aufruf fehlschlägt.

Natürlich wurden im vorherigen Artikel weitere technische Unterschiede ausführlich besprochen. Dieser Artikel konzentriert sich auf die Entwicklung intelligenter Verträge und wird daher nicht behandelt. Die beiden oben genannten Designprinzipien machen einen großen Unterschied zwischen der Entwicklung intelligenter Verträge und EVM in TON. In der ersten Diskussion wissen wir, dass ein NFT-Vertrag einige Mapping-Beziehungen, also Mapping, definieren muss, um NFT-bezogene Daten zu speichern. Die wichtigste davon ist Eigentümer. Diese Zuordnung speichert die Zuordnungsbeziehung der Eigentümeradresse des NFT, die einer bestimmten Token-ID entspricht, die den Besitz des NFT bestimmt. Die Übertragung ist eine Änderung des Besitzes. Da es sich hierbei um eine Datenstruktur handelt, die theoretisch unbegrenzt sein kann, muss sie so weit wie möglich vermieden werden. Daher wird offiziell empfohlen, die Existenz unbegrenzter Datenstrukturen als Standard für das Sharding zu verwenden. Das heißt, wenn ähnliche Anforderungen an die Datenspeicherung bestehen, wird stattdessen das Master-Slave-Vertragsparadigma verwendet und die jedem Schlüssel entsprechenden Daten werden durch die Erstellung von Unterverträgen verwaltet. Und verwalten Sie globale Parameter über den Hauptvertrag oder helfen Sie bei der Abwicklung der internen Informationsinteraktion zwischen Unterverträgen.

Das bedeutet, dass auch NFTs in TON mit einer ähnlichen Architektur gestaltet werden müssen. Jeder NFT ist ein unabhängiger Untervertrag, der exklusive Daten wie Eigentümeradresse, Metadaten usw. speichert und über einen Hauptvertrag verwaltet wird globale Daten wie NFT-Name, Symbol, Gesamtangebot usw.

Nach der Klärung der Architektur besteht der nächste Schritt darin, die grundlegenden Funktionsanforderungen zu lösen. Da diese Master-Slave-Vertragsmethode übernommen wird, muss geklärt werden, welche Funktionen vom Hauptvertrag und welche von den Unterverträgen übernommen werden. Welche internen Informationen werden für die Kommunikation zwischen ihnen verwendet und wie werden die vorherigen Daten zurückgesetzt, wenn ein Ausführungsfehler auftritt? Normalerweise ist es vor der Entwicklung eines komplexen Großprojekts notwendig, ein Klassendiagramm zu übergeben und den Informationsfluss untereinander zu klären und sorgfältig über die Rollback-Logik nachzudenken, nachdem der interne Aufruf fehlgeschlagen ist. Natürlich, obwohl die oben erwähnte NFT fehlschlägt Die Entwicklung ist einfach und kann auch durchgeführt werden Führen Sie eine ähnliche Überprüfung durch.

TON项目开发教程(一):源码角度看如何在TON Chain上创建一个NFT

Lernen Sie, TON-Smart-Verträge aus dem Quellcode zu entwickeln

TON hat sich dafür entschieden, eine C-ähnliche, statisch typisierte Sprache namens Func als Smart-Contract-Entwicklungssprache zu entwerfen. Lassen Sie uns dann lernen, wie Sie TON-Smart-Verträge aus dem Quellcode entwickeln. Ich habe das NFT-Beispiel in der offiziellen Dokumentation von TON ausgewählt, um es vorzustellen. Interessierte Freunde können es selbst ausprobieren. In diesem Fall wird ein einfaches TON NFT-Beispiel implementiert. Werfen wir einen Blick auf die Vertragsstruktur, die in zwei funktionale Verträge und drei notwendige Bibliotheken unterteilt ist.

TON项目开发教程(一):源码角度看如何在TON Chain上创建一个NFT

Die beiden Hauptfunktionsverträge sind nach den oben genannten Prinzipien gestaltet. Schauen wir uns zunächst den Code der NFT-Sammlung des Hauptvertrags an:

TON项目开发教程(一):源码角度看如何在TON Chain上创建一个NFT

Dies führt den ersten Wissenspunkt ein, wie man persistente Speicherung durchführt von Daten in TON-Smart-Verträgen Wir wissen, dass die dauerhafte Speicherung von Daten in Solidity automatisch von der EVM basierend auf der Art der Parameter erfolgt. Normalerweise werden die Statusvariablen des Smart-Vertrags nach der Ausführung automatisch beibehalten . Speicher müssen Entwickler diesen Prozess nicht berücksichtigen. Dies ist jedoch in Func nicht der Fall. Entwickler müssen die entsprechende Verarbeitungslogik selbst implementieren. Diese Situation ähnelt in gewisser Weise der Notwendigkeit, den GC-Prozess in C und C++ zu berücksichtigen, aber andere neue Entwicklungssprachen automatisieren diesen Teil normalerweise Logik. Werfen wir einen Blick auf den Code. Zuerst stellen wir einige erforderliche Bibliotheken vor und sehen dann, dass die erste Funktion „load_data“ zum Lesen der dauerhaft gespeicherten Daten verwendet wird. Ihre Logik besteht darin, zunächst die persistente Vertragsspeicherzelle über get_data zurückzugeben Dies wird standardmäßig durch die Bibliothek stdlib.fc implementiert, einige dieser Funktionen können normalerweise als Systemfunktionen verwendet werden.

Der Rückgabewerttyp dieser Funktion ist Zelle, der Zelltyp in TVM. In der vorherigen Einführung wissen wir bereits, dass alle persistenten Daten in der TON-Blockchain im Zellbaum gespeichert werden. Jede Zelle verfügt über bis zu 1023 Bits beliebiger Daten und bis zu vier Verweise auf andere Zellen. Zellen werden im stapelbasierten TVM als Speicher verwendet. In der Zelle werden kompakt codierte Daten gespeichert. Um die spezifischen Klartextdaten zu erhalten, muss die Zelle in einen Typ namens Slice konvertiert werden. Die Zelle kann über die Funktion begin_parse in den Slice-Typ konvertiert werden. Anschließend können die Daten in der Zelle durch Laden der Datenbits aus dem Slice und Verweise auf andere Zellen abgerufen werden. Beachten Sie, dass diese Aufrufmethode in Zeile 15 syntaktischer Zucker in func ist und Sie die zweite Funktion direkt aufrufen können, die den Wert der ersten Funktion zurückgibt. Laden Sie schließlich die entsprechenden Daten in der Reihenfolge der Datenpersistenzreihenfolge. Beachten Sie, dass sich dieser Prozess von Solidity unterscheidet und nicht auf der Grundlage einer Hashmap aufgerufen wird, sodass die Reihenfolge der Aufrufe nicht durcheinander gebracht werden kann.

In der Funktion save_data ist die Logik ähnlich, mit der Ausnahme, dass es sich um einen umgekehrten Prozess handelt, der den nächsten Wissenspunkt einführt, einen neuen Typ-Builder, bei dem es sich um den Typ des Zell-Builders handelt. Datenbits und Verweise auf andere Zellen können in Buildern gespeichert werden, die dann in neue Zellen finalisiert werden können. Erstellen Sie zunächst einen Builder über die Standardfunktion begin_cell und speichern Sie nacheinander verwandte Funktionen über die speicherbezogenen Funktionen. Beachten Sie, dass die oben genannte Aufrufreihenfolge mit der Speicherreihenfolge hier übereinstimmen muss. Schließlich wird der Aufbau der neuen Zelle über end_cell abgeschlossen. Zu diesem Zeitpunkt wird die Zelle im Speicher verwaltet. Schließlich kann die dauerhafte Speicherung der Zelle über die äußersten set_data abgeschlossen werden.

TON项目开发教程(一):源码角度看如何在TON Chain上创建一个NFT

Als nächstes werfen wir einen Blick auf geschäftsbezogene Funktionen. Zunächst müssen wir den nächsten Wissenspunkt vorstellen, wie man einen neuen Vertrag durch einen Vertrag erstellt, der gerade in der Master-Slave-Architektur häufig verwendet wird eingeführt. Wir wissen, dass in TON Anrufe zwischen Smart Contracts durch das Senden interner Nachrichten implementiert werden. Dies wird durch eine Nachricht namens send_raw_message erreicht. Beachten Sie, dass der erste Parameter die nachrichtencodierte Zelle ist und der zweite Parameter das Identifikationsbit ist, das verwendet wird, um den Unterschied in der Ausführungsmethode der Transaktion anzuzeigen in TON gibt es derzeit 3 ​​Nachrichtenmodi und 3 Nachrichtenflags für die Ausführungsmethode des Nachrichtenversands. Ein einzelner Modus kann mit mehreren (möglicherweise keinem) Flags kombiniert werden, um den gewünschten Modus zu erhalten. Das Kombinieren bedeutet lediglich, die Summe ihrer Werte einzutragen. Die Beschreibungstabelle der Modi und Flags finden Sie unten:

TON项目开发教程(一):源码角度看如何在TON Chain上创建一个NFT

Werfen wir also einen Blick auf die erste Hauptfunktion, „deploy_nft_item“, eine Funktion, die zum Erstellen oder Umwandeln einer neuen NFT-Instanz verwendet wird. Nach einigen Vorgängen zum Codieren einer Nachricht wird der interne Vertrag über send_raw_message gesendet und ausgewählt Das Sendeflag von Flag 1 verwendet für diese Ausführung nur die in der Kodierung angegebene Gebühr als Gasgebühr. Nach der obigen Einführung können wir leicht erkennen, dass diese Codierungsregel der Art und Weise entsprechen sollte, einen neuen Smart Contract zu erstellen. Werfen wir also einen Blick auf die Umsetzung.

Schauen wir uns direkt Zeile 51 an. Die beiden oben genannten Funktionen sind Hilfsfunktionen, die zum Generieren der für die Nachricht erforderlichen Informationen verwendet werden. Wir werden uns daher später mit diesem Codierungsprozess zum Erstellen interner Nachrichten von Smart Contracts befassen Tatsächlich handelt es sich auch um einige Identifikationsbits, die zur Erläuterung der Anforderungen der internen Nachricht verwendet werden. Der nächste Wissenspunkt wird hier eingeführt. TON wählte eine Binärsprache namens TL-B, um die Ausführungsmethode der Nachricht und verschiedene Flag-Bits zu beschreiben werden entsprechend festgelegt: Um interne Nachrichten für bestimmte spezifische Funktionen zu implementieren, fallen mir am häufigsten zwei Verwendungsszenarien ein: die Erstellung neuer Verträge und bereitgestellte Vertragsfunktionsaufrufe. Die Methode in Zeile 51 entspricht der ersteren und erstellt einen neuen NFT-Artikelvertrag, der hauptsächlich in den Zeilen 55, 56 und 57 angegeben wird. Erstens handelt es sich bei der großen Zahlenreihe in Zeile 55 um eine Reihe von Identifikationsbits. Beachten Sie, dass der erste Eingabeparameter von store_uint der Wert und der zweite die Bitlänge ist, die bestimmt, ob die interne Nachricht durch den Vertrag erstellt wird , die letzten drei Markierungsbits und der entsprechende Binärwert sind 111 (4+2+1 in Dezimalzahl), wobei die ersten beiden angeben, dass die Nachricht von StateInit-Daten begleitet wird. Diese Daten sind der Quellcode des neuen Vertrag und die für die Initialisierung erforderlichen Daten. Das letztgenannte Flag-Bit zeigt den internen Nachrichtenanhang an, d. h. es wird erwartet, dass die relevante Logik und die erforderlichen Parameter ausgeführt werden. Daher werden Sie feststellen, dass in Zeile 66 des Codes keine dreistelligen Daten festgelegt sind, was auf einen Funktionsaufruf für den bereitgestellten Vertrag hinweist. Detaillierte Kodierungsregeln finden Sie hier.

Dann entsprechen die Codierungsregeln von StateInit 49 Codezeilen, berechnet durch berechne_nft_item_state_init. Beachten Sie, dass die Codierung der Stateinit-Daten neben einigen Flag-Bits hauptsächlich zwei Teile davon umfasst neuer Vertrag. Code und initialisierte Daten. Die Codierungsreihenfolge der Daten muss mit der im neuen Vertrag festgelegten Speicherreihenfolge der Persistenzzellen übereinstimmen. Wie Sie in Zeile 36 sehen können, umfassen die Initialisierungsdaten item_index, der der tokenId in ERC721 ähnelt, und die aktuelle Vertragsadresse, die von der Standardfunktion my_address zurückgegeben wird, nämlich collection_address. Die Reihenfolge dieser Daten stimmt mit der Deklaration in überein NFT-Artikel.

Der nächste Wissenspunkt ist, dass in TON alle nicht generierten Smart Contracts ihre generierten Adressen vorab berechnen können. Dies ähnelt der Funktion „create2“ in Solidity. Die Generierung neuer Adressen in TON besteht aus zwei Teilen gespleißt mit dem Hash-Wert von stateinit. Ersteres muss angegeben werden, um der TON-Infinite-Sharding-Architektur zu entsprechen. Es handelt sich derzeit um einen einheitlichen Wert. Erhalten aus der Standardfunktions-Workchain. Letzteres wird durch die Standardfunktion cell_hash ermittelt. Zurück zu diesem Beispiel: berechne_nft_item_address ist eine Funktion, die die neue Vertragsadresse vorab berechnet. Und kodieren Sie den generierten Wert in der Nachricht in Zeile 53 als Empfangsadresse der internen Nachricht. nft_content entspricht dem Initialisierungsaufruf des erstellten Vertrags. Die spezifische Implementierung wird im nächsten Artikel vorgestellt.

Send_royalty_params muss eine Antwort auf die interne Nachricht einer schreibgeschützten Anfrage sein. In der vorherigen Einführung haben wir besonders betont, dass die interne Nachricht in TON nicht nur Vorgänge enthält, die Daten ändern können, sondern auch den Lesevorgang -Nur-Operation muss übergeben werden Dies ist in gewisser Weise implementiert, daher ist der Vertrag eine solche Operation. Zunächst ist zu beachten, dass Zeile 67 die Markierung der Rückruffunktion des Anforderers angibt, nachdem er auf die Anfrage geantwortet hat und es werden die Daten zurückgegeben, nämlich der angeforderte Artikelindex und die entsprechenden Lizenzdaten.

Lassen Sie uns den nächsten Wissenspunkt vorstellen. Es gibt nur zwei einheitliche Eingänge für intelligente Verträge mit den Namen recv_internal und recv_external. Ersteres ist der einheitliche Aufrufeingang für alle internen Nachrichten, und letzterer ist der einheitliche Aufrufeingang für alle externen Für Nachrichten müssen Entwickler eine schalterähnliche Methode verwenden, um auf verschiedene Anforderungen basierend auf den verschiedenen Flag-Bits zu reagieren, die von der Nachricht innerhalb der Funktion entsprechend den Anforderungen angegeben werden. Das Flag-Bit ist hier das Callback-Funktions-Flag in Zeile 67. Zurück zu diesem Beispiel: Führen Sie zunächst eine Leerstellenprüfung für die Nachricht durch und analysieren Sie dann die Informationen in Zeile 83, um die sender_address zu erhalten. Beachten Sie, dass der ~-Operator verwendet wird Hier gehört Zucker zu einer anderen Syntax. Ich werde hier nicht näher darauf eingehen. Als nächstes werden die OP-Operations-Flag-Bits analysiert und dann werden die entsprechenden Anforderungen entsprechend den verschiedenen Flag-Bits verarbeitet. Unter diesen werden die oben genannten Funktionen jeweils nach einer bestimmten Logik aufgerufen. Reagieren Sie beispielsweise auf eine Anfrage nach dem Lizenzgebührenparameter oder erstellen Sie einen neuen NFT und erhöhen Sie den globalen Index.

Der nächste Wissenspunkt entspricht Zeile 108. Ich denke, Sie können die Verarbeitungslogik dieser Funktion auch kennen, indem Sie sie benennen. Sie ähnelt der Anforderungsfunktion in Solidity. Ausnahmen werden in Func über die Standardfunktion throw_unless ausgelöst Der Parameter ist ein Fehlercode, der zweite besteht darin, den booleschen Wert des Bits zu überprüfen. Wenn das Bit falsch ist, wird eine Ausnahme mit dem Fehlercode ausgelöst. In dieser Zeile wird equal_slices verwendet, um zu bestimmen, ob die oben analysierte sender_address mit derowner_address des dauerhaften Speichers des Vertrags übereinstimmt, und es wird eine Berechtigungsbeurteilung vorgenommen.

TON项目开发教程(一):源码角度看如何在TON Chain上创建一个NFT

Um die Codestruktur klarer zu machen, wurde schließlich eine Reihe von Hilfsfunktionen entwickelt, die dabei helfen, Persistenzinformationen zu erhalten. Entwickler können sich auf diese Struktur beziehen, um ihre eigenen Smart Contracts zu entwickeln.

TON项目开发教程(一):源码角度看如何在TON Chain上创建一个NFT

DApp-Entwicklung im TON-Ökosystem ist wirklich interessant. Sie unterscheidet sich stark vom Entwicklungsparadigma von EVM, daher werde ich in einer Reihe von Artikeln vorstellen, wie man DApp in der TON-Kette entwickelt. Lernen Sie gemeinsam mit allen und nutzen Sie diese Welle an Möglichkeiten. Sie können auch gerne mit mir auf Twitter interagieren, um neue und interessante Dapp-Ideen zu entwickeln und diese gemeinsam weiterzuentwickeln.

Das obige ist der detaillierte Inhalt vonTutorial zur TON-Projektentwicklung (1): So erstellen Sie ein NFT auf der TON-Kette aus Quellcode-Perspektive. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn