Creación y despliegue de contrato inteligente NFT
En esta sección aprenderá a crear y desplegar un contrato inteligente de NFT necesario para configurar NFT Marketplace.
Utilice el creador de aplicaciones de cadena de bloques para generar un contrato inteligente con el fin de gestionar la creación, la propiedad y la transferencia de NFT. El elemento clave de esta solución es la capacidad de combinar y transferir NFT mediante Oracle Blockchain Platform.
En primer lugar, cree un archivo de especificación NFT y, a continuación, despliegue el contrato inteligente en una instancia de Oracle Blockchain Platform. A continuación, puede probar el contrato inteligente.
Instalar creador de aplicaciones de cadena de bloques
Después de aprovisionar una instancia de Oracle Blockchain Platform, realice los siguientes pasos:
- En la consola de Oracle Blockchain Platform, abra el separador Herramientas para desarrolladores y, a continuación, seleccione el panel Creador de aplicaciones de cadena de bloques.
- En la sección Descargar, descargue el archivo de herramientas de la interfaz de línea de comandos (CLI) o la extensión de código de Visual Studio (VS) y, a continuación, configúrelo localmente.
Personalizar el archivo de especificación de NFT de muestra
Se incluye un archivo de especificación NFT de ejemplo con Blockchain App Builder. Puede utilizarlo y adaptarlo a sus necesidades, como se muestra en el siguiente ejemplo:
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
Puede agregar propiedades y métodos personalizados para ampliar esta especificación para el código de cadena NFT. Los códigos de cadenas de NFT generados por Blockchain App Builder se basan en el estándar ERC-721
.
Para generar el código de cadena (contrato inteligente) mediante la extensión Visual Studio Code, realice los siguientes pasos:
- En la sección Códigos de dominio, haga clic en el icono +. Se abre el panel Detalles de código de dominio.
- Rellene los campos necesarios para generar el proyecto de código de cadena:
- Introduzca un nombre para el proyecto de código de cadena.
- Seleccione
TypeScript
oGo
como el idioma en el que desea generar los métodos de código de cadenas. - Seleccione el archivo de especificación de entrada que creó anteriormente.
- Introduzca la ubicación en la que desea generar el proyecto.
- Haga clic en Crear.
En la siguiente captura de pantalla de la interfaz de usuario se muestra la ventana Crear código de cadena.

