Créer et déployer un contrat intelligent NFT
Cette section explique comment créer et déployer un contrat intelligent NFT nécessaire au paramétrage de la place de marché NFT.
Utilisez Blockchain App Builder pour générer un contrat intelligent permettant de gérer la détection, la détention et le transfert de transactions NFT. L'élément clé de cette solution est la possibilité d'extraire et de transférer des NFT à l'aide d'Oracle Blockchain Platform.
Commencez par créer un fichier de spécification NFT, puis déployez le contrat intelligent vers une instance Oracle Blockchain Platform. Vous pouvez ensuite tester le contrat intelligent.
Installer Blockchain App Builder
Après avoir provisionné une instance Oracle Blockchain Platform, procédez comme suit :
- Dans la console Oracle Blockchain Platform, ouvrez l'onglet Outils de développeur, puis sélectionnez le panneau Blockchain App Builder.
- Dans la section Télécharger, téléchargez l'archive d'outils de l'interface de ligne de commande (CLI) ou l'extension de code Visual Studio (VS), puis configurez-la localement.
Personnaliser l'exemple de fichier de spécification NFT
Un exemple de fichier de spécification NFT est inclus dans Blockchain App Builder. Vous pouvez l'utiliser et l'adapter à vos besoins, comme indiqué dans l'exemple suivant :
assets:
- name: ArtCollection
type: token
symbol: ART #mandatory
standard: erc721+
anatomy:
type: nonfungible
unit: whole
behavior:
- indivisible # mandatory
- singleton # mandatory
- mintable: # mandatory
max_min_quantity: 20000
- transferable
- burnable
- roles:
minter_role_name: minter
properties:
- name: price
type: number
- name: on_sale_flag
type: boolean
metadata:
- name: painting_name
type: string
- name: description
type: string
- name: image
type: string
- name: painter_name
type: string
customMethods:
- executeQuery
- "createAccountByConsumers(org_id: string, user_id: string, token_type: string)" # Create accounts for consumers while signing up
- "sell(token_id: string, selling_price: number)" # Post the token for selling in the marketplace
- "buyWithTokens(from_org_id: string, from_user_id: string, to_org_id: string, to_user_id: string, nonfungible_token_id: string, fungible_token_id: string, amount_paid: number)" # Buy the NFT after paying the using FT Tokens
- "buyWithDirectPayment(from_org_id: string, from_user_id: string, to_org_id: string, to_user_id: string, nonfungible_token_id: string, amount_paid: number)" # Buy the NFT after paying the amount using payment gatewayVous pouvez ajouter des propriétés et des méthodes personnalisées pour étendre cette spécification pour le code chaîne NFT. Les codes chaîne NFT générés par Blockchain App Builder sont basés sur la norme ERC-721.
Pour générer le code chaîne (contrat intelligent) à l'aide de l'extension Visual Studio Code, procédez comme suit :
- Dans la section Codes chaîne, cliquez sur l'icône +. Le panneau Détails du code chaîne s'ouvre.
- Remplissez les champs requis pour générer le projet de code chaîne :
- Entrez le nom du projet de code chaîne.
- Sélectionnez
TypeScriptouGoen tant que langage dans lequel générer les méthodes de code chaîne. - Sélectionnez le fichier de spécification d'entrée que vous avez créé précédemment.
- Saisissez le lieu de génération du projet.
- Cliquez sur Créer.
La capture d'écran suivante de l'interface utilisateur montre la fenêtre Créer un code chaîne.

