WEB3DEV

Cover image for Criando NFTs verdadeiramente descentralizadas — Um guia abrangente para ERC721 e IPFS
Adriano P. Araujo
Adriano P. Araujo

Posted on

Criando NFTs verdadeiramente descentralizadas — Um guia abrangente para ERC721 e IPFS

Embora os NFTs sejam uma ótima ferramenta para identificar exclusivamente ativos e propriedade digital, o armazenamento de dados na blockchain tem um custo muito mais alto em relação aos bancos de dados tradicionais ( os dados devem ser processados e replicados entre nós ). Consequentemente, um padrão comum que surgiu no espaço do NFT era que o NFT mantivesse um link para o ativo-alvo, em vez do ativo real em si. Como tal, na ausência de uma alternativa confiável de armazenamento descentralizado, muitos NFTs ainda dependem muito da infraestrutura da web tradicional.

Por exemplo, uma imagem de alta resolução seria armazenada em um servidor centralizado, enquanto apenas o link ( i.e. https://www.domain.com/subdomain/imgLink) seria armazenado no NFT. Aqueles familiarizados com a arquitetura web2.0 poderão reconhecer facilmente que não há nada que impeça o host de imagem de alterar a imagem à qual o URL aponta. Tecnologias de armazenamento descentralizadas, como IPFS ( InterPlanetary File System ), visam resolver exatamente isso, permitindo que esses dados sejam replicados com segurança em vários nós, minimizando o risco de serem censurados ou adulterados com.

Em vez de endereços baseados no local de um arquivo, o IPFS redefine o endereço com base no conteúdo do arquivo. Embora não esteja no escopo deste guia, essa definição é possível através de hash criptográfico, Gráficos acíclicos direcionados, e Árvores de Merkle. Do ponto de vista dos dados, o que essa opção permite é :

  • Resiliência: Os dados estarão sempre disponíveis uma vez que um único nó hospeda os dados. Isso também dificulta a censura.

  • Confiabilidade: Como qualquer alteração no próprio arquivo altera o endereço de hash, há menos premissas de confiança ao navegar para um endereço. Os usuários sempre podem calcular o hash para verificar a autenticidade. Isso também minimiza o risco no controle de versão.

  • Deduplicação: Se alguns dados fazem parte de vários conjuntos de dados, cada conjunto de dados precisa apenas vincular a uma versão dos dados. Consequentemente, ninguém precisa armazenar todo o conjunto de dados, pois os links podem ser usados para extrair seções de dados da rede.

Eu recomendo acessar a Proto.school se você quiser entender todos os conceitos. Para nossos propósitos, o IPFS permite que os dados para os quais nosso NFT está apontando sejam verdadeiramente descentralizados. Para esse fim, compilei um guia de ponta a ponta sobre como integrar o IPFS e o ERC721 usando o Hardhat. Isso inclui:

  • Instalação e configuração do ambiente Hardhat & IPFS

  • Estendendo o contrato ERC721 do OpenZeppelin’s e os contratos auxiliares

  • Implantando contrato de token para a Goerli Testnet ( obtendo ETH de teste, conectando-se ao nó, exportação de chave privada )

  • Upload de dados para o IPFS e resposta de gravação para a blockchain

  • Interagindo programaticamente com uma instância de contrato local

  • Envio de tokens ERC721 criados na Goerli Testnet via Metamask

Embora direcionado àqueles que estão começando no espaço, este guia requer alguma familiaridade básica com conceitos de Node.js e Solidity. É importante notar que também pulei a seção de testes neste guia, pois o foco está na integração do IPFS. Todo o código usado neste guia pode ser encontrado no github.

Guias relacionados:

Configuração do Hardhat 

Primeiro precisamos criar um diretório de projeto e instalar o Hardhat:


mkdir ERC721-IPFS

cd ERC721-IPFS

npm install --save-dev hardhat

Enter fullscreen mode Exit fullscreen mode

Uma vez que o pacote hardhat foi instalado, podemos executar npx hardhat, que trará algumas opções para a arquitetura inicial do projeto:

Para este tutorial, selecionaremos a opção Create a JavaScript project. Você será solicitado com uma série de perguntas para as quais você pode selecionar continuamente o enter. O último dos quais instalará as dependências do projeto.

npm install --save-dev @ nomicfoundation / hardhat-toolbox @ ^ 1.0.1

Seguindo o  comando npx hardhat, o projeto terá 3 pastas:

  • contracts/    é onde os arquivos de origem dos seus contratos devem estar.

  • test/é para onde seus testes devem ir.

  • scripts/é para onde vão os scripts simples de automação.

Além disso, um arquivo  hardhat.config.js será gerado. Este arquivo gerenciará os plugins e dependências visíveis pelo hardhat. Os plugins e dependências terão que ser instalados primeiro, uma vez que são exigidos pelo arquivo hardhat.config.js.

O comando npx hardhat também criou um contrato de exemplo chamado Lock que não precisaremos para este guia,  você pode seguir em frente e removê-lo:

rm contracts/Lock.sol test/Lock.js

Agora que o Hardhat foi configurado, podemos começar a criar nosso token ERC721.

Contrato ERC721

O OpenZeppelin, que lidera o avanço do padrão ERC721, fornece uma biblioteca abrangente para o desenvolvimento seguro de contratos inteligentes que usaremos para implementar nosso token. Para fazer isso, precisamos primeiro instalar o pacote de contratos do OpenZeppelin.

npm install @openzeppelin / contracts

Podemos então importar os contratos do OpenZeppelin em nosso próprio contrato, prefixando seu caminho com @openzeppelin/contracts/....

Antes de iniciar nosso primeiro contrato de token ERC721, precisamos concluir a etapa mais importante: nomear sua coleção de tokens! Isso difere da implementação do ERC20, onde o nome é dado ao token em vez de uma coleção de tokens. Para tokens ERC721 que não são fungíveis, cado NFT precisa ter um identificador diferente, mas ainda podemos agrupá-los na mesma coleção. Portanto, para os tokens ERC721, o contrato inteligente representa a coleção de tokens em que novos NFTs da coleção podem ser cunhados passando um identificador exclusivo para o contrato da coleção de tokens.

A prática padrão é combinar o nome do arquivo do contrato inteligente com o da sua coleção de tokens. Para este guia, nomearei a coleção de token de DecentralisedNFT ( token não fungível descentralizado ) com um símbolo de DNFT e, portanto, meu nome de arquivo de contrato inteligente será DecentralisedNFT.sol. Sinta-se à vontade para escolher seu próprio nome de coleção, mas lembre-se de substituir qualquer instância do DecentralisedNFT com seu próprio nome especialmente criado.

O novo contrato será colocado na pasta contracts/:

touch contracts/DecentralisedNFT.sol

Abra o DecentralisedNFT.sol no seu editor de códigos e adicione o seguinte código. O código utilizará a função do construtor do Solidity para fornecer à coleção de token um name e um symbol após a implantação.


// contracts/DecentralisedNFT.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;



import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";

import "@openzeppelin/contracts/utils/Counters.sol";

import "@openzeppelin/contracts/access/Ownable.sol";



contract DecentralisedNFT is ERC721URIStorage, Ownable {

    using Counters for Counters.Counter;

    Counters.Counter private _tokenIds;



    // URI base requerida para interação com IPFS

    string private _baseURIExtended;



    constructor() ERC721("DecentralisedNFT", "DNFT") {

        _setBaseURI("ipfs://");

    }



    // Definição da base URI para a coleção

    function _setBaseURI(string memory baseURI) private {

        _baseURIExtended = baseURI;

    }



    // Substitui a função padrão para permitir que o ERC721URIStorage obtenha a baseURI atualizada

    function _baseURI() internal view override returns (string memory) {

        return _baseURIExtended;

    }



    // permite a cunhagem de um novo NFT

    function mintCollectionNFT(address collector, string memory metadataURI) public onlyOwner() {

        _tokenIds.increment(); // NFT IDs start at 1



        uint256 tokenId = _tokenIds.current();

        _safeMint(collector, tokenId);

        _setTokenURI(tokenId, metadataURI);



    }



}

Enter fullscreen mode Exit fullscreen mode

Importaremos o contrato OpenZeppelin's ERC721  através do caminho @openzeppelin/contracts/token/ERC721/ERC721.sol. Este contrato implementa funções adicionais além do ERC721 padrão, que nos ajudarão a gerenciar os metadados do NFT. Você pode encontrar o caminho para o contrato através da documentação e do github do Openzeppelin.

Como o conjunto principal de contratos ERC721 é imparcial, também declaramos uma função de criação personalizada mintCollectionNFT() para implementar a cunhagem de NFTs para a coleção usando as funções internas do ERC721. Isso inclui o padrão _safeMint() do ERC721, bem como o _setTokenURI() do ERC721URIStorage.

Observe que também estamos usando o contrato Ownable para garantir que apenas o contractOwner possa cunhar NFTs. Além disso, o contrato Counters garante um ID exclusivo de incremento automático para cado NFT criada. Salve o contrato DecentralisedNFT.sol e agora podemos compilar o contrato concluído.

Compilando o contrato

Para que a Máquina Virtual Ethereum ( EVM ) execute nosso código, precisamos compilar nosso código de Solidity no bytecode compatível com a EVM. Para garantir que não haja problemas de versão, podemos especificar uma versão Solidity na versão fornecida no arquivo hardhat.config.js.


require("@nomicfoundation/hardhat-toolbox");

require("@nomiclabs/hardhat-ethers");

require("@nomicfoundation/hardhat-chai-matchers")



/** @type import('hardhat/config').HardhatUserConfig */

module.exports = {

  solidity: "0.8.9",

};

Enter fullscreen mode Exit fullscreen mode

Para compilar o contrato DecentralisedNFT, podemos usar o prático comando de compilação do Hardhat.

npx hardhat compile

O Hardhat terá compilado o contrato em uma recém-criada pasta  artifacts/. Embora tenhamos escrito apenas o código para DecentralisedNFT.sol, o console mostra que havia 13 arquivos compilados. Isso ocorre devido à forma como o Solidity lida com a importação do @openzeppelin/contracts e suas dependências.

Implantando o contrato localmente

Antes de implantar o contrato em uma rede pública, é uma prática recomendada testar o contrato em uma blockchain local primeiro. O Hardhat simplifica o processo de configuração disso com uma blockchain local embutida que pode ser facilmente executada através de uma única linha de código:

npx hardhat node

Execute o comando acima em uma janela de comando separada.

A rede Hardhat imprimirá o endereço e uma lista de contas geradas localmente. Observe que essa blockchain local armazena apenas as interações até que o console seja fechado, portanto, o estado não é preservado entre as execuções. Além disso, reserve um tempo para ler os detalhes das contas, pois é importante que você não use essas contas de amostra para enviar dinheiro real. Com a blockchain local em funcionamento, podemos começar a escrever nossos scripts de implantação. Atualmente, o Hardhat não possui um sistema de implantação nativo e, portanto, a necessidade de scripts.

Para o nosso script de implantação, usaremos o plugin hardhat-ethers. Você pode encontrar a documentação para o plug-in aqui. Para usá-lo no projeto, precisamos primeiro instalá-lo:

npm install --save-dev [@nomiclabs/hardhat-ethers](http://twitter.com/nomiclabs/hardhat-ethers) ethers

Navegando para o diretório scripts/, você poderá ver que um arquivo deploy.js foi criado anteriormente. Podemos substituir a função main() com o seguinte:


// Exigimos o Hardhat Runtime Environment explicitamente aqui. Isso é opcional

//mas útil para executar o script de maneira autônoma por meio do `node <script>`.

//

// Você também pode executar um script com `npx hardhat run <script>`. Se você fizer isso, o Hardhat

// irá compilar seus contratos, adicione os membros do Hardhat Runtime Environment ao

// escopo global e execute o script.





const { ethers } = require("hardhat");



async function main() {



  // Obtém o proprietário do contrato 

  const contractOwner = await ethers.getSigners();

  console.log(`Deploying contract from: ${contractOwner[0].address}`);



  // Função auxiliar do Hardhat para obter o objeto ethers contractFactory 

  const DecentralisedNFT = await ethers.getContractFactory('DecentralisedNFT');



  // Implantação do contrato

  console.log('Deploying DecentralisedNFT...');

  const decentralisedNFT = await DecentralisedNFT.deploy();

  await decentralisedNFT.deployed();

  console.log(`DecentralisedNFT deployed to: ${decentralisedNFT.address}`)

}



// Recomendamos este padrão para poder usar async/await em qualquer lugar

// e lidar adequadamente com os erros.



main()

  .then(() => process.exit(0))

  .catch((error) => {

    console.error(error);

    process.exitCode = 1;

  });

Enter fullscreen mode Exit fullscreen mode

O Hardhat implantará o contrato usando a primeira conta criada quando iniciarmos o nó acima. A função mintCollectionNFT() em DecentralisedNFT.sol nos permitirá chamar externamente o contrato para cunhar NFTs DNFT. Para acessar a matriz de contas criadas, podemos usar a função auxiliar getSigners()  fornecida pelo plugin hardhat-ethers .

Salve o arquivo e agora estamos prontos para implantar nosso contrato DecentralisedNFT!

npx hardhat run --network localhost scripts / deploy.js

Como mencionado, estamos implantando o contrato em nosso localhost. Anote o endereço do contrato implantado, pois precisaremos dele na próxima seção para interagir com nosso contrato programaticamente.

Configurando IPFS

Antes de começarmos a cunhar NFTs, precisamos primeiro configurar seu ambiente IPFS, pois isso permitirá que os dados do IPFS sejam armazenados na blockchain. A maneira mais fácil de começar é instalar o IPFS Desktop, que é uma GUI para hospedar e interagir com o nó do IPFS. Você pode encontrar o guia de instalação aqui.

Depois de instalado, você poderá ver a instância do IPFS em execução na sua barra de tarefas. Ao clicar na seta Advanced, você também deve ver as opções de conexão para o seu nó IPFS. Observe o endereço da API padrão ao qual nos conectaremos em breve.

Interação com o contrato ( com IPFS )

Com nosso nó IPFS configurado, agora podemos criar um script para interagir com nosso contrato inteligente `DecentralisedNFT. O script completo pode ser encontrado aqui.

Dependeremos das seguintes dependências para o nosso script e, portanto, precisaremos instalá-las em nossa pasta de trabalho:

npm install --save-dev ipfs-http-client

npm install --save-dev it-to-buffer

Para acompanhar todos os dados vinculados, também criaremos uma matriz imagesSummary que manterá objetos representando umo NFT / imagem específica. Isso inclui os seguintes dados:

  • imagecID: O identificador que representa a imagem carregada no IPFS

  • metadataCID: O identificador que representa os metadados da imagem enviados ao IPFS. Isso inclui o nome, a descrição e o imageCID

  • mintedNFTId: O ID do token para o NFT recém-criada que contém o link de metadados NFT / URI

  • metadataURI: O link IPFS em que os metadados NFT estão armazenados

  • metadataJSON: O objeto de metadados armazenado pelo IPFS

A matriz imagesSummary será adicionada sempre que novas informações sobre o NFT forem geradas. O script também registrará a matriz imagesSummary no final. Como visualização, abaixo está uma captura de tela da imagesSummary gerada ao executar o código localmente:

Obtendo o contrato implantado

Para obter a instância do nosso contrato implantado, você precisará do endereço do contrato retornado do comando de implantação. Você pode substituir o contractAddress no código abaixo com o fornecido pela sua máquina local.

Image description

Com isso, montamos nosso objeto decentralisedNFT que é uma abstração de um contrato implantado na rede Ethereum, neste caso uma rede local. Este objeto decentralisedNFT permite uma maneira simples de serializar chamadas e transações para um contrato na cadeia e desserializar seus logs de resultados. Você pode acessar a documentação do ethers para mais informações.

Configurar o objeto local do nó IPFS

Para interagir com nosso nó IPFS local programaticamente, precisaremos criar uma instância IPFS para interagir. Conforme mencionado na seção acima, usaremos a configuração padrão do IPFS.

Image description

Importando imagens

Para este guia, carregaremos imagens no IPFS e, como tal, precisaremos de uma pasta para armazenar todas as imagens a serem carregadas.

mkdir images

Você pode arrastar e soltar as imagens para serem carregadas na pasta recém-criada e devemos estar prontos. Por uma questão de simplicidade, observe que o código filtra a pasta por imagens .png.

Image description

Executando o script, as imagens agora devem ser importadas como objetos de dados em buffer que você pode manipular no seu código.

Upload de imagens para IPFS

Em seguida, podemos fazer upload dos dados em buffer da imagem para o IPFS por meio de nossa instância IPFS configurada localmente. Para fazer isso, usamos a função  ipfs.add que nos retornará o CID (content identifier - identificador de conteúdo  ) da imagem carregada.

Image description

Upload de metadados para IPFS

Depois de obter o CID da imagem, podemos adicionar metadados adicionais ao link. Para este guia, implementaremos uma versão simplificada do esquema JSON de metadados recomendado para a Especificação da EIP-721.

Esquema JSON recomendado

Criaremos uma função auxiliar para criar nosso objeto de metadados.

Image description

Observe que, para simplificar, decidi manter os mesmo parâmetros name e description para todas as imagens, mas você pode implementar sua própria forma de entrada para alterar isso de acordo.

Image description

Assim como o processo de carregamento das imagens, também receberemos um CID quando os metadados forem carregados no IPFS.

Faça a cunhagem de NFTs com metadados armazenados na cadeia

Agora que temos o CID dos metadados (que inclui o CID da imagem), podemos cunhar umo NFT para cada imagem que inclua seus metadados. Para isso, usaremos a função personalizada mintCollectionNFT() que implementamos em nosso contrato DecentralisedNFT.sol. Esta função utiliza o contrato ERC721URIStorage para armazenar metadados adicionais do NFT na blockchain.

Image description

Além disso, também estamos monitorando qualquer evento Transfer  que seja emitido através da cunhagem de umo NFT para obter o tokenId criado pelo contrato Counters . Observe que o código aqui pressupõe que não há transferências simultâneas para o NFT. Para simplificar, deixei de fora consultas de eventos mais complexos ( ie. filtro para transferências originárias do endereço zero ).

Obtenha os dados armazenados na cadeia

Com o tokenId, podemos consultar a blockchain para obter os dados armazenados usando a função tokenURI() do contrato ERC721URIStorage.

Image description

Esta chamada deve retornar o URI prefixado com ipfs:// para indicar que o hash é um identificador de conteúdo do IPFS.

Obter os dados armazenados do IPFS

Dado o URI obtido da blockchain, podemos consultar o IPFS para os metadados relevantes.

Image description

 

 
Se tudo correr bem, você deverá ver os metadados JSON criados para cado NFT.

Implantando o contrato publicamente

Dada a duração deste guia, optei por pular a escrita de testes automatizados, mas isso é definitivamente algo que deve ser feito antes de implantar seu código na produção. Com esse aviso fora do caminho, finalmente é hora de implantar o DecentralisedNFT em uma rede pública! Essa é a parte interessante, pois qualquer pessoa conectada à rede poderá interagir com sua coleção NFT.

Para os fins deste guia, implantaremos o contrato na testnet Goerli. A testnet Goerli funciona de maneira idêntica à mainnet, exceto pelo valor em dólar anexado ao ETH. Como tal, é o ambiente perfeito para experimentar seus contratos antes de implantar na rede principal. Observe que também estamos implantando na Goerli, pois muitas das outras testnets ( Ropsten, Rinkeby, Kiln ) serão interrompidas após a fusão da Ethereum.

Para implantar na Goerli, precisaremos primeiro obter alguns ETH da Goerli, aqui referidos apenas como ETH. Isso é necessário, pois as transações na rede pública precisam ser processadas por um minerador que exige que uma taxa de gás seja paga. Até o momento, testamos o contrato em nossa rede local, onde todas as contas foram geradas localmente com um valor definido de ETH. Nas redes públicas, todo o novo ETH gerado é cunhado para os mineradores e, portanto, precisamos obter o ETH para executar nosso código de contrato.

Nota do tradutor: Após a fusão, ou “The Merge” da Ethereum, as transações são processadas por validadores do protocolo de consenso de prova de participação (Proof-of-Stake, ou PoS), e não mais por mineradores do protocolo de consenso de prova de trabalho (Proof-of-Work, ou PoW).

A maneira mais fácil de obter um pouco de ETH é através de torneiras (faucets). Torneiras são sites financiados pela comunidade, onde os usuários podem solicitar que o ETH seja enviado para uma carteira de propriedade privada. Observe que é melhor enviar esses fundos para uma carteira de desenvolvedor separada, pois as chaves privadas serão necessárias em texto simples posteriormente. As torneiras são usadas no ambiente de teste como uma maneira de circular o ETH da rede de teste para os desenvolvedores usarem. Você pode encontrar facilmente esses sites fazendo uma pesquisa, mas vinculei 2 desses sites abaixo:

Depois de obter um pouco de ETH, vamos em frente adicionar a rede ao nosso hardhat.config.js para que Hardhat saiba onde implantar.

Image description

Para que o Hardhat implante o contrato para a rede Goerli, ele precisa de duas coisas adicionais:

  • Um nó Goerli ao qual ele pode se conectar para enviar a transação para a rede

  • A carteira que será usada para implantar o contrato

Para que a API se conecte ao nó, você pode gerar um se inscrevendo em alchemy.io, criando um novo aplicativo e copiando a API KEY sob a “ VIEW KEY ” no painel do aplicativo. Observe que você só precisa se inscrever na conta gratuita para poder pular as informações de pagamento.

alchemy.io

Em seguida, precisaremos da chave privada da conta que pagará pela implantação do contrato. Para obter a chave privada da conta que recebeu o ETH da torneira, você pode exportá-la diretamente da Metamask em “Detalhes da Conta”. Copie e cole essa chave privada no arquivo de configuração.

Com isso, agora estamos prontos para implantar o contrato usando o seguinte comando:

npx hardhat run scripts/deploy.js --network goerli

Você deve ter notado que, ao contrário do ambiente local, a confirmação da transação não foi instantânea e isso ocorreu porque a transação teve que ser processada pela testnet Goerli. Isso mostra como o ciclo de desenvolvimento pode ser demorado se não houver um ambiente local disponível. Observe também que os saldos de ETH na conta especificada diminuíram em um pequeno valor devido às taxas de gás.

Depois de implantado, seu console deve emitir o endereço do contrato recém-implantado:

Lembre-se que o contrato DecentralisedNFT nos exige cunhar os NFTs da coleção após a implantação do contrato. Podemos reutilizar o script interact.js que executamos na seção anterior para isso. Na ordem, para o interact.js  interagir com nosso contrato implantado na Goerli, precisamos apenas mudar o contractAddress para o endereço acima, salvar e o Hardhat fará o resto do trabalho pesado. Agora podemos executar o script interact.js na testnet Goerli executando o seguinte comando:

npx hardhat run --network goerli scripts / interact.js

Isso retornará todos os seguintes logs:

Como parte do nosso script, cunhamos 3 NFTs na testnet, cada uma contendo os metadados da imagem. Como os metadados são um endereço IPFS, também podemos colar os dados em um navegador habilitado com IPFS para obter os dados armazenados no IPFS. Observe que os dados estão sendo distribuídos do seu nó IPFS local, portanto, seu nó precisa estar online para que o link funcione. Abaixo está um exemplo de dados para o tokenId 3 que foi criado:

Link

E colando o URI da imagem no mesmo navegador:

Link

Essa é uma captura de tela única da minha conta do Twitter: https://twitter.com/kai27_crypto! Talvez um dia valha milhões. Siga para mais análises e guias relacionados à criptografia; )

Piadas à parte, isso cobre o lado do IPFS, mas ainda precisamos ver nosso token para validar se ele está realmente na cadeia. Podemos fazer isso adicionando nosso contrato de token à Metamask. Abra a Metamask e navegue até a guia “ativos”, onde você verá um link “ Importar tokens ”. Selecione o link e insira o endereço do contrato O campo “ Símbolo do token ” deve ser preenchido automaticamente, mas você precisará inserir 0 para o campo decimal.

Depois de importado, você poderá ver os 3 DNFT na sua carteira.

Você deve ter notado que, diferentemente da implementação do ERC20, o botão “enviar” para o nosso ERC721 NFT foi desativado. Infelizmente, a extensão para desktop da Metamask não suporta atualmente as funcionalidades adicionais deo NFT. Para ver nosso NFT sendo transferida, podemos interagir com nosso contrato por meio de carteiros NFT que suportam essas funções ou criar outro script para interagir programaticamente. Como exemplo deste último, transfer.js mostra uma simples transferência de uma coleção  NFT .

Image description

npx hardhat run --network goerli scripts / transfer.js

Executando o código acima, o NFT 1 foi enviada para minha outra carteira de desenvolvedor:

Todas essas transações são visíveis publicamente, portanto, você pode usar ferramentas como o Etherscan para visualizar e analisar transações. Por exemplo, a transação que acabei de enviar pode ser encontrada aqui:

Para NFTs, você também pode visualizar todas os NFTs da coleção usando o rastreador de token que pode ser acessado a partir da página de visão geral do contrato principal.

Parabéns, você criou com sucesso o seu próprio NFT ERC721, que se vincula a uma imagem armazenada no IPFS! Lembre-se de que se a imagem no IPFS mudar, mesmo que seja um único pixel, o CID também mudará, anulando a autenticidade do NFT. Essa estrutura não se limita apenas aos dados da imagem e, portanto, abre caminho para a propriedade descentralizada de qualquer tipo de dados!

Obrigado por ficar até o fim. Gostaria de ouvir seus pensamentos / comentários, então deixe um comentário. Estou ativo no twitter @AwKaiShin se você quiser receber algumas informações mais digeríveis relacionadas a ativos criptográficos ou visite meu site pessoal se você quiser meus serviços: )


Este artigo foi escrito por Aw Kai Shin e traduzido por Adriano P. de Araujo. O original em inglês pode ser encontrado aqui.

Top comments (0)