Crea e distribuisci contratto smart NFT
In questa sezione imparerai come creare e distribuire un contratto smart NFT necessario per configurare il Marketplace NFT.
Utilizzare Blockchain App Builder per generare uno smart contract per gestire la mentazione, la proprietà e il trasferimento di NFT. L'enabler di base di questa soluzione è la possibilità di creare e trasferire NFT utilizzando Oracle Blockchain Platform.
In primo luogo, creare un file di specifica NFT, quindi distribuire lo smart contract a un'istanza di Oracle Blockchain Platform. È quindi possibile testare lo smart contract.
Installa App Builder Blockchain
Dopo aver eseguito il provisioning di un'istanza di Oracle Blockchain Platform, attenersi alla procedura riportata di seguito.
- Nella console di Oracle Blockchain Platform aprire la scheda Strumenti per sviluppatori e selezionare il riquadro Builder delle applicazioni blockchain.
- Nella sezione Download scaricare l'archivio degli strumenti dell'interfaccia a riga di comando (CLI) o l'estensione del codice Visual Studio (VS) e impostarla localmente.
Personalizzare il file di specifica NFT di esempio
Un file di specifica NFT di esempio è incluso in Blockchain App Builder. È possibile utilizzarlo e adattarlo alle proprie esigenze, come mostrato nell'esempio riportato di seguito.
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 gatewayÈ possibile aggiungere proprietà e metodi personalizzati per estendere questa specifica per il codice concatenato NFT. I codici concatenati NFT generati da Blockchain App Builder si basano sullo standard ERC-721.
Per generare il codice concatenato (contratto intelligente) utilizzando l'estensione Codice di Visual Studio, attenersi alla procedura riportata di seguito.
- Nella sezione Chaincodes, fare clic sull'icona +. Viene visualizzato il riquadro Dettagli codice fiscale.
- Completare i campi necessari per generare il progetto con codice concatenato.
- Immettere un nome per il progetto codice concatenato.
- Selezionare
TypeScriptoGocome lingua in cui generare i metodi del codice concatenato. - Selezionare il file della specifica di input creato in precedenza.
- Inserire l'ubicazione in cui si desidera generare il progetto.
- Fare clic su Crea.
L'immagine seguente dell'interfaccia utente mostra la finestra Crea codice concatenato.