Descripción de la ilustración Blockchain_chaincode_details.png
src
de la jerarquía del proyecto.
- El archivo de modelo contiene todas las estructuras de datos generadas que representan el token, las cuentas, etc.
- El archivo de controlador contiene todos los métodos de ciclo de vida de NFT generados y las funciones de soporte con la lógica de validación necesaria basada en la especificación.
/**
*
* 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);
}
}
}
Despliegue del contrato inteligente
Después de crear un proyecto de código de cadenas, puede desplegarlo localmente.
En el panel Detalles de código de dominio, seleccione Desplegar para abrir el asistente de despliegue. Blockchain App Builder incluye una red de cadenas de bloques local, que se ejecuta en contenedores de Docker, que puede utilizar con fines de prueba.
También puede desplegar el código de cadena en una instancia de Oracle Blockchain Platform seleccionando el perfil de conexión de la lista para el entorno de destino. También debe completar y guardar los parámetros de inicialización, porque el código de cadena NFT generado requiere los parámetros orgId
y userId
para la inicialización. Los parámetros orgId
y userId
se utilizan para especificar qué usuarios tienen privilegios de administrador de token.
Prueba del contrato inteligente
Cuando se despliega el código de cadenas, Oracle Blockchain Platform expone automáticamente las API de REST para la inicialización de tokens, la gestión de cuentas y roles, y los métodos de ciclo de vida de NFT (crear, transferir, grabar).
Puede realizar la prueba seleccionando Ejecutar en el panel Detalles de código de dominio en el creador de aplicaciones de cadena de bloques o utilizando un cliente de API de REST como Postman.
En la siguiente captura de pantalla de la interfaz de usuario se muestra el separador Ejecutar de la ventana Crear código de cadena.

Descripción de la ilustración Blockchain_chaincode_execute.png
Para llamar a métodos de contrato inteligente de Oracle Blockchain Platform mediante la API de REST, utilice el método POST
y especifique la URL, que consta de dos partes concatenadas juntas. La primera parte es el punto final de proxy de REST en Oracle Blockchain Platform, que puede obtener del separador Nodos de la consola de Oracle Blockchain Platform.
La segunda parte es el URI específico para llamar a la transacción mediante la API Transaction. Consulte la documentación para enviar una solicitud POST
. Las dos partes forman una URL completa similar a la que aparece aquí.
https://oabcs1-iad.blockchain.ocp.oraclecloud.com:7443/restproxy/api/v2/channels/{channelName}/transactions
Sustituya {channelName}
por el nombre del canal especificado al desplegar el código de cadena, como marketplace. Al crear la solicitud de API, realice los siguientes pasos:
- Defina la autorización para utilizar
Basic Auth
con eluserid and password
especificado que está asignado al rolREST_Client
. También puede utilizar tokensOAuth2
. Consulte Uso de la autenticación basada en token de acceso OAuth 2.0 en la guía de la API de REST para obtener más información. - Defina la cabecera
Content-Type
enapplication/json
. - En el cuerpo de la solicitud, incluya los parámetros necesarios para la llamada a la transacción, incluido el nombre del código de cadena y el método
create<TokenName>Token
junto con los argumentos necesarios.
Según el código de cadena generado a partir de la plantilla yaml
, el siguiente texto muestra un cuerpo de solicitud de ejemplo y la respuesta asociada.
Solicitud
{
"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
}
Respuesta
{
"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
},
Consulte la sección Explorar más para obtener más información sobre los métodos disponibles para gestionar códigos de cadenas de NFT, incluidos los métodos Golang
o TypeScript
y Platform REST API
.
Puede llamar a las API directamente desde el webhook de Oracle Content Management y la aplicación web creada sobre Visual Builder Cloud Service (VBCS), o bien reasignarlas y encapsularlas con el gateway de API para que las utilice una aplicación web de Marketplace alojada externamente. Tenga en cuenta que al crear (minutos) un NFT, uno de los parámetros que debe proporcionar es token_uri
, que puede ser IPFS URI
que apunta a un archivo JSON
que representa el objeto digital.
https://ipfs.io/ipfs/QmV68aiT7xw2WX8pmDbeTWpGP2or35NUFan9RagymsLpgV?filename=ArtCollection_NFT1.json
Los siguientes pasos describen un ejemplo de generación del URI de token mediante IPFS Desktop:
- Cargue un archivo de imagen en
IPFS
y guarde el URI de la imagen. - Cree y cargue el archivo
JSON
que incluye el URI de imagen junto con los campos de metadatos relevantes. - Comparta y copie el enlace al archivo
JSON
en ... Lista de más.
{
"painting_name": "Oracle - Red Bull Partnership",
"description": "Cloud Partnership",
"image": "https://ipfs.io/ipfs/QmVap6Gkh3Cp9DiLLWvkvJHpuXpFmYB2GzU1caM57gNcAa?filename=Oracle_RedBull.jpeg",
"painter_name": "Alex"
}
Utilice el URI que apunta al archivo JSON
para el parámetro token_uri
.
También puede incluir metadatos relevantes en los atributos que se transfieren al método create<Token-Name>Token
, que mantendrá los metadatos en el libro mayor de Oracle Blockchain Platform para una fácil recuperación.
Para los NFT creados mediante Oracle Content Management (OCM), utilice el webhook de OCM para llamar a Oracle Functions mediante un gateway de API y colocar la llamada a la API de REST en Oracle Functions como se muestra en el diagrama de arquitectura. También puede llamar a las API de REST de cadena de bloques directamente desde la aplicación web de Marketplace o utilizando una asignación de gateway de API para soportar contenido generado por el usuario. La funcionalidad de comercio de Marketplace puede invocar los métodos personalizados para manejar el pago y, a continuación, disparar una transferencia de la propiedad de NFT, como los métodos de ejemplo buyWithTokens
y buyWithDirectPayment
.