Guide de développement du projet TON (1) : Créer un NFT sur la chaîne TON du point de vue du code source

Auteur : @Web3Mario (_mario)

Résumé : En reprenant l’article précédent sur l’introduction à la technologie TON, j’ai approfondi mes recherches dans la documentation officielle de TON ces derniers temps. J’ai l’impression que l’apprentissage est encore un peu difficile, car le contenu actuel ressemble davantage à une documentation de développement interne, ce qui n’est pas très convivial pour les nouveaux développeurs. C’est pourquoi j’ai essayé de réorganiser une série d’articles sur le développement de projets TON Chain en suivant ma propre trajectoire d’apprentissage, dans l’espoir que cela puisse aider les gens à démarrer rapidement dans le développement de DApp TON. N’hésitez pas à me corriger si j’ai commis des erreurs, nous pouvons apprendre ensemble.

Quelles sont les différences entre le développement de NFT sur EVM et sur TON Chain

L’émission d’un FT ou d’un NFT est généralement la demande la plus fondamentale pour les développeurs de DApp. C’est donc aussi ma porte d’entrée pour l’apprentissage. Commençons par comprendre les différences entre le développement d’un NFT dans la pile technologique EVM et sur la chaîne TON. Les NFT basés sur l’EVM choisissent généralement d’hériter de la norme ERC-721. Un NFT est un type d’actif cryptographique indivisible, chaque actif ayant son unicité et des caractéristiques exclusives. L’ERC-721 est un paradigme de développement commun pour ce type d’actif. Jetons un coup d’œil aux fonctions et informations qu’un contrat ERC721 typique doit implémenter. Le diagramme ci-dessous est une interface ERC721. Contrairement aux FT, dans l’interface de transfert, vous devez saisir l’ID du token à transférer plutôt que la quantité. Cet ID du token est la manifestation la plus fondamentale de l’unicité de l’actif NFT. Bien sûr, pour contenir plus de propriétés, il est courant d’enregistrer une métadonnée pour chaque ID de token, qui est un lien externe contenant d’autres données extensibles de ce NFT, telles que le lien vers une image PFP, certains noms de propriétés, etc.

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

Pour les développeurs familiers avec Solidity ou orientés objet, la mise en œuvre d’un contrat intelligent de ce type est facile, tant que les types de données nécessaires dans le contrat sont définis, tels que certaines relations de mappage clés et les logiques de modification correspondantes pour ces données en fonction des fonctionnalités requises, un NFT peut être réalisé.

Cependant, dans TON Chain, tout cela devient un peu différent, avec deux raisons fondamentales différentes :

  • Dans TON, le stockage des données est basé sur les Cellules, et les Cellules du même compte sont implémentées à l’aide d’un graphe acyclique orienté. Cela signifie que les données qui nécessitent une persistance illimitée ne peuvent pas croître indéfiniment car, pour un graphe acyclique orienté, la profondeur des données détermine le coût de la recherche. Lorsque la profondeur s’étend à l’infini, cela peut entraîner des coûts de recherche excessifs et provoquer un blocage du contrat.
  • Pour rechercher des performances élevées en termes de concurrence, TON a abandonné une architecture d’exécution séquentielle au profit d’un paradigme de développement spécialement conçu pour le parallélisme, le modèle d’acteur, pour reconstruire l’environnement d’exécution. Cela a un impact sur le fait que les contrats intelligents ne peuvent être appelés de manière asynchrone qu’en envoyant des messages internes. Notez que cela s’applique à la fois aux appels de types de modification d’état et de lecture seule. De plus, il est également important de réfléchir attentivement à la façon de gérer le rollback des données en cas d’échec de l’appel asynchrone.

Bien sûr, il y a eu une discussion détaillée sur les autres différences techniques dans l’article précédent, cette article se concentre sur le développement de contrats intelligents. Les deux principes de conception ci-dessus ont entraîné de grandes différences dans le développement de contrats intelligents entre TON et EVM. Comme nous le savons dans la discussion ci-dessus, un contrat NFT doit définir certaines relations de mappage pour stocker les données liées au NFT, c’est-à-dire le mappage pour stocker les relations avec les propriétaires, qui détermine la propriété du NFT. Les transferts modifient cette propriété. Étant donné que cela est théoriquement une structure de données sans limites, il convient d’éviter autant que possible. Par conséquent, il est recommandé par l’organisation de remplacer les structures de données sans limites par un paradigme de contrat principal-esclave et de gérer les données correspondant à chaque clé en créant des sous-contrats. Et gérer les paramètres globaux via le contrat principal ou aider à gérer l’interaction interne entre les sous-contrats.