Descrizione dell'immagine blockchain_chaincode_details.png
src nella gerarchia di progetti.
- Il file modello contiene tutte le strutture dati generate che rappresentano il token, i conti e così via.
- Il file controller contiene tutti i metodi del ciclo di vita NFT generati e le funzioni di supporto con la logica di convalida richiesta in base alla specifica.
/**
*
* 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);
}
}
}
Distribuire il contratto smart
Dopo aver creato un progetto con codice concatenato, puoi distribuirlo localmente.
Nel riquadro Dettagli codice fiscale selezionare Distribuisci per aprire la distribuzione guidata. Blockchain App Builder include una rete di blockchain locale, che viene eseguita nei container Docker, che è possibile utilizzare per finalità di test.
È anche possibile distribuire il codice concatenato in un'istanza di Oracle Blockchain Platform selezionando il profilo di connessione dalla lista per l'ambiente di destinazione. È inoltre necessario completare e salvare i parametri di inizializzazione, poiché il codice concatenato NFT generato richiede i parametri orgId e userId per l'inizializzazione. I parametri orgId e userId vengono utilizzati per specificare gli utenti con privilegi di amministratore token.
Test del contratto smart
Quando il codice concatenato viene distribuito, Oracle Blockchain Platform espone automaticamente le API REST per l'inizializzazione dei token, la gestione di account e ruoli e i metodi del ciclo di vita NFT (creazione, trasferimento, masterizzazione).
È possibile eseguire il test selezionando Esegui nel riquadro Dettagli codice tariffa in Blockchain App Builder oppure utilizzando un client API REST, ad esempio Postman.
L'immagine seguente dell'interfaccia utente mostra la scheda Esegui della finestra Crea codice concatenato.

Descrizione dell'immagine blockchain_chaincode_execute.png
Per richiamare i metodi di smart contract di Oracle Blockchain Platform mediante l'API REST, utilizzare il metodo POST e specificare l'URL, composto da due parti concatenate insieme. La prima parte è l'endpoint proxy REST di Oracle Blockchain Platform, che è possibile ottenere dalla scheda Nodi della console di Oracle Blockchain Platform.
La seconda parte è l'URI specifico per richiamare la transazione utilizzando l'API Transaction. Consulta la documentazione per inviare una richiesta POST. Le due parti formano un URL completo simile a quello qui.
https://oabcs1-iad.blockchain.ocp.oraclecloud.com:7443/restproxy/api/v2/channels/{channelName}/transactionsSostituire {channelName} con il nome del canale specificato durante la distribuzione del codice concatenato, ad esempio marketplace. Durante la creazione della richiesta API, attenersi alla procedura riportata di seguito.
- Impostare l'autorizzazione per utilizzare
Basic Authcon il valoreuserid and passwordspecificato mappato al ruoloREST_Client. È inoltre possibile utilizzare i tokenOAuth2. Per ulteriori informazioni, vedere Usare OAuth 2.0 Access Token Based Authentication nella guida delle API REST. - Impostare l'intestazione
Content-Typesuapplication/json. - Nel corpo della richiesta, includere i parametri necessari per il richiamo della transazione, inclusi il nome del codice concatenato e il metodo
create<TokenName>Tokeninsieme agli argomenti richiesti.
In base al codice concatenato generato dal modello yaml, il testo seguente mostra un corpo della richiesta campione e la risposta associata.
Richiesta
{
"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
}
Risposta
{
"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
},Per ulteriori informazioni sui metodi disponibili per la gestione dei codici concatenati NFT, inclusi i metodi Golang o TypeScript e Platform REST API, vedere la sezione Esplora altro.
È possibile richiamare le API direttamente dal webhook Oracle Content Management e dall'applicazione Web creata su Visual Builder Cloud Service (VBCS) oppure rimapparle con il gateway API per l'uso da parte di un'applicazione Web del marketplace ospitato esternamente. Tenere presente che quando si crea (suggerimento) un NFT, uno dei parametri da fornire è token_uri, che può essere un IPFS URI che punta a un file JSON che rappresenta l'oggetto digitale.
https://ipfs.io/ipfs/QmV68aiT7xw2WX8pmDbeTWpGP2or35NUFan9RagymsLpgV?filename=ArtCollection_NFT1.jsonI passi seguenti descrivono un esempio di generazione dell'URI del token mediante IPFS Desktop:
- Caricare un file immagine su
IPFSe salvare l'URI dell'immagine. - Creare e caricare il file
JSONche include l'URI dell'immagine insieme ai campi di metadati pertinenti. - Condividere e copiare il collegamento nel file
JSONsotto ... Altro elenco.
{
"painting_name": "Oracle - Red Bull Partnership",
"description": "Cloud Partnership",
"image": "https://ipfs.io/ipfs/QmVap6Gkh3Cp9DiLLWvkvJHpuXpFmYB2GzU1caM57gNcAa?filename=Oracle_RedBull.jpeg",
"painter_name": "Alex"
}
Utilizzare l'URI che punta al file JSON per il parametro token_uri.
È inoltre possibile includere metadati pertinenti negli attributi passati al metodo create<Token-Name>Token, che gestiranno i metadati nel libro contabile di Oracle Blockchain Platform per un facile recupero.
Per i NFT creati utilizzando Oracle Content Management (OCM), utilizzare il webhook OCM per chiamare Oracle Functions mediante un gateway API e collocare il richiamo dell'API REST in Oracle Functions come mostrato nel diagramma dell'architettura. Puoi anche richiamare le API REST della blockchain direttamente dall'applicazione Web del marketplace o utilizzando un mapping del gateway API per supportare i contenuti generati dagli utenti. La funzionalità di trading di Marketplace può richiamare i metodi personalizzati per gestire il pagamento e quindi attivare un trasferimento della proprietà NFT, ad esempio i metodi di esempio buyWithTokens e buyWithDirectPayment.