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:
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 erforderlich, 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 ist die obige NFT-Entwicklung einfach , kann aber auch eine ähnliche Überprüfung durchführen.
Lernen Sie, wie man TON-Smart-Contracts aus dem Quellcode entwickelt
Diese beiden Hauptfunktionsverträge sind nach den oben genannten Prinzipien gestaltet. Schauen wir uns zunächst den Code der NFT-Sammlung des Hauptvertrags an:
Dies führt den ersten Wissenspunkt ein, wie man TON Persistent verwendet Speicherung von Daten in Smart Contracts 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 Contracts 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, ähnlich wie C und C++ den GC-Prozess berücksichtigen müssen, aber andere neue Entwicklungssprachen automatisieren normalerweise diesen Teil der 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 dauerhaft gespeicherter Daten verwendet wird. Ihre Logik besteht darin, zunächst die persistente Vertragsspeicherzelle über get_data zurückzugeben Dies geschieht standardmäßig über die Bibliothek stdlib.fc. Einige 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 umgewandelt 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 und Verweise auf andere Zellen aus dem Slice abgerufen werden. Beachten Sie, dass die aufrufende Methode in Zeile 15 syntaktischer Zucker in einer Funktion ist, die die zweite Funktion direkt auf dem Rückgabewert der ersten Funktion aufruft. 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 end_cell verwendet, um den Aufbau der neuen Zelle abzuschließen. 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.
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 den Ausführungsmodus 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 ist unten angegeben:
Schauen wir uns also die erste Hauptfunktion an, „deploy_nft_item“, eine Funktion, die zum Erstellen oder Umwandeln neuer NFT-Instanzen nach der Codierung verwendet wird Senden Sie eine Nachricht, senden Sie den internen Vertrag über send_raw_message und wählen Sie das Sendeflag von Flag 1 aus. Als Gasgebühr für diese Ausführung wird nur die in der Codierung angegebene Gebühr verwendet. 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 In der Mitte werden auch einige Identifikationsbits verwendet, um die Anforderungen der internen Nachricht zu beschreiben. Der nächste Wissenspunkt wird hier eingeführt. TON wählt eine Binärsprache namens TL-B, um den Ausführungsmodus der Nachricht zu beschreiben Bits zum Implementieren interner Nachrichten für bestimmte spezifische Funktionen sind die beiden am einfachsten vorstellbaren Verwendungsszenarien 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 das entsprechende Das Binärwertbit ist 111 (dezimal ist 4+2+1), die ersten beiden geben an, 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 In der vorherigen Einführung wissen wir bereits, dass ersterer angegeben werden muss, um der TON-Infinite-Sharding-Architektur zu entsprechen. 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 ausdrücklich betont, dass die interne Nachricht in TON nicht nur Vorgänge enthält, die Daten ändern können, sondern auch Lesevorgänge. Nur Operationen müssen dies übergeben Es ist auf diese Weise implementiert, daher ist der Vertrag eine solche Operation. Zunächst ist zu beachten, dass Zeile 67 die Markierung der Rückruffunktion des Anforderers darstellt, nachdem er auf die Anfrage geantwortet hat Rufen Sie die zurückgegebenen Daten ab, bei denen es sich um den angeforderten Artikelindex und die entsprechenden Lizenzdaten handelt.
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 Nachrichten müssen Entwickler eine schalterähnliche Methode verwenden, um auf verschiedene Anfragen basierend auf verschiedenen Flag-Bits zu reagieren, die je nach Anforderung in der Funktion 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 prägen 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. Ähnlich wie bei der Anforderungsfunktion in Solidity werden Ausnahmen in Func über die Standardfunktion throw_unless ausgelöst Der zweite Schritt 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.
Um die Codestruktur klarer zu machen, wurde schließlich eine Reihe von Hilfsfunktionen entwickelt, die dabei helfen, Persistenzinformationen zu erhalten. Diese werden hier nicht vorgestellt. Entwickler können auf diese Struktur zurückgreifen, um ihre eigenen Smart Contracts zu entwickeln.
DApp-Entwicklung im TON-Ökosystem ist wirklich interessant und unterscheidet sich stark vom Entwicklungsparadigma von EVM, daher werde ich in einer Reihe von Artikeln vorstellen, wie man DApp in TON Chain entwickelt.
Das obige ist der detaillierte Inhalt vonSo 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!