WEB3DEV

Cover image for Cunhando um NFT com a Blockchain Polygon e IPFS/Filecoin via NFT.Storage
Paulo Gio
Paulo Gio

Posted on • Atualizado em

Cunhando um NFT com a Blockchain Polygon e IPFS/Filecoin via NFT.Storage

Este tutorial lhe ensinará a criar um NFT usando a blockchain Polygon e utlizar o armazenamento IPFS/Filecoin via NFT.Storage. Polygon, uma solução de dimensionamento de camada 2 para Ethereum, é frequentemente escolhida pelos desenvolvedores por sua velocidade e custos de transação mais baixos, mantendo total compatibilidade com a EVM da Ethereum. O tutorial o guiará pela criação e implantação de um contrato inteligente padronizado, armazenando metadados e ativos em IPFS e Filecoin por meio da API NFT.Storage e cunhando o NFT em sua própria carteira na Polygon.

Introdução

Neste tutorial, visamos atender a três características com nosso processo de cunhagem:

  • Escalabilidade do processo de cunhagem em termos de custo e rendimento. Se o caso de uso visa criar NFTs rapidamente, a tecnologia subjacente precisa lidar com todas as solicitações de cunhagem e a cunhagem deve ser barata.
  • Durabilidade do NFT, pois os ativos podem ter vida longa e, portanto, precisam permanecer utilizáveis durante toda a sua vida útil.
  • Imutabilidade do NFT e do ativo que ele representa para evitar que alterações indesejadas e agentes mal-intencionados alterem o ativo digital que o NFT representa.

A Polygon aborda a característica de escalabilidade com seu protocolo e framework. Eles também são compatíveis com a Ethereum e sua máquina virtual, permitindo que os desenvolvedores movam seu código livremente entre as duas blockchains. Da mesma forma, o NFT.Storage garante durabilidade com o poder da rede Filecoin subjacente e imutabilidade usando o endereçamento de conteúdo do IPFS.

Neste tutorial você terá uma visão geral do processo de cunhagem do NFT, aprenderá como armazenar um ativo digital com NFT.Storage e usar este ativo digital para cunhar seu NFT na Polygon.

Pré-requisitos

O conhecimento geral sobre NFTs lhe fornecerá informações e contexto. A NFT School cobre o básico do NFT, assim como tópicos avançados e outros tutoriais.

Para testar e executar o código encontrado neste tutorial, você precisará de uma instalação funcional do Node.js.

Você também precisará de uma carteira Polygon na rede de testes de Mumbai com uma pequena quantidade do token MATIC. Siga as instruções abaixo para começar:

  1. Baixe e instale a Metamask. Metamask é uma carteira criptográfica e porta de entrada para aplicativos blockchain. É muito fácil de usar e simplifica muitas etapas, como por exemplo, configurar uma carteira Polygon.
  2. Conecte a Metamask à rede de testes Mumbai da Polygon e selecione-a no menu suspenso. Usaremos a rede de testes da Polygon para cunhar nosso NFT, pois é gratuita.
  3. Receba o token MATIC em sua carteira usando um faucet. Selecione a rede de testes Mumbai e cole o endereço da sua carteira Metamask no formulário. Para cunhar um NFT, precisamos pagar uma pequena quantia de MATIC, que é uma taxa cobrada pelos mineradores por operações para adicionar novas transações à blockchain, como por exemplo, cunhar um NFT ou criar um novo contrato inteligente.
  4. Copie sua chave privada da Metamask clicando nos três pontos no canto superior direito e selecionando 'Detalhes da conta'. Na parte inferior, você pode encontrar um botão para exportar sua chave privada. Clique nele e digite sua senha quando solicitada. Você pode copiar e colar a chave privada em um arquivo de texto por enquanto. Vamos usá-la mais tarde no tutorial ao interagir com a blockchain.