Cela signifie également que les NFT dans TON doivent être conçus avec une architecture similaire, chaque NFT étant un sous-contrat autonome qui stocke des données exclusives telles que l’adresse du propriétaire, les métadonnées, etc., et est géré par un contrat principal pour les données globales telles que le nom NFT, le symbole, l’offre totale, etc.

Une fois l’architecture clairement définie, il est maintenant temps de répondre aux exigences des fonctions clés. Étant donné l’utilisation de ce contrat principal-secondaire, il est donc nécessaire de préciser quelles fonctions sont contenues dans le contrat principal et lesquelles sont contenues dans le contrat secondaire, ainsi que la manière dont les deux communiquent par des informations internes. En même temps, en cas d’erreur d’exécution, il est nécessaire de déterminer comment revenir aux données précédentes. En général, avant de développer un projet complexe de grande envergure, il est nécessaire de créer un diagramme de classes qui précise le flux d’informations entre eux et de réfléchir attentivement à la logique de retour en arrière en cas d’échec de l’appel interne. Bien sûr, bien que le développement NFT ci-dessus soit simple, une vérification similaire peut également être effectuée.

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

Apprendre à développer des contrats intelligents TON à partir du code source

TON a choisi de concevoir un langage de développement de contrats intelligents similaire au langage C, appelé Func. Nous allons maintenant apprendre à développer des contrats intelligents TON à partir du code source. J’ai choisi l’exemple NFT du document officiel de TON pour l’illustration. Les utilisateurs intéressés peuvent le consulter. Dans ce cas, un exemple simple de TON NFT est implémenté. Examinons la structure du contrat, qui se compose de deux contrats fonctionnels et de trois bibliothèques nécessaires.

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

Ces deux principaux contrats intelligents sont conçus selon les principes susmentionnés. Tout d’abord, examinons le code du contrat principal nft-collection :

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

Cela introduit le premier point de connaissance, comment stocker de manière persistante des données dans les contrats intelligents TON. Nous savons que dans Solidity, le stockage persistant des données est automatiquement géré par l’EVM en fonction du type de paramètre, et généralement, les variables d’état du contrat intelligent seront automatiquement stockées de manière persistante en fonction de la dernière valeur après l’exécution. Les développeurs n’ont pas besoin de se soucier de ce processus. Cependant, dans Func, la situation n’est pas la même, les développeurs doivent implémenter la logique de traitement correspondante eux-mêmes. Cette situation est un peu similaire à la nécessité pour C et C++ de considérer le processus de GC, mais les autres nouveaux langages de développement traitent généralement cette partie de la logique de manière automatisée. Regardons le code, tout d’abord, incluons certaines bibliothèques nécessaires, puis voyons la première fonction load_data utilisée pour lire les données stockées de manière persistante. Sa logique consiste d’abord à retourner la cellule de stockage persistant de contrat via get_data, notez que cela est implémenté par la bibliothèque standard stdlib.fc, et que certaines des fonctions qu’elle contient peuvent généralement être utilisées comme fonctions système.

Le type de retour de cette fonction est cell, qui est le type cellule dans TVM. Comme mentionné précédemment, nous savons déjà que toutes les données persistantes de la blockchain TON sont stockées dans l’arbre des cellules. Chaque cellule peut contenir jusqu’à 1023 bits de données arbitraires et jusqu’à quatre références à d’autres cellules. Les cellules sont utilisées comme mémoire dans TVM basé sur la pile. Les données stockées dans les cellules sont des données encodées de manière compacte, pour obtenir des données en clair spécifiques, il est nécessaire de convertir la cellule en un type appelé slice. La cellule peut être transformée en type slice via la fonction begin_parse, puis les données binaires et les références à d’autres cellules peuvent être chargées à partir du slice pour obtenir les données de la cellule. Notez que l’appel de la ligne 15 est une syntaxe sucrée pour une fonction dans une fonction, et les données correspondantes sont chargées dans l’ordre de persistance à la fin. Il est important de noter que ce processus est différent de Solidity et ne repose pas sur des appels de hachage, donc l’ordre des appels ne doit pas être modifié.

Dans la fonction save_data, la logique est similaire, sauf que c’est un processus inversé, ce qui introduit un nouveau point de connaissance, un nouveau type de constructeur, qui est le type de constructeur de cellule. Les bits de données et les références à d’autres cellules peuvent être stockés dans le constructeur, puis le constructeur peut être finalisé en une nouvelle cellule. Tout d’abord, créez un constructeur avec la fonction standard begin_cell, puis stockez les fonctions connexes en utilisant les fonctions de stockage connexes, en veillant à ce que l’ordre d’appel dans le texte précédent corresponde à l’ordre de stockage ici. Enfin, terminez la construction de la nouvelle cellule avec end_cell, à ce moment-là, cette cellule est gérée en mémoire, enfin, avec le set_data le plus externe, vous pouvez achever le stockage persistant de cette cellule.

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

