O primeiro passo que você dará para construir um Dapp de cunhagem NFT é preparar a arte. Sem a arte, você não pode ter seu projeto NFT atualizado. Outro motivo para pré-processar suas artes é gerar metadados para cada uma das imagens. Sem esses metadados, seu NFT não pode ser vendido em nenhum dos grandes mercados secundários, como o Opensea. Por exemplo, a imagem abaixo é um NFT no mercado Opensea com alguns metadados que também podem ser vistos abaixo. As informações acima, incluindo a obra de arte, seus detalhes e características, podem ser vistas na imagem IPFS abaixo. Configurando as dependências do projeto Abra seu terminal e navegue até o diretório do projeto ou crie uma pasta de projeto em um local específico. Por exemplo, executar no terminal criará uma pasta chamada “ no local especificado. **mkdir preprocessor** pré-processador” Em seguida, execute os seguintes comandos no terminal. cd preprocessor npm init -y npm install sharp @faker.js/faker --save-dev Os comandos acima instalarão as bibliotecas e em seu projeto. A biblioteca faker nos ajudará a gerar informações aleatórias. Visto que a biblioteca nítida nos ajudará a processar a imagem em uma determinada dimensão, qualidade e formato. sharp faker Em seguida, crie uma pasta em seu projeto chamada e outra chamada . Na pasta “arts”, coloque todas as imagens para processamento dentro dela. arts outputs Com os passos acima realizados, abra o projeto em “código VS”. A estrutura do projeto deve se parecer com a abaixo. - preprocessor/ - arts/ - node_modules/ - outputs/ - package.json - package-lock.json Ótimo, vamos passar para a codificação do mecanismo responsável pelo processamento das imagens. Pré-requisitos Você precisará do seguinte instalado em seu computador para concluir este tutorial. NodeJs Aplicativo de área de trabalho IPFS Código VS Codificando o mecanismo de processamento Crie um arquivo na raiz do seu projeto chamado e cole o seguinte 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++ } }) As etapas a seguir ajudarão você a entender como esse mecanismo de processamento de metadados funciona. Importando Bibliotecas Essenciais const fs = require('fs') const path = require('path') const sharp = require('sharp') const { faker } = require('@faker-js/faker') const input = './arts' const output = './outputs' O representa o sistema de arquivos, é um módulo embutido que acompanha o NodeJs. Ele tem a responsabilidade de gerenciar as atividades de leitura e gravação de arquivos em sua máquina. fs O é outro módulo de nó que o ajuda a navegar pelas estruturas de diretório em sua máquina. Isso será fundamental para localizar onde nossas imagens são mantidas. path Sharp é o módulo que usamos para processar a imagem, como redimensionar e transformar em um tipo de arquivo diferente. Usaremos o falsificador para gerar um número aleatório. Por fim, a variável de contém o local onde estão localizadas as imagens a serem processadas e a aponta para o local onde as imagens processadas serão salvas. input output Definindo Variáveis Essenciais 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()), } Os códigos acima contêm variáveis importantes a serem usadas durante a geração de nossos metadados. nos ajuda a numerar as imagens de forma consistente com a iteração atual. **Image_counter** define a dimensão da largura e altura de cada imagem a ser processada. **ImgSize** fala do formato de arquivo que você deseja que suas imagens processadas suportem. **Desired_ext** especifica o local onde as imagens devem ser armazenadas no IPFS. **Base_url** contém mais informações sobre os metadados de cada imagem. **Attributes** Executando Tarefa Recursiva fs.readdirSync(input).forEach((file) => { if(['.jpg', '.jpeg', '.png', '.gif', '.webp'].includes(orginal_ext)) { // Images and metadata tasks are recursively performed here... } }) No bloco de código acima, usamos a biblioteca do sistema de arquivos (fs) para percorrer todas as imagens no local (arts). E para cada uma das imagens, garantimos que nosso mecanismo selecione apenas imagens de uma lista aprovada de extensões. **input** Executando a tarefa de metadados 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, }, ], } No bloco de código acima, fornecemos valores para cada espaço de metadados. Por exemplo, ambientes, armas e todos os valores de características são fornecidos aleatoriamente e dinamicamente. Executando a tarefa de transformação de imagem 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++ No trecho acima, usamos o módulo do sistema de arquivos novamente para primeiro localizar cada uma de nossas artes e redimensioná-las para a dimensão especificada (500 x 500). Além disso, fornecemos um novo nome de acordo com a iteração atual e demos a extensão desejada (webp). Redimensionar e transformar as imagens em otimizou muito nossas obras de arte a uma altura surpreendente. webp Por exemplo, onde submeti este motor de pré-processamento de imagem a imagens totalizando um tamanho de . O tamanho caiu para para a extensão e surpreendentes Essa enorme redução de tamanho representa um grande salto no tempo de carregamento de um site da Minting construído com minhas imagens. neste vídeo 99 111MB 62MB .png .webp 4.5MB Por fim, a partir do bloco de código acima, criamos metadados para cada imagem processada, contendo um nome idêntico e uma URL apontando para o local da imagem. Esses metadados são os que implantaremos no IPFS após o processamento das imagens. JSON Agora, execute o comando abaixo para ter sua imagem transformada. Certifique-se de estar na pasta do seu projeto. node imagify.js Neste ponto, terminamos nosso mecanismo de imagem, nossa pasta de saída deve ter a seguinte estrutura de arquivo como resultado. - output/ - images - 1.webp - 2.webp - ...... - metadata - 1.json - 2.json - ...... Upload de imagens e metadados para IPFS IPFS significa o sistema de arquivos interplanetário, é ponto a ponto e descentralizado. Não há uma maneira fácil de extrair dados armazenados no IPFS e, como tal, é um par quase perfeito para usar junto com seus aplicativos blockchain para armazenar conteúdo de mídia. Para usar a maneira mais fácil e menos confusa, vá para a página de instalação do aplicativo IPFS Desktop e siga as instruções especificadas lá. Depois que a instalação for bem-sucedida, abra o aplicativo IPFS e carregue PRIMEIRO, e repito, PRIMEIRO carregue a pasta de imagens. Uma string CID (identificação de conteúdo) exclusiva será gerada como parte do nome da pasta, veja a imagem abaixo. Agora, copie o CID da pasta de imagens como pode ser visto na imagem acima e substitua-o em seu código . Veja o código abaixo. **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 Agora, execute o novamente para incluir a localização exata de cada imagem em seus metadados . Veja um exemplo dos metadados JSON gerados antes e depois da substituição do CID. **node imagify.js** JSON Você pode assistir a este vídeo para entender como usei essas imagens e metadados em um projeto de cunhagem NFT completo. https://www.youtube.com/watch?v=QN3wb_mXBjY?embedable=true Antes da substituição do 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 } ] } Após a substituição do 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 } ] } Por fim, conforme mostrado na imagem abaixo, carregue a pasta de metadados no IPFS junto com a pasta de imagens. Fantástico, agora vamos colocá-lo na web para o mundo ver. Atualmente, ambas as pastas estão localizadas em seu nó IPFS local (seu computador), para que seja acessível em todo o mundo, você precisa usar um serviço de fixação como o . Pinata Fixando suas pastas no IPFS Primeiro, vá para o e inscreva-se, caso ainda não tenha feito isso. Em seguida, clique no ícone da conta e selecione Chaves de API. Veja a imagem abaixo. Pinata Pin Manager Na página de criação de chaves, clique em criar uma nova chave e insira o nome da chave. Observe a imagem abaixo. Agora copie a chave JWT na área de transferência. Isso é o que usaremos para vincular nosso IPFS Desktop à nossa conta Pinata. Veja a imagem abaixo. Em seguida, abra seu aplicativo de desktop IPFS, vá para a guia de configurações e adicione um novo serviço, selecione Pinata e cole seu token JWT no espaço fornecido. Consulte a imagem abaixo. A última coisa a fazer é fixar suas pastas no Pinata usando as instruções abaixo. Vá para a guia de arquivos, clique na linha pontilhada tripla e selecione definir fixação. Isso aparecerá na imagem abaixo. Selecione Pinata e aplique, ao fazer isso, sua pasta de imagens estará acessível globalmente. Confirmando a acessibilidade global da imagem Vá para este site, copie e cole seu CID no campo de entrada IPFS e clique no botão de cache. Isso verifica todo o conjunto de gateways IPFS disponíveis publicamente em busca de suas imagens. Veja a imagem abaixo. Os resultados da imagem acima mostram que muitos nós IPFS agora têm cópias da pasta de imagens disponíveis e acessíveis globalmente, mesmo que você exclua a cópia original em seu nó local. Com as etapas claramente descritas para você, fixe também a pasta de metadados para torná-los publicamente disponíveis online. Agora você pode usar qualquer um dos links na imagem acima como URL base para tokens . Veja a imagem abaixo. ERC721 E aí está, é como preparar e fazer upload de suas obras de arte no IPFS. Conclusão Você sempre encontrará a necessidade de entender como pré-processar e fazer upload de obras de arte no IPFS em escala de lote. Depois de entender como trabalhar e processar imagens para o IPFS, você pode começar a usá-lo em seus projetos web3 especiais. Até a próxima vez, continue esmagando! Veja o uso de demonstração ao vivo no meu projeto NFT no testnet Goerli . Veja a localização da Opensea. Você pode assistir a versão em vídeo no meu canal do YouTube. aqui aqui https://www.youtube.com/watch?v=YzurgMLwFVQ?embedable=true Sobre o autor Sou um desenvolvedor full-stack blockchain com mais de anos de experiência na indústria de desenvolvimento de software. 6+ Ao combinar desenvolvimento de software, redação e ensino, demonstro como criar aplicativos descentralizados em redes blockchain compatíveis com EVM. Minhas pilhas incluem , , , , , , , e muito mais. JavaScript React Vue Angular Node React Native NextJs Solidity para aprender como criar um aplicativo Web3 do zero. Também ofereço aulas particulares e especializadas para pessoas sérias que desejam aprender individualmente com um mentor. Inscreva-se no meu canal do YouTube . Marque aqui as suas aulas de Web3 Agora, deixe-me mostrar como representar a imagem e os metadados acima em seu código.