El primer paso que tomará para construir una Dapp de acuñación de NFT es preparar la obra de arte. Sin la obra de arte, no puede actualizar su proyecto NFT. Otra razón para preprocesar sus obras de arte es generar metadatos para cada una de las imágenes. Sin estos metadatos, su NFT no se puede vender en ninguno de los grandes mercados secundarios, como Opensea. Por ejemplo, la imagen a continuación es un NFT en el mercado de Opensea que contiene algunos metadatos que también se pueden ver a continuación. La información anterior, incluida la obra de arte, sus detalles y características, se puede ver en la imagen de IPFS a continuación. Configuración de dependencias del proyecto Abra su terminal y navegue hasta el directorio de su proyecto o cree una carpeta de proyecto en una ubicación específica. Por ejemplo, ejecutar en la terminal creará una carpeta llamada " en su ubicación especificada. **mkdir preprocessor** preprocesador" A continuación, ejecute los siguientes comandos en la terminal. cd preprocessor npm init -y npm install sharp @faker.js/faker --save-dev Los comandos anteriores instalarán las bibliotecas y en su proyecto. La biblioteca faker nos ayudará a generar información aleatoria. Mientras que la biblioteca nítida nos ayudará a procesar la imagen a una determinada dimensión, calidad y formato. Sharp Faker A continuación, crea una carpeta en tu proyecto llamada y otra llamada . En la carpeta "artes", coloque todas las imágenes para procesar dentro. arts outputs Una vez realizados los pasos anteriores, abra el proyecto en "código VS". La estructura del proyecto debe parecerse a la siguiente. - preprocessor/ - arts/ - node_modules/ - outputs/ - package.json - package-lock.json Genial, pasemos a codificar el motor encargado de procesar las imágenes. requisitos previos Necesitará lo siguiente instalado en su computadora para completar este tutorial. NodeJs Aplicación de escritorio IPFS Código VS Codificación del motor de procesamiento Cree un archivo en la raíz de su proyecto llamado y pegue el siguiente código **imagify.js** const fs = require('fs') const path = require('path') const sharp = require('sharp') const { faker } = require('@faker-js/faker') const input = './arts' const output = './outputs' let img_counter = 1 const imgSize = { width: 500, height: 500 } const desired_ext = '.webp' const base_url = 'https://ipfs.io/ipfs/REPLACE_WITH_IPFS_CID/' const attributes = { weapon: [ 'Stick', 'Knife', 'Blade', 'Clube', 'Ax', 'Sword', 'Spear', 'Gun', 'Craft', ], environment: [ 'Space', 'Sky', 'Desert', 'Forest', 'Grassland', 'Moiuntains', 'Oceans', 'Rainforest', ], rarity: Array.from(Array(10).keys()), } fs.readdirSync(input).forEach((file) => { const orginal_ext = path.extname(file) const orginal_file_name = path.basename(file).split('.')[0] if (['.jpg', '.jpeg', '.png', '.gif', '.webp'].includes(orginal_ext)) { const id = img_counter const metadata = { id, name: `Adulam NFT #${id}`, description: 'AI Arts NFTs Collection, Mint and collect the hottest NFTs around.', price: 1, image: base_url + id + desired_ext, demand: faker.random.numeric({ min: 10, max: 100 }), attributes: [ { trait_type: 'Environment', value: attributes.environment.sort(() => 0.5 - Math.random())[0], }, { trait_type: 'Weapon', value: attributes.weapon.sort(() => 0.5 - Math.random())[0], }, { trait_type: 'Rarity', value: attributes.rarity.sort(() => 0.5 - Math.random())[0], max_value: 10, }, { display_type: 'date', trait_type: 'Created', value: Date.now(), }, { display_type: 'number', trait_type: 'generation', value: 1, }, ], } if (fs.existsSync(`${input}/${orginal_file_name + orginal_ext}`)) { sharp(`${input}/${orginal_file_name + orginal_ext}`) .resize(imgSize.height, imgSize.width) .toFile(`${output}/images/${id + desired_ext}`, (err, info) => console.log(err), ) fs.writeFileSync(`${output}/metadata/${id}.json`, JSON.stringify(metadata), { encoding: 'utf-8', flag: 'w', }) } console.log(metadata) img_counter++ } }) Los siguientes pasos lo ayudarán a comprender cómo funciona este motor de procesamiento de metadatos. Importación de bibliotecas esenciales const fs = require('fs') const path = require('path') const sharp = require('sharp') const { faker } = require('@faker-js/faker') const input = './arts' const output = './outputs' El representa el sistema de archivos, es un módulo incorporado que viene con NodeJs. Tiene la responsabilidad de administrar las actividades de lectura y escritura de archivos en su máquina. fs La es otro módulo de nodo que lo ayuda a navegar a través de las estructuras de directorios en su máquina. Esto será fundamental para localizar dónde se guardan nuestras imágenes. path Sharp es el módulo que usamos para procesar la imagen, como cambiar el tamaño y transformar a un tipo de archivo diferente. Usaremos el falsificador para generar un número aleatorio. Por último, la variable de contiene la ubicación donde se encuentran las imágenes a procesar y la apunta a la ubicación donde se guardarán las imágenes procesadas. input output Definición de variables esenciales let img_counter = 1 const imgSize = { width: 500, height: 500 } const desired_ext = '.webp' const base_url = 'https://ipfs.io/ipfs/REPLACE_WITH_IPFS_CID/' const attributes = { weapon: [ 'Stick', 'Knife', 'Blade', 'Clube', 'Ax', 'Sword', 'Spear', 'Gun', 'Craft', ], environment: [ 'Space', 'Sky', 'Desert', 'Forest', 'Grassland', 'Moiuntains', 'Oceans', 'Rainforest', ], rarity: Array.from(Array(10).keys()), } Los códigos anteriores contienen variables importantes que se utilizarán en el curso de la generación de nuestros metadatos. nos ayuda a numerar las imágenes de manera consistente con la iteración actual. **Image_counter** define la dimensión del ancho y el alto de cada imagen a procesar. **ImgSize** habla del formato de archivo que desea que tengan sus imágenes procesadas. **Desired_ext** especifica la ubicación donde se almacenarán las imágenes en el IPFS. **Base_url** contiene más información sobre los metadatos de cada imagen. **Attributes** Ejecutando Tarea Recursiva fs.readdirSync(input).forEach((file) => { if(['.jpg', '.jpeg', '.png', '.gif', '.webp'].includes(orginal_ext)) { // Images and metadata tasks are recursively performed here... } }) En el bloque de código anterior, usamos la biblioteca del sistema de archivos (fs) para recorrer todas las imágenes en la ubicación de (artes). Y para cada una de las imágenes, nos aseguramos de que nuestro motor solo seleccione imágenes de una lista aprobada de extensiones. **input** Realización de la tarea de metadatos const id = img_counter const metadata = { id, name: `Adulam NFT #${id}`, description: 'AI Arts NFTs Collection, Mint and collect the hottest NFTs around.', price: 1, image: base_url + id + desired_ext, demand: faker.random.numeric({ min: 10, max: 100 }), attributes: [ { trait_type: 'Environment', value: attributes.environment.sort(() => 0.5 - Math.random())[0], }, { trait_type: 'Weapon', value: attributes.weapon.sort(() => 0.5 - Math.random())[0], }, { trait_type: 'Rarity', value: attributes.rarity.sort(() => 0.5 - Math.random())[0], max_value: 10, }, { display_type: 'date', trait_type: 'Created', value: Date.now(), }, { display_type: 'number', trait_type: 'generation', value: 1, }, ], } En el bloque de código anterior, proporcionamos valores para cada espacio de metadatos. Por ejemplo, los entornos, las armas y todos los valores de los rasgos se proporcionan de forma aleatoria y dinámica. Realización de la tarea de transformación de imagen if (fs.existsSync(`${input}/${orginal_file_name + orginal_ext}`)) { sharp(`${input}/${orginal_file_name + orginal_ext}`) .resize(imgSize.height, imgSize.width) .toFile(`${output}/images/${id + desired_ext}`, (err, info) => console.log(err), ) fs.writeFileSync(`${output}/metadata/${id}.json`, JSON.stringify(metadata), { encoding: 'utf-8', flag: 'w', }) } console.log(metadata) img_counter++ En el fragmento anterior, usamos el módulo del sistema de archivos nuevamente para ubicar primero cada una de nuestras ilustraciones y cambiar su tamaño a nuestra dimensión especificada (500 x 500). Además, proporcionamos un nuevo nombre en línea con la iteración actual y le dimos la extensión deseada (webp). Cambiar el tamaño y transformar las imágenes en optimizó en gran medida nuestras obras de arte a una altura asombrosa. webp Por ejemplo, donde sometí este motor de preprocesamiento de imágenes a imágenes que suman un tamaño de . El tamaño se redujo a MB para la extensión y para la extensión . Esa enorme reducción de tamaño representa un gran salto en el tiempo de carga de un sitio web de Minting creado con mis imágenes. en este video 99 111MB .webp .png 4.5MB 62MB Por último, a partir del bloque de código anterior, creamos metadatos para cada imagen procesada, con un nombre idéntico y una URL que apunta a la ubicación de la imagen. Estos metadatos son los que implementaremos en IPFS después de procesar las imágenes. JSON Ahora, ejecute el siguiente comando para transformar su imagen. Asegúrese de estar en la carpeta de su proyecto. node imagify.js En este punto, hemos terminado con nuestro motor de imágenes, nuestra carpeta de salida debería tener la siguiente estructura de archivos como resultado. - output/ - images - 1.webp - 2.webp - ...... - metadata - 1.json - 2.json - ...... Subir imágenes y metadatos a IPFS IPFS significa sistema de archivos interplanetarios, es peer-to-peer y descentralizado. No existe una manera fácil de extraer datos almacenados en IPFS y, como tal, es un par casi perfecto para usar junto con sus aplicaciones de cadena de bloques para almacenar contenido multimedia. Para usar la forma fácil y menos confusa, diríjase a la página de instalación de la aplicación IPFS Desktop y siga las instrucciones especificadas allí. Después de que la instalación sea exitosa, abra la aplicación IPFS y cargue PRIMERO, y repito, PRIMERO cargue la carpeta de imágenes. Se generará una cadena CID (Identificación de contenido) única como parte del nombre de la carpeta, vea la imagen a continuación. Ahora, copie el CID de la carpeta de imágenes como se puede ver en la imagen de arriba, y reemplácelo en su código . Vea el código a continuación. **imagify.js** const base_url = "https://ipfs.io/ipfs/REPLACE_WITH_IPFS_CID/" //old string const base_url = "https://ipfs.io/ipfs/QmY1zrFibpdHQ7qcqZqq7THsqTremZYepXNWR5Au3MF1ST/" //new string Ahora, ejecute nuevamente para incluir la ubicación precisa de cada imagen en sus metadatos . Vea un ejemplo de los metadatos JSON generados antes y después del reemplazo del CID. **node imagify.js** JSON Puede ver este video para comprender cómo utilicé estas imágenes y metadatos en un proyecto completo de acuñación de NFT. https://www.youtube.com/watch?v=QN3wb_mXBjY?embedable=true Antes del reemplazo de CID { id: 97, name: 'Adulam NFT #97', description: 'AI Arts NFTs Collection, Mint and collect the hottest NFTs around.', price: 1, image: 'https://ipfs.io/ipfs/REPLACE_WITH_IPFS_CID/97.webp', demand: '4', attributes: [ { trait_type: 'Environment', value: 'Forest' }, { trait_type: 'Weapon', value: 'Craft' }, { trait_type: 'Rarity', value: 4, max_value: 10 }, { display_type: 'date', trait_type: 'Created', value: 1664478034024 }, { display_type: 'number', trait_type: 'generation', value: 1 } ] } Después del reemplazo de CID { id: 97, name: 'Adulam NFT #97', description: 'AI Arts NFTs Collection, Mint and collect the hottest NFTs around.', price: 1, image: 'https://ipfs.io/ipfs/QmY1zrFibpdHQ7qcqZqq7THsqTremZYepXNWR5Au3MF1ST/97.webp', demand: '7', attributes: [ { trait_type: 'Environment', value: 'Moiuntains' }, { trait_type: 'Weapon', value: 'Clube' }, { trait_type: 'Rarity', value: 2, max_value: 10 }, { display_type: 'date', trait_type: 'Created', value: 1664478110287 }, { display_type: 'number', trait_type: 'generation', value: 1 } ] } Finalmente, como se muestra en la imagen a continuación, suba la carpeta de metadatos a IPFS junto con la carpeta de imágenes. Fantástico, ahora fijémoslo en la web para que el mundo lo vea. Actualmente, ambas carpetas se encuentran en su nodo IPFS local (su computadora), para que sea accesible en todo el mundo, debe usar un servicio de fijación como . Pinata Anclar sus carpetas a IPFS Primero, dirígete al y regístrate si no lo has hecho antes. Luego haga clic en el icono de la cuenta y seleccione Claves API. Vea la imagen a continuación. administrador de pines de Pinata En la página de creación de claves, haga clic en crear una nueva clave e ingrese el nombre de la clave. Observa la imagen de abajo. Ahora copie la clave JWT en su portapapeles. Esto es lo que usaremos para vincular nuestro IPFS Desktop con nuestra cuenta de Pinata. Vea la imagen a continuación. A continuación, abra su aplicación de escritorio IPFS, diríjase a la pestaña de configuración y agregue un nuevo servicio, seleccione Pinata y pegue su token JWT en el espacio proporcionado. Consulte la imagen a continuación. Lo último que debe hacer es anclar sus carpetas a Pinata usando las instrucciones a continuación. Dirígete a la pestaña de archivos, haz clic en la línea de puntos triples y selecciona establecer fijación. Esto aparecerá en la imagen de abajo. Seleccione Pinata y aplique, al hacerlo, su carpeta de imágenes será accesible globalmente. Confirmación de la accesibilidad de la imagen global Diríjase a este sitio web, copie y pegue su CID en el campo de entrada de IPFS y haga clic en el botón de caché. Esto escanea todo el conjunto de puertas de enlace IPFS disponibles públicamente en busca de sus imágenes. Vea la imagen a continuación. Los resultados de la imagen de arriba muestran que muchos nodos IPFS ahora tienen copias de la carpeta de imágenes disponibles y accesibles globalmente, incluso si eliminó la copia original en su nodo local. Con los pasos claramente descritos para usted, también ancle la carpeta de metadatos para que estén disponibles públicamente en línea. Ahora puede usar cualquiera de los enlaces en la imagen de arriba como su URL base para tokens . Vea la imagen a continuación. ERC721 Y ahí lo tienes, así es como preparar y cargar tus obras de arte en IPFS. Conclusión Siempre encontrará la necesidad de comprender cómo preprocesar y cargar obras de arte en el IPFS a escala de lotes. Una vez que comprenda cómo trabajar y procesar imágenes en IPFS, puede comenzar a usarlo en sus proyectos web3 especiales. ¡Hasta la próxima, sigue aplastándolo! Vea el uso de demostración en vivo en mi proyecto NFT en la red de prueba de Goerli . Vea la ubicación de Opensea . Puedes ver la versión en video en mi canal de YouTube. aquí aquí https://www.youtube.com/watch?v=YzurgMLwFVQ?embedable=true Sobre el Autor Soy un desarrollador de blockchain de pila completa con más de años de experiencia en la industria del desarrollo de software. 6+ Al combinar el desarrollo de software, la escritura y la enseñanza, demuestro cómo crear aplicaciones descentralizadas en redes de cadena de bloques compatibles con EVM. Mis pilas incluyen , , , , , , , y más. JavaScript React Vue Angular Node React Native NextJs Solidity para aprender a crear una aplicación Web3 desde cero. También ofrezco clases privadas y especializadas para gente seria que quiere aprender uno a uno de un mentor. Suscríbete a mi canal de YouTube . Reserva aquí tus clases de Web3 Ahora, déjame mostrarte cómo representar la imagen y los metadatos anteriores en tu código.