Ensuite, regardons les fonctions commerciales connexes. Tout d’abord, il est nécessaire de présenter un point de connaissance, comment créer un nouveau contrat via un contrat, ce qui sera souvent utilisé dans l’architecture maître-esclave récemment présentée. Nous savons que dans TON, l’appel entre les contrats intelligents est réalisé en envoyant des messages internes. Cela est réalisé via une méthode appelée send_raw_message, où le premier paramètre est la cell encodée du message, et le deuxième paramètre est un drapeau utilisé pour indiquer la différence dans le mode d’exécution de la transaction. TON a configuré différentes manières d’envoyer des messages internes, actuellement avec 3 modes de message et 3 drapeaux de message. Un seul mode peut être combiné avec plusieurs (peut-être aucun) drapeaux pour obtenir le mode souhaité. La combinaison signifie simplement d’ajouter leurs valeurs pour les obtenir. Voici un tableau décrivant les modes et les drapeaux:

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

Alors, examinons la première fonction principale, deploy_nft_item, comme son nom l’indique, il s’agit d’une fonction utilisée pour créer ou plutôt pour réaliser une nouvelle instance NFT, après avoir encodé un msg, envoie_raw_message envoie ce contrat interne, et sélectionne le drapeau 1 comme indicateur d’envoi, ne prenant que les frais spécifiés dans le codage comme frais de gaz pour cette exécution. Après avoir lu ce qui précède, nous comprenons facilement que cette règle de codage devrait correspondre à la manière de créer un nouveau contrat intelligent. Voyons maintenant comment cela est mis en œuvre.

Regardons directement la ligne 51, les deux fonctions ci-dessus sont des fonctions auxiliaires utilisées pour générer les informations nécessaires au message, nous reviendrons donc plus tard pour voir que c’est un processus de codage pour créer un message interne pour un contrat intelligent, certains des chiffres au milieu sont en fait des indicateurs utilisés pour indiquer les besoins de ce message interne. Ici, nous devons introduire un nouveau point de connaissance, TON a choisi un langage binaire appelé TL-B pour décrire la manière dont les messages sont exécutés, et en fonction de différents indicateurs, pour réaliser certaines fonctionnalités spécifiques du message interne, les deux cas d’utilisation les plus évidents sont la création d’un nouveau contrat et l’appel de la fonction d’un contrat déjà déployé. La méthode de la ligne 51 correspond au premier cas, la création d’un nouveau contrat nft item, principalement défini par les lignes 55, 56, 57. Tout d’abord, la longue série de chiffres de la ligne 55 est une série d’indicateurs, notez que le premier argument de store_uint est une valeur, le deuxième est une longueur de bits, qui détermine que le message interne est la création d’un contrat. Les trois derniers indicateurs, et la valeur binaire correspondante est 111 (en décimal, c’est-à-dire 4+2+1), les deux premiers indiquent que le message sera accompagné de données StateInit, ces données sont le code source du nouveau contrat, ainsi que les données d’initialisation requises. Le dernier indicateur indique le transport du message interne, c’est-à-dire que l’on souhaite exécuter la logique correspondante et les paramètres nécessaires. C’est pourquoi vous verrez que dans le code de la ligne 66, ces trois bits de données ne sont pas définis, ce qui signifie qu’il s’agit d’un appel de fonction d’un contrat déjà déployé. Vous pouvez consulter ici les règles de codage spécifiques.

Donc, la règle de codage de StateInit correspond à la ligne de code 49, calculée par calculate_nft_item_state_init. Notez que le codage des données StateInit suit également une règle de codage TL-B établie, qui implique principalement deux parties: le code du nouveau contrat et les données d’initialisation. L’ordre de codage des données doit correspondre à l’ordre de stockage des cellules persistantes spécifiées par le nouveau contrat. À la ligne 36, on peut voir que les données d’initialisation comprennent item_index, similaire à tokenId dans ERC721, et l’adresse du contrat actuel retournée par la fonction standard my_address, c’est-à-dire collection_address. L’ordre de ces données correspond à la déclaration dans nft-item.