Description de l'image Blockchain_chaincode_details.png
src dans la hiérarchie du projet.
- Le fichier modèle contient toutes les structures de données générées représentant le jeton, les comptes, etc.
- Le fichier de contrôleur contient toutes les méthodes de cycle de vie NFT générées et les fonctions de prise en charge avec la logique de validation requise en fonction de la spécification.
/**
*
* BDB sql rich queries can be executed in OBP CS/EE.
* This method can be invoked only when connected to remote OBP CS/EE network.
*
*/
@Validator(yup.string())
public async executeQuery(query: string) {
const result = await this.query(query);
return result;
}
@Validator(yup.string(), yup.string(), yup.string())
public async createAccountByConsumers(org_id: string, user_id: string, token_type: string) {
//await this.Ctx.ERC721Auth.checkAuthorization('ERC721ACCOUNT.createAccount', 'TOKEN');
return await this.Ctx.ERC721Account.createAccount(org_id, user_id, token_type);
}
@Validator(yup.string(), yup.number())
public async sell (token_id: string, selling_price: number) {
try {
const token = await this.Ctx.ERC721Token.get(token_id);
const t = new ArtCollection(token)
t.price = selling_price;
t.on_sale_flag = true;
//console.log(token);
await this.Ctx.ERC721Token.update(t);
return `Token ID : '${token_id}' has been posted for selling in the marketplace'`;
} catch(error) {
throw new Error(error.message);
}
}
@Validator(yup.string(), yup.string(), yup.string(), yup.string(), yup.string(), yup.string(), yup.number())
public async buyWithTokens(from_org_id: string, from_user_id: string, to_org_id: string, to_user_id: string, nonfungible_token_id: string, fungible_token_id: string, amount_paid: number) {
try {
const token = await this.Ctx.ERC721Token.get(nonfungible_token_id);
const t = new ArtCollection(token);
const oChainUtil = new OChainUtils(this.Ctx.Stub);
var msg = `Token ID : '${nonfungible_token_id}' had not been transferred'`;
if (t.on_sale_flag==true) {
if(t.price == amount_paid) {
// @ts-ignore
await oChainUtil.invokeChaincode("LoyaltyToken7", "transferTokens", [fungible_token_id, from_org_id, from_user_id, amount_paid], "marketplace");
const from_account_id = await this.Ctx.ERC721Account.generateAccountId(from_org_id, from_user_id);
const to_account_id = await this.Ctx.ERC721Account.generateAccountId(to_org_id, to_user_id);
await this.Ctx.ERC721Token.transferFrom(from_account_id, to_account_id, t);
msg = `Token ID : '${nonfungible_token_id}' has been successfully transferred to UserID : '${to_user_id}'`;
}
}
else {
msg = `Token ID : '${nonfungible_token_id}' has not been transferred to UserID : '${to_user_id}' as the amount was not fully paid'`;
}
return msg;
} catch(error)
{
throw new Error(error.message);
}
}
@Validator(yup.string(), yup.string(), yup.string(), yup.string(), yup.string(), yup.number())
public async buyWithDirectPayment(from_org_id: string, from_user_id: string, to_org_id: string, to_user_id: string, nonfungible_token_id: string, amount_paid: number) {
try {
const token = await this.Ctx.ERC721Token.get(nonfungible_token_id);
const t = new ArtCollection(token);
var msg = `Token ID : '${nonfungible_token_id}' had not been transferred'`;
if (t.on_sale_flag==true) {
if(t.price == amount_paid) {
const from_account_id = await this.Ctx.ERC721Account.generateAccountId(from_org_id, from_user_id);
const to_account_id = await this.Ctx.ERC721Account.generateAccountId(to_org_id, to_user_id);
await this.Ctx.ERC721Token.transferFrom(from_account_id, to_account_id, t);
msg = `Token ID : '${nonfungible_token_id}' has been successfully transferred to UserID : '${to_user_id}'`;
}
}
else {
msg = `Token ID : '${nonfungible_token_id}' has not been transferred to UserID : '${to_user_id}' as the amount was not fully paid'`;
}
return msg;
} catch(error) {
throw new Error(error.message);
}
}
}
Déployer le contrat intelligent
Après avoir créé un projet de code chaîne, vous pouvez le déployer localement.
Dans le panneau Détails du code chaîne, sélectionnez Déployer pour ouvrir l'assistant de déploiement. Blockchain App Builder inclut un réseau de chaîne de blocs local, qui s'exécute dans les conteneurs Docker, que vous pouvez utiliser à des fins de test.
Vous pouvez également déployer le code chaîne vers une instance Oracle Blockchain Platform en sélectionnant le profil de connexion dans la liste pour l'environnement cible. Vous devez également terminer et enregistrer les paramètres d'initialisation, car le code chaîne NFT généré requiert les paramètres orgId et userId pour l'initialisation. Les paramètres orgId et userId permettent d'indiquer les utilisateurs disposant de privilèges d'administrateur de jeton.
Tester le contrat intelligent
Lorsque le code chaîne est déployé, Oracle Blockchain Platform expose automatiquement les API REST pour l'initialisation du jeton, la gestion des comptes et des rôles, ainsi que les méthodes de cycle de vie NFT (création, transfert, brûlure).
Vous pouvez effectuer un test en sélectionnant Exécuter dans le panneau Détails du code chaîne dans Blockchain App Builder, ou en utilisant un client d'API REST tel que Postman.
La capture d'écran suivante de l'interface utilisateur montre l'onglet Exécuter de la fenêtre Créer un code chaîne.

