Following the previous article on TON technology, I have delved into the official TON development documentation recently. It seems a bit challenging to learn, as the current content appears to be more like internal development documentation, which is not very friendly to new developers. Therefore, I am trying to organize a series of articles on TON Chain project development based on my own learning trajectory, hoping to provide some help for everyone to quickly get started with TON DApp development. Feel free to point out any mistakes in the writing, and let’s learn together.
Quelles sont les différences entre le développement de NFT sur EVM et le développement de NFT sur TON Chain
Émettre un FT ou un NFT est généralement la demande la plus fondamentale pour les développeurs de DApp. C’est donc 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 choisiront généralement d’hériter de la norme ERC-721. Les NFT, qui désignent un type d’actif cryptographique indivisible, ont chacun une unicité avec des caractéristiques exclusives. ERC-721 est un paradigme de développement commun pour ce type d’actifs. Regardons quelles fonctions un contrat ERC 721 typique doit implémenter et quelles informations il doit enregistrer. Le diagramme ci-dessous représente une interface ERC 721. On peut voir que, contrairement aux FT, l’interface de transfert nécessite de saisir l’identifiant unique de l’actif à transférer au lieu de la quantité. Cet identifiant est la manifestation la plus fondamentale de l’unicité de l’actif NFT. Bien sûr, pour contenir plus d’attributs, il est courant d’enregistrer une métadonnée pour chaque identifiant, qui est un lien externe contenant d’autres données extensibles de l’NFT, telles qu’un lien vers une image PFP, certains noms d’attributs, etc.
Pour les développeurs familiers avec Solidity ou orientés objet, implémenter un tel contrat intelligent est facile. Il suffit de définir les types de données requis dans le contrat, tels que des relations de mappage clés, et de développer la logique de modification correspondante pour ces données en fonction des fonctionnalités requises, afin de créer un NFT.
Cependant, dans TON Chain, tout cela devient un peu différent, avec deux raisons principales à l’origine de ces différences :
Dans TON, le stockage des données est basé sur les Cellules, et les Cellules du même compte sont mises en œuvre à l’aide d’un graphe acyclique orienté. Cela signifie que les données nécessitant une persistance illimitée ne peuvent pas croître de manière illimitée, car dans un tel graphe acyclique orienté, la profondeur des données détermine le coût de la requête. Après une extension infinie de la profondeur, il est possible que le coût de la requête devienne trop élevé, entraînant ainsi un problème de blocage du contrat intelligent.
Pour rechercher des performances élevées en termes de concurrence, TON a abandonné l’architecture d’exécution séquentielle et adopté un paradigme de développement conçu spécifiquement pour le parallélisme, le modèle d’acteur, pour reconstruire l’environnement d’exécution. Cela a entraîné une conséquence : 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 modification d’état et aux appels en lecture seule. De plus, il est également nécessaire de réfléchir attentivement à la manière 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. Cet article se concentre sur le développement de contrats intelligents, donc nous n’allons pas les aborder. Les deux principes de conception ci-dessus ont entraîné une grande différence dans le développement de contrats intelligents entre TON et EVM. Dans l’exposé initial, nous savons qu’un contrat NFT doit définir certaines relations de mappage pour stocker les données liées au NFT, c’est-à-dire une correspondance pour stocker les adresses des propriétaires des NFT correspondant à un certain tokenID, déterminant ainsi la propriété du NFT, un transfert étant une modification de cette propriété. Étant donné que cela est théoriquement une structure de données sans limite, il est nécessaire de l’éviter autant que possible. Par conséquent, il est recommandé d’utiliser l’existence de structures de données sans limite comme critère de fragmentation. Cela signifie que lorsque des besoins de stockage similaires se présentent, il est préférable de les remplacer par le paradigme des contrats maîtres-esclaves, en gérant les données correspondantes à chaque clé par la création de sous-contrats. Le contrat principal gère les paramètres globaux ou aide à traiter les informations internes 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 indépendant, stockant des données exclusives telles que l’adresse du propriétaire, les métadonnées, etc., et gérant les données globales via un contrat principal, telles que le nom du NFT, le symbole, le total de l’offre, etc.
Une fois que l’architecture a été définie, il est nécessaire de répondre aux besoins des fonctionnalités principales. Étant donné l’utilisation de ce contrat maître-esclave, il est important de préciser quelles fonctionnalités sont prises en charge par le contrat maître et quelles fonctionnalités sont prises en charge par le contrat enfant, ainsi que la manière dont les informations internes sont communiquées entre les deux. De plus, il est nécessaire de définir la logique de rollback des données en cas d’erreur d’exécution. Avant de développer des projets complexes à grande échelle, il est généralement nécessaire de créer un diagramme de classes et de clarifier les flux d’informations entre les différentes parties, tout en réfléchissant attentivement à la logique de rollback en cas de défaillance des appels internes. Bien sûr, bien que le développement de NFT mentionné ci-dessus soit simple, une validation similaire peut également être effectuée.
Apprendre à développer des contrats intelligents TON à partir du code source
TON a choisi de concevoir un langage de programmation statiquement typé similaire au langage C, appelé Func, pour le développement des contrats intelligents. Voyons maintenant comment développer un contrat intelligent TON à partir du code source. J’ai choisi de présenter l’exemple de NFT du document officiel de TON. Les camarades intéressés peuvent le consulter par eux-mêmes. Dans ce cas, un exemple simple de TON NFT a été implémenté. Regardons la structure du contrat, qui se compose de deux contrats fonctionnels et de trois bibliothèques nécessaires.
Ces deux contrats intelligents principaux sont conçus selon les principes susmentionnés. Commençons par examiner le code du contrat principal nft-collection :
Cela introduit le premier point de connaissance, comment stocker de manière persistante les données dans le contrat intelligent TON. Nous savons que dans Solidity, le stockage persistant des données est automatiquement traité par l’EVM en fonction du type de paramètre. En général, les variables d’état du contrat intelligent seront automatiquement stockées de manière persistante après l’exécution en fonction de la dernière valeur, et les développeurs n’ont pas besoin de considérer ce processus. Cependant, dans Func, ce n’est pas le cas. Les développeurs doivent implémenter eux-mêmes la logique de traitement correspondante. Cette situation est un peu similaire à celle de C et C++, qui doivent prendre en compte le processus de collecte des déchets, mais d’autres nouveaux langages de développement traitent généralement cette partie de la logique de manière automatisée. Examinons le code. Tout d’abord, importez certaines bibliothèques requises, puis voyons la première fonction load_data utilisée pour lire les données stockées de manière persistante. Sa logique est de d’abord retourner la cellule de stockage persistante du contrat via get_data, notez que cela est implémenté par la bibliothèque standard stdlib.fc, et que certaines de ses fonctions peuvent généralement être considérées comme des fonctions système à utiliser.
Le type de retour de cette fonction est un cell, qui est un type cellulaire dans TVM. Comme nous l’avons déjà mentionné précédemment, toutes les données persistantes de la blockchain TON sont stockées dans un arbre de cellules. Chaque cellule peut contenir jusqu’à 1023 bits de données arbitraires et jusqu’à quatre références vers d’autres cellules. Les cellules sont utilisées comme mémoire dans le TVM basé sur la pile. Les données stockées dans une cellule sont encodées de manière compacte, et pour obtenir les données en clair spécifiques, il est nécessaire de convertir la cellule en un type appelé slice. Une cellule peut être convertie en un slice en utilisant la fonction begin_parse, puis les données et les références vers d’autres cellules peuvent être chargées à partir du slice pour obtenir les données de la cellule. Notez que l’appel de la méthode à la ligne 15 est une syntaxe de sucre syntaxique dans une fonction, qui permet d’appeler directement la deuxième fonction de la valeur de retour de la première fonction. Enfin, les données correspondantes sont chargées dans l’ordre de persistance des données. Notez 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, mais c’est un processus inverse, ce qui introduit un nouveau point de connaissance, un nouveau type de constructeur, qui est le type de constructeur de cellule. Les données binaires et les références à d’autres cellules peuvent être stockées dans le constructeur, puis le constructeur peut être finalisé en une nouvelle cellule. Tout d’abord, créez un constructeur à l’aide de la fonction standard begin_cell, puis stockez les fonctions associées à l’aide des fonctions de stockage associées. Notez que l’ordre d’appel dans le texte précédent doit correspondre à l’ordre de stockage ici. Enfin, terminez la construction de la nouvelle cellule à l’aide de end_cell, à ce stade, cette cellule est gérée en mémoire, enfin, à l’aide de set_data de la couche externe, vous pouvez effectuer le stockage persistant de cette cellule.
Ensuite, regardons les fonctions liées aux opérations commerciales. 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 précédemment 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 fonction appelée send_raw_message, notez que le premier paramètre est la cell encodée du message, le deuxième paramètre est un drapeau indiquant la différence dans le mode d’exécution de la transaction. TON a défini différentes manières d’envoyer des messages internes, actuellement il existe 3 modes de messages et 3 drapeaux de messages. Un seul mode peut être combiné avec plusieurs (peut-être aucun) drapeaux pour obtenir le mode souhaité. La combinaison signifie simplement d’additionner leurs valeurs et de les remplir. Le tableau ci-dessous décrit les modes et les drapeaux:
Alors, regardons la première fonction principale, deploy_nft_item, comme son nom l’indique, il s’agit d’une fonction pour créer ou fabriquer une nouvelle instance de NFT, après avoir codé un message, l’envoyer via send_raw_message à ce contrat interne, en sélectionnant le drapeau 1 pour l’envoi, ne prenant que les frais spécifiés dans le codage comme frais de gaz pour cette exécution. Après avoir lu le paragraphe précédent, il est facile de comprendre que cette règle de codage devrait correspondre à la manière de créer un nouveau smart contract. Voyons maintenant comment cela est concrètement mis en œuvre.
Regardons directement la ligne 51, les deux fonctions ci-dessus sont des fonctions d’assistance pour générer les informations nécessaires au message, nous regarderons plus tard, ceci est un processus de codage pour créer un message interne pour le smart contract, certains des nombres au milieu sont en fait des indicateurs pour indiquer les besoins de ce message interne, nous introduirons ici un autre 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 mettre en œuvre certaines fonctionnalités spécifiques des messages internes en fonction de différents indicateurs, les deux scénarios d’utilisation les plus évidents sont la création de nouveaux contrats et l’appel de fonctions de contrats déjà déployés. La méthode à la ligne 51 correspond à la première, la création d’un nouveau contrat d’élément nft, principalement défini par les lignes 55, 56, 57. Tout d’abord, la longue chaîne de chiffres à la ligne 55 est une série d’indicateurs, notez que le premier paramètre de store_uint est une valeur numérique, le deuxième est la longueur en bits, qui détermine que les trois derniers indicateurs sont pour la création de contrat, avec la valeur binaire correspondante à 111 (en décimal, 4+2+1), les deux premiers indiquent que le message sera accompagné de données StateInit, ces données correspondent au code source du nouveau contrat, ainsi que les données nécessaires à l’initialisation. Le dernier indicateur indique le chargement du message interne, indiquant ainsi l’exécution de la logique associée et les paramètres nécessaires. C’est pourquoi vous verrez qu’à la ligne 66, ces trois indicateurs ne sont pas définis, ce qui signifie qu’il s’agit d’un appel de fonction à un contrat déjà déployé. Les règles de codage spécifiques peuvent être consultées ici.
Alors, la règle de codage de StateInit correspond à la ligne de code 49, calculée via calculate_nft_item_state_init. Notez que le codage des données stateinit suit également une règle de codage TL-B établie, à l’exception de certains indicateurs, principalement les nouvelles parties code et data d’un contrat initialisé. 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 incluent item_index, similaire à tokenId dans ERC 721, et l’adresse de contrat actuelle 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 à noter dans TON est que tous les contrats intelligents non encore générés peuvent calculer à l’avance leur adresse de génération. Ceci est similaire à la fonction create 2 de Solidity. Dans TON, la génération d’une nouvelle adresse est composée de deux parties : le bit d’identification de workchain et la concaténation de la valeur de hachage de stateinit. Le premier a déjà été expliqué dans la présentation précédente, il doit être spécifié pour correspondre à l’architecture de sharding infini de TON, et actuellement, il est 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 calcule préalablement l’adresse d’un 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éé, dont les détails seront expliqués dans le prochain article.
En ce qui concerne send_royalty_params, il doit s’agir du message interne correspondant à une requête en lecture seule, dans l’introduction précédente, nous avons délibérément souligné qu’en TON, le message interne contient non seulement des opérations susceptibles de modifier les données, mais aussi des opérations en lecture seule doivent être implémentées de cette manière, de sorte que le contrat est une telle opération, tout d’abord, il convient de noter que la ligne 67 représente la marque de la fonction pullback du demandeur après avoir répondu à la demande, qui est la donnée retournée, qui est l’élément de la demande et les données de redevances correspondantes.
Ensuite, introduisons le point de connaissance suivant, dans TON smart contracts il n’y a que deux entrées unifiées, nommées recv_internal et recv_external, où la première est l’entrée d’appel unifiée de tous les messages internes, et la seconde est l’entrée d’appel unifiée de tous les messages externes 67 lignes de balisage de fonction de pullback. Pour en revenir à l’exemple, effectuez d’abord une vérification de short bits sur le message, analysez les informations contenues dans le message séparément après le passage et analysez d’abord l’expéditeur_address à la ligne 83, ce paramètre sera utilisé pour les vérifications d’autorisation ultérieures, notez que l’opérateur ~ appartient ici à un autre sucre syntaxique. Je ne m’étendrai pas là-dessus ici. Ensuite, les bits de balise d’opération OP sont analysés, puis les demandes correspondantes sont traitées séparément en fonction des différents bits de balise. C’est-à-dire que les fonctions ci-dessus sont appelées séparément selon une certaine logique. Par exemple, en réponse à une demande de paramètre de redevance, ou lors de la monting d’un nouveau NFT et de l’auto-incrémentation de l’index global.
Le prochain point de connaissance correspond à 108 lignes, et je suis sûr que vous pouvez connaître la logique de traitement de cette fonction par son nom. De manière similaire à la fonction require de Solidity, dans Func, un standard de fonction throw_unless est utilisé pour lever une exception. Le premier argument est le code d’erreur, le second est la valeur booléenne de vérification de bits. Si le bit est faux, l’exception sera levée avec le code d’erreur correspondant. Dans cette ligne, equal_slices est utilisé pour vérifier si l’adresse de l’expéditeur résolue ci-dessus est égale à l’adresse de propriétaire stockée en permanence dans ce contrat, afin de vérifier les autorisations.
Enfin, pour rendre la structure du code plus claire, commencez par une série de fonctions auxiliaires pour obtenir des informations persistantes. Ici, nous n’allons pas nous étendre sur les détails, les développeurs peuvent utiliser cette structure comme référence pour développer leurs propres smart contracts.
Le développement DApp de l’écosystème TON est vraiment intéressant, avec des différences importantes par rapport au paradigme de développement EVM, donc j’écrirai une série d’articles sur la façon de développer des DApp sur TON Chain. Apprenons ensemble et saisissons cette opportunité. Je vous invite également à interagir avec moi sur Twitter pour échanger des idées de nouvelles DApp intéressantes et développer ensemble.
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.
Guide de développement du projet TON (1) : Comment créer un NFT sur la chaîne TON du point de vue du code source
Auteur original: @Web3 Mario (_mario)
Following the previous article on TON technology, I have delved into the official TON development documentation recently. It seems a bit challenging to learn, as the current content appears to be more like internal development documentation, which is not very friendly to new developers. Therefore, I am trying to organize a series of articles on TON Chain project development based on my own learning trajectory, hoping to provide some help for everyone to quickly get started with TON DApp development. Feel free to point out any mistakes in the writing, and let’s learn together.
Quelles sont les différences entre le développement de NFT sur EVM et le développement de NFT sur TON Chain
Émettre un FT ou un NFT est généralement la demande la plus fondamentale pour les développeurs de DApp. C’est donc 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 choisiront généralement d’hériter de la norme ERC-721. Les NFT, qui désignent un type d’actif cryptographique indivisible, ont chacun une unicité avec des caractéristiques exclusives. ERC-721 est un paradigme de développement commun pour ce type d’actifs. Regardons quelles fonctions un contrat ERC 721 typique doit implémenter et quelles informations il doit enregistrer. Le diagramme ci-dessous représente une interface ERC 721. On peut voir que, contrairement aux FT, l’interface de transfert nécessite de saisir l’identifiant unique de l’actif à transférer au lieu de la quantité. Cet identifiant est la manifestation la plus fondamentale de l’unicité de l’actif NFT. Bien sûr, pour contenir plus d’attributs, il est courant d’enregistrer une métadonnée pour chaque identifiant, qui est un lien externe contenant d’autres données extensibles de l’NFT, telles qu’un lien vers une image PFP, certains noms d’attributs, etc.
Pour les développeurs familiers avec Solidity ou orientés objet, implémenter un tel contrat intelligent est facile. Il suffit de définir les types de données requis dans le contrat, tels que des relations de mappage clés, et de développer la logique de modification correspondante pour ces données en fonction des fonctionnalités requises, afin de créer un NFT.
Cependant, dans TON Chain, tout cela devient un peu différent, avec deux raisons principales à l’origine de ces différences :
Bien sûr, il y a eu une discussion détaillée sur les autres différences techniques dans l’article précédent. Cet article se concentre sur le développement de contrats intelligents, donc nous n’allons pas les aborder. Les deux principes de conception ci-dessus ont entraîné une grande différence dans le développement de contrats intelligents entre TON et EVM. Dans l’exposé initial, nous savons qu’un contrat NFT doit définir certaines relations de mappage pour stocker les données liées au NFT, c’est-à-dire une correspondance pour stocker les adresses des propriétaires des NFT correspondant à un certain tokenID, déterminant ainsi la propriété du NFT, un transfert étant une modification de cette propriété. Étant donné que cela est théoriquement une structure de données sans limite, il est nécessaire de l’éviter autant que possible. Par conséquent, il est recommandé d’utiliser l’existence de structures de données sans limite comme critère de fragmentation. Cela signifie que lorsque des besoins de stockage similaires se présentent, il est préférable de les remplacer par le paradigme des contrats maîtres-esclaves, en gérant les données correspondantes à chaque clé par la création de sous-contrats. Le contrat principal gère les paramètres globaux ou aide à traiter les informations internes 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 indépendant, stockant des données exclusives telles que l’adresse du propriétaire, les métadonnées, etc., et gérant les données globales via un contrat principal, telles que le nom du NFT, le symbole, le total de l’offre, etc.
Une fois que l’architecture a été définie, il est nécessaire de répondre aux besoins des fonctionnalités principales. Étant donné l’utilisation de ce contrat maître-esclave, il est important de préciser quelles fonctionnalités sont prises en charge par le contrat maître et quelles fonctionnalités sont prises en charge par le contrat enfant, ainsi que la manière dont les informations internes sont communiquées entre les deux. De plus, il est nécessaire de définir la logique de rollback des données en cas d’erreur d’exécution. Avant de développer des projets complexes à grande échelle, il est généralement nécessaire de créer un diagramme de classes et de clarifier les flux d’informations entre les différentes parties, tout en réfléchissant attentivement à la logique de rollback en cas de défaillance des appels internes. Bien sûr, bien que le développement de NFT mentionné ci-dessus soit simple, une validation similaire peut également être effectuée.
Apprendre à développer des contrats intelligents TON à partir du code source
TON a choisi de concevoir un langage de programmation statiquement typé similaire au langage C, appelé Func, pour le développement des contrats intelligents. Voyons maintenant comment développer un contrat intelligent TON à partir du code source. J’ai choisi de présenter l’exemple de NFT du document officiel de TON. Les camarades intéressés peuvent le consulter par eux-mêmes. Dans ce cas, un exemple simple de TON NFT a été implémenté. Regardons la structure du contrat, qui se compose de deux contrats fonctionnels et de trois bibliothèques nécessaires.
Ces deux contrats intelligents principaux sont conçus selon les principes susmentionnés. Commençons par examiner le code du contrat principal nft-collection :
Cela introduit le premier point de connaissance, comment stocker de manière persistante les données dans le contrat intelligent TON. Nous savons que dans Solidity, le stockage persistant des données est automatiquement traité par l’EVM en fonction du type de paramètre. En général, les variables d’état du contrat intelligent seront automatiquement stockées de manière persistante après l’exécution en fonction de la dernière valeur, et les développeurs n’ont pas besoin de considérer ce processus. Cependant, dans Func, ce n’est pas le cas. Les développeurs doivent implémenter eux-mêmes la logique de traitement correspondante. Cette situation est un peu similaire à celle de C et C++, qui doivent prendre en compte le processus de collecte des déchets, mais d’autres nouveaux langages de développement traitent généralement cette partie de la logique de manière automatisée. Examinons le code. Tout d’abord, importez certaines bibliothèques requises, puis voyons la première fonction load_data utilisée pour lire les données stockées de manière persistante. Sa logique est de d’abord retourner la cellule de stockage persistante du contrat via get_data, notez que cela est implémenté par la bibliothèque standard stdlib.fc, et que certaines de ses fonctions peuvent généralement être considérées comme des fonctions système à utiliser.
Le type de retour de cette fonction est un cell, qui est un type cellulaire dans TVM. Comme nous l’avons déjà mentionné précédemment, toutes les données persistantes de la blockchain TON sont stockées dans un arbre de cellules. Chaque cellule peut contenir jusqu’à 1023 bits de données arbitraires et jusqu’à quatre références vers d’autres cellules. Les cellules sont utilisées comme mémoire dans le TVM basé sur la pile. Les données stockées dans une cellule sont encodées de manière compacte, et pour obtenir les données en clair spécifiques, il est nécessaire de convertir la cellule en un type appelé slice. Une cellule peut être convertie en un slice en utilisant la fonction begin_parse, puis les données et les références vers d’autres cellules peuvent être chargées à partir du slice pour obtenir les données de la cellule. Notez que l’appel de la méthode à la ligne 15 est une syntaxe de sucre syntaxique dans une fonction, qui permet d’appeler directement la deuxième fonction de la valeur de retour de la première fonction. Enfin, les données correspondantes sont chargées dans l’ordre de persistance des données. Notez 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, mais c’est un processus inverse, ce qui introduit un nouveau point de connaissance, un nouveau type de constructeur, qui est le type de constructeur de cellule. Les données binaires et les références à d’autres cellules peuvent être stockées dans le constructeur, puis le constructeur peut être finalisé en une nouvelle cellule. Tout d’abord, créez un constructeur à l’aide de la fonction standard begin_cell, puis stockez les fonctions associées à l’aide des fonctions de stockage associées. Notez que l’ordre d’appel dans le texte précédent doit correspondre à l’ordre de stockage ici. Enfin, terminez la construction de la nouvelle cellule à l’aide de end_cell, à ce stade, cette cellule est gérée en mémoire, enfin, à l’aide de set_data de la couche externe, vous pouvez effectuer le stockage persistant de cette cellule.
Ensuite, regardons les fonctions liées aux opérations commerciales. 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 précédemment 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 fonction appelée send_raw_message, notez que le premier paramètre est la cell encodée du message, le deuxième paramètre est un drapeau indiquant la différence dans le mode d’exécution de la transaction. TON a défini différentes manières d’envoyer des messages internes, actuellement il existe 3 modes de messages et 3 drapeaux de messages. Un seul mode peut être combiné avec plusieurs (peut-être aucun) drapeaux pour obtenir le mode souhaité. La combinaison signifie simplement d’additionner leurs valeurs et de les remplir. Le tableau ci-dessous décrit les modes et les drapeaux:
Alors, regardons la première fonction principale, deploy_nft_item, comme son nom l’indique, il s’agit d’une fonction pour créer ou fabriquer une nouvelle instance de NFT, après avoir codé un message, l’envoyer via send_raw_message à ce contrat interne, en sélectionnant le drapeau 1 pour l’envoi, ne prenant que les frais spécifiés dans le codage comme frais de gaz pour cette exécution. Après avoir lu le paragraphe précédent, il est facile de comprendre que cette règle de codage devrait correspondre à la manière de créer un nouveau smart contract. Voyons maintenant comment cela est concrètement mis en œuvre.
Regardons directement la ligne 51, les deux fonctions ci-dessus sont des fonctions d’assistance pour générer les informations nécessaires au message, nous regarderons plus tard, ceci est un processus de codage pour créer un message interne pour le smart contract, certains des nombres au milieu sont en fait des indicateurs pour indiquer les besoins de ce message interne, nous introduirons ici un autre 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 mettre en œuvre certaines fonctionnalités spécifiques des messages internes en fonction de différents indicateurs, les deux scénarios d’utilisation les plus évidents sont la création de nouveaux contrats et l’appel de fonctions de contrats déjà déployés. La méthode à la ligne 51 correspond à la première, la création d’un nouveau contrat d’élément nft, principalement défini par les lignes 55, 56, 57. Tout d’abord, la longue chaîne de chiffres à la ligne 55 est une série d’indicateurs, notez que le premier paramètre de store_uint est une valeur numérique, le deuxième est la longueur en bits, qui détermine que les trois derniers indicateurs sont pour la création de contrat, avec la valeur binaire correspondante à 111 (en décimal, 4+2+1), les deux premiers indiquent que le message sera accompagné de données StateInit, ces données correspondent au code source du nouveau contrat, ainsi que les données nécessaires à l’initialisation. Le dernier indicateur indique le chargement du message interne, indiquant ainsi l’exécution de la logique associée et les paramètres nécessaires. C’est pourquoi vous verrez qu’à la ligne 66, ces trois indicateurs ne sont pas définis, ce qui signifie qu’il s’agit d’un appel de fonction à un contrat déjà déployé. Les règles de codage spécifiques peuvent être consultées ici.
Alors, la règle de codage de StateInit correspond à la ligne de code 49, calculée via calculate_nft_item_state_init. Notez que le codage des données stateinit suit également une règle de codage TL-B établie, à l’exception de certains indicateurs, principalement les nouvelles parties code et data d’un contrat initialisé. 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 incluent item_index, similaire à tokenId dans ERC 721, et l’adresse de contrat actuelle 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 à noter dans TON est que tous les contrats intelligents non encore générés peuvent calculer à l’avance leur adresse de génération. Ceci est similaire à la fonction create 2 de Solidity. Dans TON, la génération d’une nouvelle adresse est composée de deux parties : le bit d’identification de workchain et la concaténation de la valeur de hachage de stateinit. Le premier a déjà été expliqué dans la présentation précédente, il doit être spécifié pour correspondre à l’architecture de sharding infini de TON, et actuellement, il est 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 calcule préalablement l’adresse d’un 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éé, dont les détails seront expliqués dans le prochain article.
En ce qui concerne send_royalty_params, il doit s’agir du message interne correspondant à une requête en lecture seule, dans l’introduction précédente, nous avons délibérément souligné qu’en TON, le message interne contient non seulement des opérations susceptibles de modifier les données, mais aussi des opérations en lecture seule doivent être implémentées de cette manière, de sorte que le contrat est une telle opération, tout d’abord, il convient de noter que la ligne 67 représente la marque de la fonction pullback du demandeur après avoir répondu à la demande, qui est la donnée retournée, qui est l’élément de la demande et les données de redevances correspondantes.
Ensuite, introduisons le point de connaissance suivant, dans TON smart contracts il n’y a que deux entrées unifiées, nommées recv_internal et recv_external, où la première est l’entrée d’appel unifiée de tous les messages internes, et la seconde est l’entrée d’appel unifiée de tous les messages externes 67 lignes de balisage de fonction de pullback. Pour en revenir à l’exemple, effectuez d’abord une vérification de short bits sur le message, analysez les informations contenues dans le message séparément après le passage et analysez d’abord l’expéditeur_address à la ligne 83, ce paramètre sera utilisé pour les vérifications d’autorisation ultérieures, notez que l’opérateur ~ appartient ici à un autre sucre syntaxique. Je ne m’étendrai pas là-dessus ici. Ensuite, les bits de balise d’opération OP sont analysés, puis les demandes correspondantes sont traitées séparément en fonction des différents bits de balise. C’est-à-dire que les fonctions ci-dessus sont appelées séparément selon une certaine logique. Par exemple, en réponse à une demande de paramètre de redevance, ou lors de la monting d’un nouveau NFT et de l’auto-incrémentation de l’index global.
Le prochain point de connaissance correspond à 108 lignes, et je suis sûr que vous pouvez connaître la logique de traitement de cette fonction par son nom. De manière similaire à la fonction require de Solidity, dans Func, un standard de fonction throw_unless est utilisé pour lever une exception. Le premier argument est le code d’erreur, le second est la valeur booléenne de vérification de bits. Si le bit est faux, l’exception sera levée avec le code d’erreur correspondant. Dans cette ligne, equal_slices est utilisé pour vérifier si l’adresse de l’expéditeur résolue ci-dessus est égale à l’adresse de propriétaire stockée en permanence dans ce contrat, afin de vérifier les autorisations.
Enfin, pour rendre la structure du code plus claire, commencez par une série de fonctions auxiliaires pour obtenir des informations persistantes. Ici, nous n’allons pas nous étendre sur les détails, les développeurs peuvent utiliser cette structure comme référence pour développer leurs propres smart contracts.
Le développement DApp de l’écosystème TON est vraiment intéressant, avec des différences importantes par rapport au paradigme de développement EVM, donc j’écrirai une série d’articles sur la façon de développer des DApp sur TON Chain. Apprenons ensemble et saisissons cette opportunité. Je vous invite également à interagir avec moi sur Twitter pour échanger des idées de nouvelles DApp intéressantes et développer ensemble.