Le prochain point à aborder dans TON est que tous les contrats intelligents non générés peuvent précalculer leur adresse de génération, ce qui est similaire à la fonction create2 de Solidity. Dans TON, la génération d’une nouvelle adresse est composée de deux parties : le workchain ID et le hachage de stateinit sont concaténés ensemble. Le premier a déjà été expliqué précédemment, il doit être spécifié pour répondre à l’architecture de fractionnement infini de TON, et il est actuellement défini comme une valeur uniforme obtenue à partir de la fonction standard workchain. Le second est obtenu à partir de la fonction standard cell_hash. Par conséquent, dans cet exemple, calculate_nft_item_address est la fonction qui précalcule l’adresse du nouveau contrat. La valeur générée est ensuite encodée dans le message à la ligne 53 en tant qu’adresse de réception du message interne. nft_content correspond à l’appel d’initialisation du contrat créé, les détails de sa mise en œuvre seront expliqués dans le prochain article.

En ce qui concerne send_royalty_params, il doit répondre à un message interne d’une certaine demande de lecture. Dans la description précédente, nous avons souligné spécifiquement que les messages internes dans TON ne contiennent pas seulement des opérations qui peuvent modifier les données, mais que les opérations de lecture doivent également être mises en œuvre de cette manière. Par conséquent, ce contrat est une telle opération. Tout d’abord, il convient de noter que la ligne 67 représente le marqueur de la fonction de rappel pour l’appelant après la réponse à cette demande. La réponse est la donnée renvoyée, qui comprend l’indice de l’élément demandé et les données de redevance correspondantes.

Dans la suite, permettez-nous d’introduire un nouveau point de connaissance, TON a seulement deux points d’entrée unifiés pour les contrats intelligents, nommés recv_internal et recv_external, le premier est le point d’entrée unifié pour tous les messages internes, le second est le point d’entrée unifié pour tous les messages externes, les développeurs doivent, à l’intérieur de la fonction, répondre aux différentes demandes de manière similaire à un switch en fonction des différents indicateurs spécifiés par le message, ces indicateurs sont les marques de rappel de la fonction à la ligne 67 ci-dessus. Revenons à cet exemple, d’abord vérifier les espaces vides dans le message, puis analyser les informations dans le message. Tout d’abord, à la ligne 83, analyser et obtenir l’adresse de l’expéditeur, ce paramètre sera utilisé pour les vérifications de permission ultérieures, veuillez noter l’opérateur ~ ici, qui est un autre syntactic sugar. Nous ne l’expliquerons pas pour le moment. Ensuite, analyser le bit d’opération op, puis, en fonction du bit d’opération différent, traiter les demandes correspondantes. Cela implique l’appel de certaines fonctions susmentionnées en fonction de certaines logiques. Par exemple, répondre à une demande pour le paramètre de royauté, ou réaliser un nouveau minting de nft, et incrémenter l’index global.

Le prochain point de connaissance correspond à la ligne 108, et je pense que tout le monde peut comprendre la logique de traitement de cette fonction à travers son nom. Similaire à la fonction require dans Solidity, dans Func, une exception est levée via la fonction standard throw_unless, le premier paramètre étant le code d’erreur, le deuxième étant un booléen de vérification. Si le booléen est faux, une exception est levée, accompagnée du code d’erreur correspondant. Et à cette ligne, equal_slices est utilisé pour vérifier si l’adresse de l’expéditeur analysée précédemment est égale à l’adresse du propriétaire stockée de manière persistante dans ce contrat, pour effectuer une vérification d’autorisation.

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

Enfin, pour rendre la structure du code plus claire, commencez par une série de fonctions auxiliaires pour obtenir des informations persistantes, je ne vais pas les détailler ici, les développeurs peuvent se référer à cette structure pour développer leurs propres contrats intelligents.

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

Le développement de DApp dans l’écosystème TON est vraiment intéressant, avec des différences majeures par rapport au paradigme de développement d’EVM, donc je vais introduire comment développer des DApp dans TON Chain à travers une série d’articles. Apprenons ensemble et saisissons cette opportunité. Je vous invite également à interagir avec moi sur Twitter, à partager de nouvelles idées de DApp intéressantes et à développer ensemble.

TON-1.68%
Voir l'original
Cette page peut inclure du contenu de tiers fourni à des fins d'information uniquement. Gate ne garantit ni l'exactitude ni la validité de ces contenus, n’endosse pas les opinions exprimées, et ne fournit aucun conseil financier ou professionnel à travers ces informations. Voir la section Avertissement pour plus de détails.
  • Récompense
  • Commentaire
  • Reposter
  • Partager
Commentaire
0/400
Aucun commentaire
  • Épingler
Trader les cryptos partout et à tout moment
qrCode
Scan pour télécharger Gate app
Communauté
Français (Afrique)
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)