Description de l'image Blockchain_chaincode_execute.png
Pour appeler des méthodes de contrat intelligent Oracle Blockchain Platform à l'aide de l'API REST, utilisez la méthode POST et indiquez l'URL, composée de deux parties concaténées ensemble. La première partie est l'adresse de proxy REST dans Oracle Blockchain Platform, que vous pouvez obtenir à partir de l'onglet Noeuds de la console Oracle Blockchain Platform.
La deuxième partie est l'URI spécifique permettant d'appeler la transaction à l'aide de l'API Transaction. Reportez-vous à la documentation pour envoyer une demande POST. Les deux parties forment une URL complète similaire à celle ici.
https://oabcs1-iad.blockchain.ocp.oraclecloud.com:7443/restproxy/api/v2/channels/{channelName}/transactionsRemplacez {channelName} par le nom du canal indiqué lors du déploiement de votre code chaîne, tel que marketplace. Lors de la construction de la demande d'API, procédez comme suit :
- Définissez l'autorisation pour utiliser
Basic Authavec l'élémentuserid and passwordindiqué qui est mappé avec le rôleREST_Client. Vous pouvez également utiliser des jetonsOAuth2. Pour plus d'informations, reportez-vous à Utilisation de l'authentification par jeton d'accès OAuth 2.0 dans le guide de l'API REST. - Définissez l'en-tête
Content-Typesurapplication/json. - Dans le corps de la demande, incluez les paramètres requis pour l'appel de transaction, y compris le nom du code chaîne et la méthode
create<TokenName>Token, ainsi que les arguments requis.
En fonction du code chaîne généré à partir du modèle yaml, le texte suivant présente un exemple de corps de demande et la réponse associée.
Demande
{
"chaincode": "{{NFTChaincode}}",
"args": [
"createArtCollectionToken",
"{\"token_id\":\"{{NFTTokenID}}\",\"token_uri\":\"https://ipfs.io/ipfs/QmV68aiT7xw2WX8pmDbeTWpGP2or35NUFan9RagymsLpgV?filename=ArtCollection_NFT1.json\",\"metadata\":{\"painting_name\":\"Oracle - Red Bull Partnership\",\"image\":\"https://ipfs.io/ipfs/QmVap6Gkh3Cp9DiLLWvkvJHpuXpFmYB2GzU1caM57gNcAa?filename=Oracle_RedBull_NFT1.jpeg\",\"painter\":\"Alex\"},\"price\":200,\"on_sale_flag\":false}"
],
"timeout": 0,
"sync": true
}
Réponse
{
"returnCode": "Success",
"error": "",
"result": {
"txid": "c999922f04c3011bf25ca43624e4bb23e8900634f8e23a1648170a90274a9733",
"payload": {
"metadata": {
"painter": "Alex",
"painting_name": "Oracle - Red Bull Partnership",
"image": "https://ipfs.io/ipfs/QmVap6Gkh3Cp9DiLLWvkvJHpuXpFmYB2GzU1caM57gNcAa?filename=Oracle_RedBull_NFT1.jpeg"
},
"assetType": "otoken",
"created_by": "oaccount~eadf1b0ae857164f8681d1742b6328089a7d33ebec76d8248cb909da7a84f42a",
"creation_date": "2022-04-28T12:08:38.000Z",
"owner": "oaccount~eadf1b0ae857164f8681d1742b6328089a7d33ebec76d8248cb909da7a84f42a",
"uri": "https://ipfs.io/ipfs/QmV68aiT7xw2WX8pmDbeTWpGP2or35NUFan9RagymsLpgV?filename=ArtCollection_NFT1.json",
"is_burned": false,
"token_id": "NFT17",
"token_name": "artcollection",
"symbol": "ART",
"token_standard": "erc721+",
"token_type": "nonfungible",
"token_unit": "whole",
"behaviors": [
"indivisible",
"singleton",
"mintable",
"transferable",
"burnable",
"roles"
],
"roles": {
"minter_role_name": "minter"
},
"mintable": {
"max_mint_quantity": 20000
},
"token_uri": "https://ipfs.io/ipfs/QmV68aiT7xw2WX8pmDbeTWpGP2or35NUFan9RagymsLpgV?filename=ArtCollection_NFT1.json",
"price": 200,
"on_sale_flag": false
},Reportez-vous à la section Découvrir plus pour plus d'informations sur les méthodes disponibles pour la gestion des codes chaîne NFT, y compris les méthodes Golang ou TypeScript et Platform REST API.
Vous pouvez appeler les API directement à partir du webhook Oracle Content Management et de l'application Web basée sur Visual Builder Cloud Service (VBCS), ou les remapper et les encapsuler avec la passerelle d'API pour les utiliser par une application Web Marketplace hébergée en externe. Notez que lorsque vous créez (mint) un NFT, l'un des paramètres que vous devez fournir est token_uri, qui peut être un IPFS URI pointant vers un fichier JSON qui représente l'objet numérique.
https://ipfs.io/ipfs/QmV68aiT7xw2WX8pmDbeTWpGP2or35NUFan9RagymsLpgV?filename=ArtCollection_NFT1.jsonLes étapes suivantes décrivent un exemple de génération de l'URI de jeton à l'aide du bureau IPFS :
- Téléchargez un fichier image sur
IPFSet enregistrez l'URI de l'image. - Créez et téléchargez le fichier
JSONqui inclut l'URI de l'image, ainsi que les champs de métadonnées pertinents. - Partagez et copiez le lien vers le fichier
JSONsous ... Plus liste.
{
"painting_name": "Oracle - Red Bull Partnership",
"description": "Cloud Partnership",
"image": "https://ipfs.io/ipfs/QmVap6Gkh3Cp9DiLLWvkvJHpuXpFmYB2GzU1caM57gNcAa?filename=Oracle_RedBull.jpeg",
"painter_name": "Alex"
}
Utilisez l'URI qui pointe vers le fichier JSON pour le paramètre token_uri.
Vous pouvez également inclure des métadonnées pertinentes dans les attributs transmis à la méthode create<Token-Name>Token, qui maintiendront les métadonnées dans le registre Oracle Blockchain Platform pour faciliter leur extraction.
Pour les transactions NFT créées à l'aide d'Oracle Content Management (OCM), utilisez le webhook OCM pour appeler Oracle Functions à l'aide d'une passerelle d'API et placez l'appel d'API REST dans Oracle Functions comme indiqué dans le diagramme de l'architecture. Vous pouvez également appeler les API REST Blockchain directement à partir de l'application Web Marketplace ou à l'aide d'un mappage de passerelle d'API pour prendre en charge le contenu généré par l'utilisateur. La fonctionnalité de négociation Marketplace peut appeler les méthodes personnalisées pour gérer le paiement, puis déclencher un transfert de propriété NFT, comme les exemples de méthodes buyWithTokens et buyWithDirectPayment.