Dans ce tutoriel, nous allons apprendre à créer un site Web pour collecter des objets de collection numériques (ou NFT) sur la blockchain Flow. Nous utiliserons le langage de contrat intelligent Cadence avec React pour que tout cela se réalise. Nous découvrirons également Flow, ses avantages et les outils amusants que nous pouvons utiliser.
À la fin de cet article, vous disposerez des outils et des connaissances dont vous avez besoin pour créer votre propre application décentralisée sur la blockchain Flow.
Allons-y !
Nous construisons une application pour les objets de collection numériques. Chaque objet de collection est un jeton non fongible (NFT).
Pour que tout cela fonctionne, nous utiliserons la norme NonFungibleToken de Flow, qui est un ensemble de règles qui nous aident à gérer ces éléments numériques spéciaux (similaires à l'ERC-721 dans Ethereum).
Avant de commencer, assurez-vous d'installer Flow CLI sur votre système. Si vous ne l'avez pas fait, suivez ces instructions d'installation .
Si vous êtes prêt à démarrer votre projet, saisissez d'abord la configuration du flux de commandes.
Cette commande fait de la magie en coulisse pour établir les bases de votre projet. Il crée un système de dossiers et configure un fichier appelé flow.json pour configurer votre projet, en s'assurant que tout est organisé et prêt à fonctionner !
Le projet contiendra un dossier cadence
et un fichier flow.json
. (Un fichier flow.json est un fichier de configuration pour votre projet, automatiquement maintenu.)
Le dossier Cadence contient les éléments suivants :
Suivez les étapes ci-dessous pour utiliser Flow NFT Standard.
Tout d’abord, accédez au dossier flow-collectibles-portal
et recherchez le dossier cadence
. Ensuite, ouvrez le dossier contracts
. Créez un nouveau fichier et nommez-le NonFungibleToken.cdc
.
Maintenant, ouvrez le lien nommé NonFungibleToken qui contient le standard NFT. Copiez tout le contenu de ce fichier et collez-le dans le nouveau fichier que vous venez de créer (« NonFungibleToken.cdc »).
C'est ça! Vous avez mis en place avec succès les normes de votre projet.
Maintenant, écrivons du code !
Cependant, avant de nous lancer dans le codage, il est important que les développeurs établissent un modèle mental sur la manière de structurer leur code.
Au niveau supérieur, notre base de code se compose de trois composants principaux :
NFT : Chaque objet de collection est représenté comme un NFT.
Collection : Une collection fait référence à un groupe de NFT appartenant à un utilisateur spécifique.
Fonctions et variables globales : ce sont des fonctions et des variables définies au niveau global pour le contrat intelligent et ne sont associées à aucune ressource particulière.
Créez un nouveau fichier nommé Collectibles.cdc
dans cadence/contracts
. C'est ici que nous écrirons le code.
Structure du contrat
import NonFungibleToken from "./NonFungibleToken.cdc" pub contract Collectibles: NonFungibleToken{ pub var totalSupply: UInt64 // other code will come here init(){ self.totalSupply = 0 } }
Décomposons le code ligne par ligne :
Tout d'abord, nous devrons standardiser le fait que nous construisons un NFT en incluant ce que l'on appelle le « NonFungibleToken ». Il s'agit d'une norme NFT construite par Flow qui définit l'ensemble de fonctionnalités suivant qui doit être inclus par chaque contrat intelligent NFT.
Après l'importation, créons notre contrat. Pour ce faire, nous utilisons pub contract [contract name]
. Utilisez la même syntaxe chaque fois que vous créez un nouveau contrat. Vous pouvez remplir le contract name
avec le nom que vous souhaitez pour votre contrat. Dans notre cas, appelons-le Collectibles
.
Ensuite, nous voulons nous assurer que notre contrat suit un certain ensemble de fonctionnalités et de règles de NonFungibleToken. Pour ce faire, nous ajoutons une interface NonFungibleToken à l'aide de `:`.
Comme ça ( `pub contract Collectibles: NonFungibleToken{}`
)
Chaque contrat DOIT avoir la fonction init()
. Il est appelé lors du déploiement initial du contrat. Ceci est similaire à ce que Solidity appelle un constructeur.
Créons maintenant une variable globale appelée totalSupply
avec un type de données UInt64
. Cette variable gardera une trace de votre total d’objets de collection.
Maintenant, initialisez totalSupply
avec la valeur 0
.
C'est ça! Nous avons jeté les bases de notre contrat Collectibles
. Maintenant, nous pouvons commencer à ajouter plus de fonctionnalités pour le rendre encore plus excitant.
Avant de continuer, veuillez consulter l'extrait de code pour comprendre comment nous définissons les variables dans Cadence :
Ajoutez le code suivant à votre contrat intelligent :
import NonFungibleToken from "./NonFungibleToken.cdc" pub contract Collectibles: NonFungibleToken{ // above code… pub resource NFT: NonFungibleToken.INFT{ pub let id: UInt64 pub var name: String pub var image: String init(_id:UInt64, _name:String, _image:String){ self.id = _id self.name = _name self.image = _image } } // init()... }
Comme vous l'avez vu précédemment, le contrat implémente l'interface standard NFT, représentée par pub contract Collectibles: NonFungibleToken
. De même, les ressources peuvent également implémenter diverses interfaces de ressources.
Ajoutons donc l'interface NonFungibleToken.INFT
à la ressource NFT, qui impose l'existence d'une propriété publique appelée id au sein de la ressource.
Voici les variables que nous utiliserons dans la ressource NFT :
id:
conserve l’ID de NFTname:
Nom du NFT.image:
URL de l’image de NFT.
Après avoir défini la variable, assurez-vous d'initialiser la variable dans la fonction init()
.
Allons de l'avant et créons une autre ressource appelée Collection Resource
.
Tout d’abord, vous devez comprendre le fonctionnement Collection Resources
.
Si vous aviez besoin de stocker un fichier musical et plusieurs photos sur votre ordinateur portable, que feriez-vous ?
En règle générale, vous accédez à un lecteur local (disons votre D-Drive) et créez un dossier music
et un dossier photos
. Vous copierez et collerez ensuite les fichiers de musique et de photo dans vos dossiers de destination.
De même, c'est ainsi que fonctionnent vos objets de collection numériques sur Flow.
Imaginez votre ordinateur portable comme un Flow Blockchain Account
, votre D-Drive comme Account Storage
et votre dossier comme Collection
.
Ainsi, lorsque vous interagissez avec un projet pour acheter des NFT, le projet crée sa collection
dans account storage
, de la même manière que vous créez un dossier sur votre D-Drive. Lorsque vous interagissez avec 10 projets NFT différents, vous vous retrouverez avec 10 collections différentes dans votre compte.
C'est comme avoir un espace personnel pour stocker et organiser vos trésors numériques uniques !
import NonFungibleToken from "./NonFungibleToken.cdc" pub contract Collectibles: NonFungibleToken{ //Above code NFT Resource… // Collection Resource pub resource Collection{ } // Below code… }
Chaque collection
possède une variable ownedNFTs
pour contenir les NFT Resources
.
pub resource Collection { pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT} init(){ self.ownedNFTs <- {} } }
Interfaces de ressources
Une interface resource
dans Flow est similaire aux interfaces d’autres langages de programmation. Il se trouve au-dessus d'une ressource et garantit que la ressource qui l'implémente dispose des fonctionnalités requises telles que définies par l'interface.
Il peut également être utilisé pour restreindre l'accès à l'ensemble de la ressource et être plus restrictif en termes de modificateurs d'accès que la ressource elle-même.
Dans la norme NonFungibleToken
, il existe plusieurs interfaces de ressources telles que INFT
, Provider
, Receiver
et CollectionPublic
.
Chacune de ces interfaces possède des fonctions et des champs spécifiques qui doivent être implémentés par la ressource qui les utilise.
Dans ce contrat, nous utiliserons ces trois interfaces de NonFungibleToken: Provider
, Receiver
et CollectionPublic
. Ces interfaces définissent des fonctions telles que deposit
, withdraw
, borrowNFT
et getIDs
. Nous expliquerons chacun d’eux en détail au fur et à mesure.
Nous ajouterons également certains événements que nous émettrons à partir de ces fonctions, ainsi que déclarerons certaines variables que nous utiliserons plus loin dans le didacticiel.
pub contract Collectibles:NonFungibleToken{ // rest of the code… pub event ContractInitialized() pub event Withdraw(id: UInt64, from: Address?) pub event Deposit(id: UInt64, to: Address?) pub let CollectionStoragePath: StoragePath pub let CollectionPublicPath: PublicPath pub resource interface CollectionPublic{ pub fun deposit(token: @NonFungibleToken.NFT) pub fun getIDs(): [UInt64] pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT } pub resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic{ pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT} init(){ self.ownedNFTs <- {} } } }
Retirer
Maintenant, créons la fonction withdraw()
requise par l'interface.
pub resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic{ // other code pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT { let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT") emit Withdraw(id: token.id, from: self.owner?.address) return <- token } init()... }
À l'aide de cette fonction, vous pouvez déplacer la ressource NFT hors de la collection. Si ça:
L'appelant peut ensuite utiliser cette ressource et la sauvegarder dans le stockage de son compte.
Dépôt
Il est maintenant temps de passer à la fonction deposit()
requise par NonFungibleToken.Receiver
.
pub resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic{ // other code pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT { let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT") emit Withdraw(id: token.id, from: self.owner?.address) return <- token } pub fun deposit(token: @NonFungibleToken.NFT) { let id = token.id let oldToken <- self.ownedNFTs[id] <-token destroy oldToken emit Deposit(id: id, to: self.owner?.address) } init()... }
Emprunter et obtenir un ID
Concentrons-nous maintenant sur les deux fonctions requises par NonFungibleToken.CollectionPublic: borrowNFT()
et getID()
.
pub resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic{ // other code pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT { let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT") emit Withdraw(id: token.id, from: self.owner?.address) return <- token } pub fun deposit(token: @NonFungibleToken.NFT) { let id = token.id let oldToken <- self.ownedNFTs[id] <-token destroy oldToken emit Deposit(id: id, to: self.owner?.address) } pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT { if self.ownedNFTs[id] != nil { return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)! } panic("NFT not found in collection.") } pub fun getIDs(): [UInt64]{ return self.ownedNFTs.keys } init()... }
Destructeur
La dernière chose dont nous avons besoin pour la ressource de collection est un destructeur.
destroy (){ destroy self.ownedNFTs }
Puisque la ressource Collection contient d’autres ressources (ressources NFT), nous devons spécifier un destructeur. Un destructeur s'exécute lorsque l'objet est détruit. Cela garantit que les ressources ne se retrouvent pas « sans abri » lorsque leur ressource parent est détruite. Nous n'avons pas besoin de destructeur pour la ressource NFT car elle ne contient aucune autre ressource.
Examinons le code source complet des ressources de la collection :
import NonFungibleToken from "./NonFungibleToken.cdc" pub contract Collectibles: NonFungibleToken{ pub var totalSupply: UInt64 pub resource NFT: NonFungibleToken.INFT{ pub let id: UInt64 pub var name: String pub var image: String init(_id:UInt64, _name:String, _image:String){ self.id = _id self.name = _name self.image = _image } } pub resource interface CollectionPublic{ pub fun deposit(token: @NonFungibleToken.NFT) pub fun getIDs(): [UInt64] pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT } pub event ContractInitialized() pub event Withdraw(id: UInt64, from: Address?) pub event Deposit(id: UInt64, to: Address?) pub let CollectionStoragePath: StoragePath pub let CollectionPublicPath: PublicPath pub resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic{ pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT} init(){ self.ownedNFTs <- {} } destroy (){ destroy self.ownedNFTs } pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT { let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT") emit Withdraw(id: token.id, from: self.owner?.address) return <- token } pub fun deposit(token: @NonFungibleToken.NFT) { let id = token.id let oldToken <- self.ownedNFTs[id] <-token destroy oldToken emit Deposit(id: id, to: self.owner?.address) } pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT { if self.ownedNFTs[id] != nil { return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)! } panic("NFT not found in collection.") } pub fun getIDs(): [UInt64]{ return self.ownedNFTs.keys } } init(){ self.CollectionPublicPath = /public/NFTCollection self.CollectionStoragePath = /storage/NFTCollection self.totalSupply = 0 emit ContractInitialized() } }
Maintenant, nous avons terminé toutes les ressources. Ensuite, nous examinerons la fonction globale.
Les fonctions globales sont des fonctions définies au niveau global du contrat intelligent, ce qui signifie qu'elles ne font partie d'aucune ressource. Ceux-ci sont accessibles et appelés par le public, et exposent les fonctionnalités de base du contrat intelligent au public.
createEmptyCollection : Cette fonction initialise un Collectibles.Collection
vide dans le stockage du compte de l'appelant.
checkCollection : Cette fonction pratique vous aide à découvrir si votre compte dispose déjà d'une ressource collection
.
mintNFT : Cette fonction est super cool car elle permet à n'importe qui de créer un NFT.
// pub resource Collection… pub fun createEmptyCollection(): @Collection{ return <- create Collection() } pub fun checkCollection(_addr: Address): Bool{ return getAccount(_addr) .capabilities.get<&{Collectibles.CollectionPublic}> (Collectibles.CollectionPublicPath)! .check() } pub fun mintNFT(name:String, image:String): @NFT{ Collectibles.totalSupply = Collectibles.totalSupply + 1 let nftId = Collectibles.totalSupply var newNFT <- create NFT(_id:nftId, _name:name, _image:image) return <- newNFT } init()...
Et maintenant, ENFIN, avec tout en place, nous avons fini d'écrire notre contrat intelligent. Jetez un œil au code final ici .
Voyons maintenant comment un utilisateur interagit avec les contrats intelligents déployés sur la blockchain Flow.
Il y a deux étapes pour interagir avec la blockchain Flow :
Les transactions sont des données signées cryptographiquement qui contiennent un ensemble d'instructions qui interagissent avec le contrat intelligent pour mettre à jour l'état du flux. En termes simples, cela ressemble à un appel de fonction qui modifie les données sur la blockchain. Les transactions impliquent généralement un certain coût, qui peut varier en fonction de la blockchain sur laquelle vous vous trouvez.
Une transaction comprend plusieurs phases facultatives : phase prepare
, pre
, execute
et post
.
Vous pouvez en savoir plus à ce sujet dans le document de référence Cadence sur les transactions . Chaque phase a un objectif ; les deux phases les plus importantes sont prepare
et execute
.
Prepare Phase
: Cette phase est utilisée pour accéder aux données et informations contenues dans le compte du signataire (autorisé par le type AuthAccount).
Execute Phase
: Cette phase est utilisée pour exécuter des actions.
Maintenant, créons une transaction pour notre projet.
Suivez les étapes ci-dessous pour créer une transaction dans votre dossier de projet.
Tout d’abord, allez dans le dossier du projet et ouvrez le dossier cadence
. À l'intérieur, ouvrez le dossier transaction
et créez un nouveau fichier portant le nom Create_Collection.cdc
et mint_nft.cdc
import Collectibles from "../contracts/Collectibles.cdc" transaction { prepare(signer: AuthAccount) { if signer.borrow<&Collectibles.Collection>(from: Collectibles.CollectionStoragePath) == nil { let collection <- Collectibles.createEmptyCollection() signer.save(<-collection, to: Collectibles.CollectionStoragePath) let cap = signer.capabilities.storage.issue<&{Collectibles.CollectionPublic}>(Collectibles.CollectionStoragePath) signer.capabilities.publish( cap, at: Collectibles.CollectionPublicPath) } } }
Décomposons ce code ligne par ligne :
Cette transaction interagit avec le contrat intelligent Collectibles. Ensuite, il vérifie si l'expéditeur (signataire) a une ressource Collection stockée dans son compte en empruntant une référence à la ressource Collection à partir du chemin de stockage spécifié Collectibles.CollectionStoragePath
. Si la référence est nulle, cela signifie que le signataire n'a pas encore de collection.
Si le signataire n'a pas de collection, il crée alors une collection vide en appelant la fonction createEmptyCollection()
.
Après avoir créé la collection vide, placez-la dans le compte du signataire sous le chemin de stockage spécifié Collectibles.CollectionStoragePath
.
Cela établit un lien entre le compte du signataire et la collection nouvellement créée à l'aide link()
.
import NonFungibleToken from "../contracts/NonFungibleToken.cdc" import Collectibles from "../contracts/Collectibles.cdc" transaction(name:String, image:String){ let receiverCollectionRef: &{NonFungibleToken.CollectionPublic} prepare(signer:AuthAccount){ self.receiverCollectionRef = signer.borrow<&Collectibles.Collection>(from: Collectibles.CollectionStoragePath) ?? panic("could not borrow Collection reference") } execute{ let nft <- Collectibles.mintNFT(name:name, image:image) self.receiverCollectionRef.deposit(token: <-nft) } }
Décomposons ce code ligne par ligne :
Nous importons d'abord le Collectibles contract
NonFungibleToken
et Collectibles.
transaction(name: String, image: String)
Cette ligne définit une nouvelle transaction. Il prend deux arguments, nom et image, tous deux de type String. Ces arguments sont utilisés pour transmettre le nom et l'image du NFT en cours de création.
let receiverCollectionRef: &{NonFungibleToken.CollectionPublic}
Cette ligne déclare une nouvelle variable receiverCollectionRef.
Il s'agit d'une référence à une collection publique de NFT de type NonFungibleToken.CollectionPublic
. Cette référence sera utilisée pour interagir avec la collection où nous déposerons le nouveau NFT.
prepare(signer: AuthAccount)
Cette ligne démarre le bloc de préparation, qui est exécuté avant la transaction. Il faut un argument signataire de type AuthAccount
. AuthAccount
représente le compte du signataire de la transaction.
Il emprunte une référence à Collectibles.Collection
à partir du stockage du signataire à l'intérieur du bloc de préparation. Il utilise la fonction d'emprunt pour accéder à la référence à la collection et la stocker dans la variable receiverCollectionRef
.
Si la référence n'est pas trouvée (si la collection n'existe pas dans le stockage du signataire, par exemple), le message d'erreur « Impossible d'emprunter la référence de la collection ».
Le bloc execute
contient la logique d'exécution principale de la transaction. Le code à l’intérieur de ce bloc sera exécuté une fois le bloc prepare
terminé avec succès.
nft <- Collectibles.mintNFT(_name: name, image: image)
À l'intérieur du bloc execute
, cette ligne appelle la fonction mintNFT
du contrat Collectibles
avec le nom et les arguments d'image fournis. Cette fonction devrait créer un nouveau NFT avec le nom et l'image donnés. Le symbole <-
indique que le NFT est reçu comme un objet pouvant être déplacé (une ressource).
self.receiverCollectionRef.deposit(token: <-nft)
Cette ligne dépose le NFT nouvellement créé dans la collection spécifiée. Il utilise la fonction de dépôt sur receiverCollectionRef
pour transférer la propriété du NFT du compte d'exécution de la transaction vers la collection. Le symbole <-
indique également ici que le NFT est déplacé en tant que ressource pendant le processus deposit
.
Nous utilisons un script pour afficher ou lire les données de la blockchain. Les scripts sont gratuits et ne nécessitent pas de signature.
Suivez les étapes ci-dessous pour créer un script dans votre dossier de projet.
Tout d’abord, allez dans le dossier du projet et ouvrez le dossier cadence
. À l'intérieur, ouvrez le dossier script
et créez un nouveau fichier portant le nom view_nft.cdc
.
import NonFungibleToken from "../contracts/NonFungibleToken.cdc" import Collectibles from "../contracts/Collectibles.cdc" pub fun main(user: Address, id: UInt64): &NonFungibleToken.NFT? { let collectionCap= getAccount(user).capabilities .get<&{Collectibles.CollectionPublic}>(/public/NFTCollection) ?? panic("This public capability does not exist.") let collectionRef = collectionCap.borrow()! return collectionRef.borrowNFT(id: id) }
Décomposons ce code ligne par ligne :
Tout d’abord, nous importons le contrat NonFungibleToken
et Collectibles
.
pub fun main(acctAddress: Address, id: UInt64): &NonFungibleToken.NFT?
Cette ligne définit le point d'entrée du script, qui est une fonction publique nommée main. La fonction prend deux paramètres :
acctAddress
: Un paramètre de type Address
représentant l'adresse d'un compte sur la blockchain Flow.
id
: Un paramètre de type UInt64
représentant l'identifiant unique du NFT au sein de la collection.
Ensuite, nous utilisons getCapability
pour récupérer la capacité Collectibles.Collection
pour l' acctAddress
spécifiée. Une capacité est une référence à une ressource qui permet d'accéder à ses fonctions et à ses données. Dans ce cas, il récupère la capacité du type de ressource Collectibles.Collection
.
Ensuite, nous empruntons un NFT à collectionRef
à l’aide de la fonction borrowNFT
. La fonction borrowNFT
prend le paramètre id
, qui est l'identifiant unique du NFT au sein de la collection. La fonction borrow
sur une capacité permet de lire les données de la ressource.
Enfin, nous renvoyons le NFT de la fonction.
Il est maintenant temps de déployer notre contrat intelligent sur le réseau de test Flow.
1. Créez un compte Flow.
Exécutez la commande suivante dans le terminal pour générer un compte Flow :
flow keys generate
Assurez-vous de noter votre clé publique et votre clé privée.
Ensuite, nous nous dirigerons vers
Collez votre clé publique dans le champ de saisie spécifié.
Conservez les algorithmes de signature et de hachage par défaut.
Complétez le Captcha.
Cliquez sur Créer un compte.
Après avoir créé un compte, nous recevons un dialogue avec notre nouvelle adresse Flow contenant 1 000 jetons Flow de test. Copiez l'adresse afin que nous puissions l'utiliser à l'avenir .
2. Configurez le projet.
Maintenant, configurons notre projet. Initialement, lorsque nous avons configuré le projet, il a créé un fichier flow.json
.
Il s'agit du fichier de configuration de Flow CLI et définit la configuration des actions que Flow CLI peut effectuer pour vous. Considérez cela comme à peu près équivalent à hardhat.config.js
sur Ethereum.
Maintenant, ouvrez votre éditeur de code, copiez et collez le code ci-dessous dans votre fichier flow.json
.
{ "contracts": { "Collectibles": "./cadence/contracts/Collectibles.cdc", "NonFungibleToken": { "source": "./cadence/contracts/NonFungibleToken.cdc", "aliases": { "testnet": "0x631e88ae7f1d7c20" } } }, "networks": { "testnet": "access.devnet.nodes.onflow.org:9000" }, "accounts": { "testnet-account": { "address": "ENTER YOUR ADDRESS FROM FAUCET HERE", "key": "ENTER YOUR GENERATED PRIVATE KEY HERE" } }, "deployments": { "testnet": { "testnet-account": [ "Collectibles" ] } } }
Collez votre clé privée générée à l'endroit (clé : « ENTREZ VOTRE CLÉ PRIVÉE GÉNÉRÉE ICI ») dans le code.
Maintenant, exécutez le code sur le testnet. Accédez au terminal et exécutez le code suivant :
flow project deploy --network testnet
5. Attendez la confirmation.
Après avoir soumis la transaction, vous recevrez un identifiant de transaction. Attendez que la transaction soit confirmée sur le testnet, indiquant que le contrat intelligent a été déployé avec succès.
Vérifiez votre contrat déployé ici .
Vérifiez le code complet sur GitHub .
Toutes nos félicitations! Vous avez maintenant créé un portail d'objets de collection sur la blockchain Flow et l'avez déployé sur le testnet. Et après? Maintenant, vous pouvez travailler sur la construction du frontend que nous aborderons dans la partie 2 de cette série.
Passez une très bonne journée !
Également publié ici