Maison  >  Article  >  Comment créer un NFT sur TON Chain du point de vue du code source

Comment créer un NFT sur TON Chain du point de vue du code source

WBOY
WBOYoriginal
2024-06-25 18:45:02678parcourir

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

L'émission d'un FT ou d'un NFT est généralement le besoin le plus fondamental pour les développeurs DApp. Je l'utilise donc également comme point d'entrée pour l'apprentissage. Tout d'abord, comprenons les différences suivantes entre le développement d'un NFT dans la pile technologique EVM et TON Chain. Les NFT basés sur EVM choisissent souvent d'hériter de la norme ERC-721. Ce qu'on appelle le NFT fait référence à un type indivisible d'actif crypté, et chaque actif est unique, c'est-à-dire qu'il possède certaines caractéristiques exclusives. ERC-721 est un paradigme de développement commun pour ce type d'actifs. Jetons un coup d'œil aux fonctions qu'un contrat ERC721 commun doit mettre en œuvre et aux informations qui doivent être enregistrées. L'image ci-dessous est une interface ERC721. On constate que contrairement à FT, ce qui doit être saisi dans l'interface de transfert, c'est le tokenId à transférer plutôt que le montant. Ce tokenId est également l'incarnation la plus basique du caractère unique des actifs NFT. Bien entendu, afin de transporter plus d'attributs, une métadonnée est généralement enregistrée pour chaque tokenId. Ces métadonnées sont un lien externe qui enregistre d'autres données évolutives du NFT, telles que. sous forme de liens vers des images PFP, des noms de certaines propriétés, etc.

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

Pour les développeurs familiers avec Solidity ou orientés objet, il est facile de mettre en œuvre un tel contrat intelligent tant que les types de données requis dans le contrat sont définis, comme certaines relations de mappage clés, et. sur la base des besoins Il est nécessaire de développer fonctionnellement la logique de modification correspondante pour ces données afin de réaliser un NFT.