Por fim, você precisará de um editor de texto ou código. Para maior conveniência, escolha um editor com suporte às linguagens JavaScript e Solidity. Uma boa opção é o Visual Studio Code com a extensão do Solidity habilitada.

Preparação

Obtenha uma chave de API para o NFT.storage

Para usar o NFT.Storage, você precisará de uma chave de API. Primeiro, vá para NFT.Storage para fazer login com seu endereço de e-mail. Você receberá um e-mail com um link que fará seu login - sem necessidade de senha. Depois de fazer o login com sucesso, vá para API Keys por meio da barra de navegação. Você encontrará um botão para criar uma Nova Chave. Quando for solicitado um nome de chave de API, você pode escolher livremente um ou usar “Polygon + NFT.Storage”. Você pode copiar o conteúdo da coluna da chave agora ou fazer referência a NFT.Storage posteriormente no tutorial.

Configure seu espaço de trabalho

Crie uma nova pasta vazia que podemos usar como nosso espaço de trabalho para este tutorial. Sinta-se à vontade para escolher qualquer nome e local em seu sistema de arquivos. Abra um terminal e navegue até a pasta recém-criada.

Em seguida, instalaremos as seguintes dependências do Node.js:

  • Hardhat e Hardhat-Ethers, um ambiente de desenvolvimento para Ethereum (e blockchains compatíveis com a Ethereum, como a Polygon).
  • OpenZeppelin, uma coleção de contratos inteligentes com contratos de base NFT padronizados.
  • NFT.Storage, uma biblioteca para se conectar à API NFT.Storage.
  • Dotenv, uma biblioteca para manipular arquivos de ambiente para configuração (por exemplo, injetando chaves privadas no script).

Use o seguinte comando para instalar todas as dependências de uma vez:

npm install hardhat @openzeppelin/contracts nft.storage dotenv @nomiclabs/hardhat-ethers
Enter fullscreen mode Exit fullscreen mode

O Hardhat precisa ser inicializado na pasta atual. Para iniciar a inicialização, execute:

npx hardhat
Enter fullscreen mode Exit fullscreen mode

Quando solicitado, escolha Create an empty hardhat.config.js. O output do console deve ficar assim:

✔ What do you want to do? · Create an empty hardhat.config.js
✨ Config file created ✨
Enter fullscreen mode Exit fullscreen mode

Faremos algumas modificações no arquivo de configuração do hardhat.config.js para suportar a rede de teste Polygon Mumbai. Abra o hardhat.config.js que foi criado na última etapa. Observe que estamos carregando sua chave privada da carteira Polygon de um arquivo de ambiente e que esse arquivo de ambiente deve ser mantido em segurança.

/**
* @type import('hardhat/config').HardhatUserConfig
*/
require("@nomiclabs/hardhat-ethers");
require('dotenv').config();
const { PRIVATE_KEY } = process.env;
module.exports = {
  defaultNetwork: "PolygonMumbai",
  networks: {
    hardhat: {
    },
     PolygonMumbai: {
      url: "https://rpc-mumbai.maticvigil.com",
      accounts: [PRIVATE_KEY]
    }
  },
  solidity: {
    version: "0.8.12",
    settings: {
      optimizer: {
        enabled: true,
        runs: 200
      }
    }
  },
}
Enter fullscreen mode Exit fullscreen mode

Crie um novo arquivo chamado .env que conterá sua chave de API para o NFT.Storage e sua carteira Polygon. O conteúdo do arquivo .env deve se parecer com a declaração abaixo:

PRIVATE_KEY="Sua chave privada"
NFT_STORAGE_API_KEY="Sua chave de API"
Enter fullscreen mode Exit fullscreen mode

Substitua os espaços reservados pela chave de API que você criou durante a preparação e sua chave privada da carteira Polygon.

Para manter nosso projeto organizado, criaremos três novas pastas:

  1. contracts, para os contratos Polygon escritos em Solidity.
  2. assets, contendo o ativo digital que cunharemos como um NFT.
  3. scripts, como auxiliares para conduzir o processo de preparação e cunhagem.

Execute o seguinte comando:

mkdir contracts assets scripts
Enter fullscreen mode Exit fullscreen mode

Por fim, adicionaremos uma imagem à pasta assets. Esta imagem será nossa arte que enviaremos para o NFT.Storage e cunharemos na Polygon. Vamos chamá-la de ExemploNFT.png por enquanto. Se você não tem uma arte legal pronta, você pode baixar um padrão simples aqui.

Cunhando seu NFT

Armazenando dados de ativos com o NFT.Storage

Usaremos o NFT.Storage para armazenar nosso ativo digital e seus metadados. O NFT.Storage garante imutabilidade e durabilidade ao carregar seu ativo digital para o Filecoin e o IPFS automaticamente. IPFS e Filecoin operam em identificadores de conteúdo (CID) para referência imutável. O IPFS fornecerá recuperação rápida com seu cache replicado geograficamente e o Filecoin garante durabilidade com provedores de armazenamento incentivados.

Crie um script chamado store-asset.mjs dentro do diretório scripts. O conteúdo está listado abaixo:

import { NFTStorage, File } from "nft.storage"
import fs from 'fs'
import dotenv from 'dotenv'
dotenv.config()

const API_KEY = process.env.NFT_STORAGE_API_KEY

async function storeAsset() {
   const client = new NFTStorage({ token: API_KEY })
   const metadata = await client.store({
       name: 'ExemploNFT',
       description: 'Meu ExemploNFT é uma obra de arte incrível!',
       image: new File(
           [await fs.promises.readFile('assets/ExemploNFT.png')],
           'ExemploNFT.png',
           { type: 'image/png' }
       ),
   })
   console.log("Metadados armazenados no Filecoin e IPFS na URL:", metadata.url)
}

storeAsset()
   .then(() => process.exit(0))
   .catch((error) => {
       console.error(error);
       process.exit(1);
   });
Enter fullscreen mode Exit fullscreen mode

A parte principal do script é a função storeAsset. Ele cria um novo cliente conectando-se ao NFT.Storage usando a chave de API que você criou anteriormente. Em seguida, apresentamos os metadados que consistem em nome, descrição e imagem. Observe que estamos lendo o ativo NFT diretamente do sistema de arquivos do diretório assets. No final da função, imprimiremos a URL dos metadados, pois a usaremos posteriormente ao criar o NFT na Polygon.

Depois de configurar o script, você pode acioná-lo executando:

node scripts/store-asset.mjs
Enter fullscreen mode Exit fullscreen mode

Seu output deve se parecer com a listagem abaixo, onde HASH é o CID da arte que você acabou de armazenar.

Metadados armazenados no Filecoin e IPFS na URL: ipfs://HASH/metadata.json
Enter fullscreen mode Exit fullscreen mode

Criando seu NFT na Polygon

Crie o contrato inteligente para cunhagem

Primeiro, criaremos um contrato inteligente que será usado para cunhar o NFT. Como a Polygon é compatível com a Ethereum, escreveremos o contrato inteligente no Solidity. Crie um novo arquivo para nosso contrato inteligente NFT chamado ExemploNFT.sol dentro do diretório contracts. Você pode copiar o código das declarações abaixo:

// Contrato baseado em https://docs.openzeppelin.com/contracts/4.x/erc721
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract ExemploNFT is ERC721URIStorage, Ownable {
   using Counters for Counters.Counter;
   Counters.Counter private _tokenIds;

   constructor() ERC721("NFT", "ENFT") {}

   function mintNFT(address recipient, string memory tokenURI)
       public onlyOwner
       returns (uint256)
   {
       _tokenIds.increment();

       uint256 newItemId = _tokenIds.current();
       _mint(recipient, newItemId);
       _setTokenURI(newItemId, tokenURI);

       return newItemId;
   }
}
Enter fullscreen mode Exit fullscreen mode

Para ser um NFT válido, seu contrato inteligente deve implementar todos os métodos do padrão ERC-721. Utilizamos a implementação da biblioteca OpenZeppelin, que já disponibiliza um conjunto de funcionalidades básicas e adere ao padrão.

No topo de nosso contrato inteligente, importamos três classes de contrato inteligente OpenZeppelin:

\@openzeppelin/contracts/token/ERC721/ERC721.sol contém a implementação dos métodos básicos do padrão ERC-721, que nosso contrato inteligente NFT herdará. Usamos o ERC721URIStorage, que é uma extensão para armazenar não apenas os ativos, mas também metadados como um arquivo JSON off-chain. Assim como o contrato, este arquivo JSON precisa aderir ao ERC-721.

\@openzeppelin/contracts/utils/Counters.sol fornece contadores que só podem ser incrementados ou decrementados em um. Nosso contrato inteligente usa um contador para acompanhar o número total de NFTs cunhados e definir o ID exclusivo em nosso novo NFT.

\@openzeppelin/contracts/access/Ownable.sol configura o controle de acesso em nosso contrato inteligente, para que apenas o proprietário do contrato inteligente (você) possa cunhar NFTs.

Após nossas instruções de importação, temos nosso contrato inteligente NFT personalizado, que contém um contador, um construtor e um método para realmente cunhar o NFT. A maior parte do trabalho árduo é feito pelo contrato básico herdado do OpenZeppelin, que implementa a maioria dos métodos necessários para criar um NFT aderente ao padrão ERC-721.

O contador mantém o controle do número total de NFTs cunhados, que é usado no método de cunhagem como um identificador exclusivo para o NFT.

No construtor, passamos dois argumentos de string para o nome do contrato inteligente e o símbolo (representado em carteiras). Você pode alterá-los para o que quiser.

Finalmente, temos nosso método mintNFT que nos permite realmente cunhar o NFT. O método é definido como onlyOwner para garantir que ele só possa ser executado pelo proprietário do contrato inteligente.

address recipient especifica o endereço que receberá o NFT primeiro.

string memory tokenURI é uma URL que deve resolver para um documento JSON que descreve os metadados do NFT. Em nosso caso, já está armazenado no NFT.Storage. Podemos usar o link IPFS retornado para o arquivo JSON de metadados durante a execução do método.

Dentro do método, incrementamos o contador para receber um novo identificador exclusivo para nosso NFT. Em seguida, chamamos os métodos fornecidos pelo contrato base do OpenZeppelin para cunhar o NFT para o destinatário com o identificador recém-criado e definindo o URI dos metadados. O método retorna o identificador exclusivo após a execução.

Implante o contrato inteligente na Polygon

Agora, é hora de implantar nosso contrato inteligente na Polygon. Crie um novo arquivo chamado deploy-contract.mjs no diretório scripts. Copie o código abaixo para esse arquivo e salve-o.

async function deployContract() {
 const ExemploNFT = await ethers.getContractFactory("ExemploNFT")
 const exemploNFT = await ExemploNFT.deploy()
 await exemploNFT.deployed()
 // Isso resolve o bug na rede Mumbai, onde o endereço do contrato não é o real
 const txHash = exemploNFT.deployTransaction.hash
 const txReceipt = await ethers.provider.waitForTransaction(txHash)
 const contractAddress = txReceipt.contractAddress
 console.log("Contrato implantado no endereço:", contractAddress)
}

deployContract()
 .then(() => process.exit(0))
 .catch((error) => {
   console.error(error);
   process.exit(1);
 });
Enter fullscreen mode Exit fullscreen mode

A implantação do contrato é feita com as funções auxiliares fornecidas pela biblioteca do Hardhat. Primeiro, obtemos o contrato inteligente que criamos na etapa anterior com a fábrica de contratos fornecida. Em seguida, o implantamos chamando o respectivo método e aguardamos a conclusão da implantação. Existem mais algumas linhas abaixo do código descrito para obter o endereço correto no ambiente da rede de testes. Salve o arquivo mjs. Execute o script com o seguinte comando:

npx hardhat run scripts/deploy-contract.mjs --network PolygonMumbai
Enter fullscreen mode Exit fullscreen mode

Se tudo estiver correto, você verá o seguinte output:

Contrato implantado no endereço: 0x{SEU_ENDEREÇO_DE_CONTRATO}
Enter fullscreen mode Exit fullscreen mode

Observe que você precisará do endereço do contrato impresso na etapa de cunhagem. Você pode copiá-lo e colá-lo em um arquivo de texto separado e salvá-lo para mais tarde. Isso é necessário para que o script de cunhagem possa chamar o método de cunhagem desse contrato específico.

Cunhando o NFT na Polygon

Agora, para cunhar o NFT precisamos apenas chamar o contrato que acabamos de implantar na Polygon. Crie um novo arquivo chamado mint-nft.mjs dentro do diretório scripts, copie e cole este código abaixo:

const CONTRACT_ADDRESS = "0x00"
const META_DATA_URL = "ipfs://XX"

async function mintNFT(contractAddress, metaDataURL) {
   const ExemploNFT = await ethers.getContractFactory("ExemploNFT")
   const [owner] = await ethers.getSigners()
   await ExemploNFT.attach(contractAddress).mintNFT(owner.address, metaDataURL)
   console.log("NFT cunhado para: ", owner.address)
}

mintNFT(CONTRACT_ADDRESS, META_DATA_URL)
   .then(() => process.exit(0))
   .catch((error) => {
       console.error(error);
       process.exit(1);
   });
Enter fullscreen mode Exit fullscreen mode

Edite as duas primeiras linhas para inserir o endereço do contrato da implantação anterior e a URL de metadados que foi retornada ao armazenar o ativo com o NFT.Storage. O restante do script configura a chamada para seu contrato inteligente com você como o futuro proprietário do NFT e o ponteiro para os metadados armazenados no IPFS.

Em seguida, execute o script:

npx hardhat run scripts/mint-nft.mjs \--network PolygonMumbai
Enter fullscreen mode Exit fullscreen mode

Você pode esperar ver o seguinte output:

NFT cunhado para: 0x{SEU_ENDEREÇO_DA_CARTEIRA}
Enter fullscreen mode Exit fullscreen mode

Conclusão

Neste tutorial, aprendemos como cunhar um NFT de ponta a ponta com a Polygon e o NFT.Storage. Essa combinação de tecnologia resulta em descentralização adequada e garante escalabilidade, durabilidade e imutabilidade.

Implantamos um contrato inteligente personalizado para criar nosso NFT específico para nossas necessidades. Para este tutorial, usamos um exemplo simples baseado no padrão ERC-721. No entanto, você também pode definir uma lógica complexa que rege o ciclo de vida do NFT. Para casos de uso mais complexos, o padrão sucessor ERC-1155 é um bom ponto de partida. OpenZeppelin, a biblioteca que usamos em nosso tutorial, oferece um assistente de contratos que ajuda a criar contratos NFT.

A cunhagem bem-sucedida pode ser vista como o início da valiosa fase do NFT. O NFT pode então ser usado para provar a propriedade e pode ser transferido para outros usuários. Os motivos para transferir um NFT podem incluir uma venda bem-sucedida em um dos mercados NFT, como o OpenSea, ou um tipo diferente de evento, como adquirir um item em um jogo baseado em NFT. Explorar as vastas possibilidades dos NFTs é definitivamente um próximo passo bem empolgante.

Se você quiser ajuda para criar seu projeto NFT com NFT.storage, recomendamos que você participe do canal #nft-storage no Discord e no Slack.

Este artigo foi originalmente escrito por https://nftschool.dev e traduzido por Paulinho Giovannini. Você pode ver o artigo original aqui.

Latest comments (0)