Cependant, ce n'est pas la même chose dans TON Chain. Il y a deux raisons principales à la différence :

  • Dans TON, le stockage des données est basé sur Cell, et la cellule du même compte est mise en œuvre via des informations dirigées et dirigées. Diagramme en anneau non orienté à réaliser. Cela signifie que les données qui doivent être stockées ne peuvent pas croître sans limites, car pour un graphe acyclique orienté, le coût de la requête est déterminé par la profondeur des données. Lorsque la profondeur s'étend à l'infini, le coût de la requête peut être trop élevé, ce qui conduit à. Le contrat est bloqué dans une impasse.

  • Afin de rechercher des performances de concurrence élevée, TON a abandonné l'architecture d'exécution en série et a plutôt adopté un paradigme de développement spécifiquement conçu pour le parallélisme, le modèle Actor, pour reconstruire l'environnement d'exécution. Cela a un impact. Les contrats intelligents ne peuvent être appelés de manière asynchrone qu'en envoyant des messages dits internes. Notez qu'il s'agit d'un type d'appel de modification d'état ou d'un type d'appel en lecture seule, ce principe doit également être suivi. doit être soigneusement examiné. Comment gérer la restauration des données en cas d'échec d'un appel asynchrone.

    Bien sûr, d'autres différences techniques ont été discutées en détail dans l'article précédent. Cet article espère se concentrer sur le développement de contrats intelligents, il ne sera donc pas abordé. Les deux principes de conception ci-dessus font une grande différence entre le développement de contrats intelligents dans TON et EVM. Dans la discussion initiale, nous savons qu'un contrat NFT doit définir certaines relations de mappage, c'est-à-dire le mappage, pour enregistrer les données liées au NFT. Le plus important d'entre eux est celui des propriétaires. Ce mappage stocke la relation de mappage de l'adresse du propriétaire du NFT correspondant à un certain tokenID, qui détermine la propriété du NFT. Le transfert est une modification de la propriété. Puisqu’il s’agit d’une structure de données qui peut en théorie être illimitée, elle doit être évitée autant que possible. Par conséquent, il est officiellement recommandé d’utiliser l’existence de structures de données illimitées comme norme de partitionnement. Autrement dit, lorsque les exigences de stockage de données sont similaires, le paradigme du contrat maître-esclave est utilisé à la place et les données correspondant à chaque clé sont gérées en créant des sous-contrats. Et gérez les paramètres globaux via le contrat principal, ou aidez à gérer l'interaction des informations internes entre les sous-contrats.

    Cela signifie que les NFT dans TON doivent également être conçus en utilisant une architecture similaire. Chaque NFT est un sous-contrat indépendant, qui enregistre des données exclusives telles que l'adresse du propriétaire, les métadonnées, etc., et est géré via un contrat principal. données globales telles que le nom NFT, le symbole, l'offre totale, etc.

    Après avoir clarifié l'architecture, l'étape suivante consiste à résoudre les exigences fonctionnelles de base. Puisque cette méthode de contrat maître-esclave est adoptée, il est nécessaire de clarifier quelles fonctions sont assurées par le contrat principal et quelles fonctions sont assurées par le sous-contrat. contrat, et quelles fonctions sont assurées par le sous-contrat, et quelles fonctions sont assurées par le sous-contrat. Quelles informations internes sont utilisées pour communiquer entre elles et comment restaurer les données précédentes lorsqu'une erreur d'exécution se produit. Habituellement, avant de développer un projet complexe à grande échelle, il est nécessaire de passer un diagramme de classes et de clarifier le flux d'informations entre eux, et de réfléchir attentivement à la logique de restauration après l'échec de l'appel interne. Bien sûr, le développement NFT ci-dessus est simple. , mais il peut également effectuer une vérification similaire.

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

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

    TON a choisi de concevoir un langage de type C, typé statiquement, nommé Func comme langage de développement de contrats intelligents, puis apprenons comment le développer à partir du code source Pour le contrat intelligent TON, j'ai choisi l'exemple NFT dans le document officiel de TON pour le présenter. Les amis intéressés peuvent le consulter par eux-mêmes. Dans ce cas, un exemple simple de TON NFT est implémenté. Jetons un coup d'œil à la structure du contrat, qui est divisée en deux contrats fonctionnels et trois bibliothèques nécessaires.

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

    Ces deux contrats fonctionnels principaux sont conçus selon les principes ci-dessus. Tout d'abord, regardons le code du contrat principal nft-collection :

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

    Cela introduit le premier point de connaissance, comment utiliser TON Persistent. stockage des données dans les contrats intelligents. Nous savons que le stockage persistant des données dans Solidity est automatiquement géré par l'EVM en fonction du type de paramètres. Normalement, les variables d'état du contrat intelligent seront automatiquement conservées en fonction de la dernière valeur après l'exécution. . Stockage, les développeurs n'ont pas besoin de prendre en compte ce processus. Mais ce n'est pas le cas dans Func. Les développeurs doivent implémenter eux-mêmes la logique de traitement correspondante. Cette situation est quelque peu similaire à la façon dont C et C++ doivent considérer le processus GC, mais d'autres nouveaux langages de développement automatisent généralement cette partie de la logique. . Jetons un coup d'œil au code. Tout d'abord, nous introduisons quelques bibliothèques requises, puis nous voyons que la première fonction load_data est utilisée pour lire les données stockées de manière persistante. Sa logique est de renvoyer d'abord la cellule de stockage du contrat persistant via get_data. se fait par le standard Implémenté par la bibliothèque stdlib.fc, certaines fonctions peuvent généralement être utilisées comme fonctions système.

    Le type de valeur de retour de cette fonction est cell, qui est le type de cellule dans TVM. Dans l’introduction précédente, nous savons déjà que toutes les données persistantes de la blockchain TON sont stockées dans l’arborescence cellulaire. Chaque cellule contient jusqu'à 1 023 bits de données arbitraires et jusqu'à quatre références à d'autres cellules. Les cellules sont utilisées comme mémoire dans le TVM basé sur une pile. Ce qui est stocké dans la cellule sont des données codées de manière compacte. Pour obtenir les données en texte clair spécifiques, la cellule doit être convertie en un type appelé tranche. La cellule peut être convertie en type tranche via la fonction start_parse, puis les données de la cellule peuvent être obtenues en chargeant les bits de données et les références à d'autres cellules de la tranche. Notez que la méthode appelante de la ligne 15 est du sucre syntaxique dans une fonction qui appelle directement la deuxième fonction sur la valeur de retour de la première fonction. Et enfin chargez les données correspondantes dans l'ordre selon l'ordre de persistance des données. Notez que ce processus est différent de solidity et n'est pas appelé en fonction de hashmap, donc l'ordre des appels ne peut pas être gâché.

    Dans la fonction save_data, la logique est similaire, sauf qu'il s'agit d'un processus inverse, qui introduit le point de connaissance suivant, un nouveau constructeur de type, qui est le type de constructeur de cellules. Les bits de données et les références à d'autres cellules peuvent être stockées dans des générateurs, qui peuvent ensuite être finalisées dans de nouvelles cellules. Créez d'abord un constructeur via la fonction standard start_cell et stockez tour à tour les fonctions associées via les fonctions liées au magasin. Notez que l'ordre d'appel ci-dessus doit être cohérent avec l'ordre de stockage ici. Enfin, end_cell est utilisé pour terminer la construction de la nouvelle cellule. A ce moment, la cellule est gérée en mémoire. Enfin, via le set_data le plus externe, le stockage persistant de la cellule peut être complété.

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

    Ensuite, jetons un coup d'œil aux fonctions liées à l'entreprise. Tout d'abord, nous devons introduire le point de connaissance suivant, comment créer un nouveau contrat via un contrat, qui sera fréquemment utilisé dans l'architecture maître-esclave. introduit. Nous savons que dans TON, les appels entre contrats intelligents sont mis en œuvre par l'envoi de messages internes. Ceci est réalisé via un message appelé send_raw_message. Notez que le premier paramètre est la cellule codée du message et le deuxième paramètre est le bit d'identification, qui est utilisé pour indiquer la différence dans la méthode d'exécution de la transaction. Différents paramètres internes sont définis. dans TON, il existe actuellement 3 modes de message et 3 indicateurs de message pour le mode d'exécution de l'envoi de messages. Un seul mode peut être combiné avec plusieurs indicateurs (peut-être aucun) pour obtenir le mode souhaité. Combiner signifie simplement remplir la somme de leurs valeurs. Le tableau de description des modes et des indicateurs est donné ci-dessous :

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

    Regardons donc la première fonction principale, déployer_nft_item, comme son nom l'indique, il s'agit d'une fonction utilisée pour créer ou lancer de nouvelles instances NFT après quelques opérations après l'encodage. un msg, envoyez le contrat interne via send_raw_message et sélectionnez le drapeau d'envoi du drapeau 1. Seuls les frais spécifiés dans l'encodage seront utilisés comme frais de gaz pour cette exécution. Après l’introduction ci-dessus, on peut facilement se rendre compte que cette règle de codage doit correspondre à la manière de créer un nouveau contrat intelligent. Voyons donc 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 requises pour le message, nous y reviendrons donc plus tard. Il s'agit d'un processus d'encodage pour créer des messages internes de contrats intelligents. le milieu est en fait ce sont également des bits d'identification utilisés pour décrire les exigences du message interne. Le point de connaissance suivant est introduit ici. TON a choisi un langage binaire appelé TL-B pour décrire le mode d'exécution du message et définit différents indicateurs. bits à Pour implémenter des messages internes pour certaines fonctions spécifiques, les deux scénarios d'utilisation les plus simples à imaginer sont la création d'un nouveau contrat et les appels de fonctions de contrat déployés. La méthode de la ligne 51 correspond à la première, créant un nouveau contrat d'article nft, qui est principalement spécifié par les lignes 55, 56 et 57. Tout d'abord, la grande série de nombres de la ligne 55 est une série de bits d'identification. Notez que le premier paramètre d'entrée de store_uint est la valeur et le second est la longueur en bits, qui détermine si le message interne est créé par le contrat. , les trois derniers bits de marquage et le bit de valeur binaire correspondant est 111 (le nombre décimal est 4+2+1), dont les deux premiers indiquent que le message sera accompagné de données StateInit. Ces données sont le code source du. nouveau contrat et les données nécessaires à l'initialisation. Ce dernier bit indicateur indique la pièce jointe du message interne, c'est-à-dire que la logique pertinente et les paramètres requis devraient être exécutés. Par conséquent, vous verrez que les données à trois chiffres ne sont pas définies dans la ligne 66 du code, ce qui indique un appel de fonction au contrat déployé. Les règles de codage détaillées peuvent être trouvées ici.

    Ensuite, les règles d'encodage de StateInit correspondent à 49 lignes de code, calculées via calculate_nft_item_state_init. Notez que l'encodage des données stateinit suit également une règle d'encodage TL-B établie. En plus de certains bits d'indicateur, il implique principalement deux parties du. nouveau code de contrat et données initialisées. L'ordre de codage des données doit être cohérent avec l'ordre de stockage des cellules de persistance spécifié par le nouveau contrat. Comme vous pouvez le voir à la ligne 36, les données d'initialisation incluent item_index, qui est similaire au tokenId dans ERC721, et l'adresse du contrat actuel renvoyée par la fonction standard my_address, qui est collection_address. L'ordre de ces données est cohérent avec la déclaration dans. article nft.

    Le prochain point de connaissance est que dans TON, tous les contrats intelligents non générés peuvent pré-calculer leurs adresses générées. Ceci est similaire à la fonction create2 dans Solidity. La génération de nouvelles adresses dans TON se compose de deux parties. épissé avec la valeur de hachage de stateinit, nous savons déjà que la première doit être spécifiée afin de correspondre à l'architecture de partitionnement infinie TON. Il s'agit actuellement d'une valeur unifiée. Obtenu à partir de la chaîne de travail des fonctions standard. Cette dernière est obtenue par la fonction standard cell_hash. Revenons donc à cet exemple, calculate_nft_item_address est une fonction qui précalcule la nouvelle adresse du contrat. Et codez la valeur générée dans le message sur la ligne 53 comme adresse de réception du message interne. nft_content correspond à l'appel d'initialisation du contrat créé. L'implémentation spécifique sera présentée dans le prochain article.

    Quant à send_royalty_params, il doit s'agir d'une réponse au message interne d'une requête en lecture seule. Dans l'introduction précédente, nous avons spécialement souligné que le message interne de TON contient non seulement des opérations susceptibles de modifier les données, mais également la lecture. -seule l'opération doit réussir. Elle est implémentée d'une certaine manière, donc 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 de rappel du demandeur après avoir répondu à la demande. pour obtenir les données renvoyées, qui sont l'index d'article demandé et les données de redevances correspondantes.

    Présentons le point de connaissance suivant. Il n'y a que deux entrées unifiées pour les contrats intelligents dans TON, nommées recv_internal et recv_external, la première est l'entrée d'appel unifiée pour tous les messages internes, et la seconde est l'entrée d'appel unifiée pour tous les messages externes. messages. , les développeurs doivent utiliser une méthode de type commutateur pour répondre à différentes requêtes basées sur différents bits d'indicateur spécifiés par message dans la fonction selon les exigences. Le bit d'indicateur ici est l'indicateur de fonction de rappel de la ligne 67 ci-dessus. Revenons à cet exemple, effectuez d'abord une vérification des postes vacants sur le message, puis analysez les informations contenues dans le message respectivement. Commencez par analyser la ligne 83 pour obtenir l'adresse de l'expéditeur. Ce paramètre sera utilisé pour les vérifications d'autorisation ultérieures. ici appartient à une autre syntaxe. Je ne m’étendrai pas là-dessus ici. Ensuite, les bits d'indicateur d'opération opérationnelle sont analysés, puis les demandes correspondantes sont traitées en fonction de différents bits d'indicateur. Parmi elles, les fonctions ci-dessus sont appelées respectivement selon une certaine logique. Par exemple, répondez à une demande concernant le paramètre de redevance, ou créez un nouveau nft et incrémentez l'index global.

    Le point de connaissance suivant correspond à la ligne 108. Je pense que vous pouvez également connaître la logique de traitement de cette fonction en la nommant. Semblable à la fonction require dans Solidity, les exceptions sont levées dans Func via la fonction standard throw_unless. est le code d'erreur. La seconde consiste à vérifier la valeur booléenne du bit. Si le bit est faux, une exception sera levée avec le code d'erreur. Dans cette ligne, equal_slices est utilisé pour déterminer si l'adresse de l'expéditeur analysée ci-dessus est égale à l'adresse du propriétaire du stockage persistant du contrat, et un jugement d'autorisation est effectué.

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

    Enfin, afin de rendre la structure du code plus claire, une série de fonctions auxiliaires ont été développées pour aider à obtenir des informations de persistance, qui ne seront pas présentées ici. Les développeurs peuvent se référer à cette structure pour développer leurs propres contrats intelligents.

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

    Le développement de DApp dans l'écosystème TON est vraiment intéressant et est très différent du paradigme de développement d'EVM, je vais donc vous présenter comment développer DApp dans TON Chain à travers une série d'articles.

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn