Pular para o conteúdo principal

Como escrever e implantar um NFT (Primeira parte da série de tutoriais sobre NFT)

ERC-721AlchemySoliditycontratos inteligentes
Intermediário
Sumi Mudgil
22 de abril de 2021
13 minutos de leitura minute read

Com os NFTs trazendo a blockchain aos olhos do público, agora é uma excelente oportunidade para entender a tendência publicando seu próprio contrato NFT (ERC-721 Token) na blockchain Ethereum!

A Alchemy tem muito orgulho por estar no espaço NFT com os maiores nomes incluindo Makersplace (recentemente atingiu a marca de 69 milhões de doláres em vendas de artes digitais), Dapper Labs (criadores do NBA Top Shot e Crypto Kitties), OpenSea (o maior mercado de NFT do mundo), Zora, Super Rare, NFTfi, Foundation, Enjin, Origin Protocol, Immutable e muito mais.

Neste tutorial, nós vamos criar e implantar um contrato inteligente ERC-721 na rede de teste Sepolia usando MetaMask(opens in a new tab), Solidity(opens in a new tab), Hardhat(opens in a new tab), Pinata(opens in a new tab) e Alquimia(opens in a new tab) (não se preocupe caso não entender o que tudo isso significa — explicaremos tudo!).

Na parte 2 deste tutorial, veremos como podemos usar nosso contrato inteligente para gerar NFT, e na Parte 3, explicaremos como ver seu NFT no MetaMask.

E claro, se você tiver dúvidas a qualquer momento, acesso o Alchemy Discord(opens in a new tab) ou visite a página de Documentação sobre a API NFT da Alchemy(opens in a new tab)!

Etapa 1: Se conectar à rede Ethereum

Existem várias maneiras de fazer solicitações para a blockchain Ethereum, mas para facilitar as coisas, usaremos uma conta gratuita na Alchemy(opens in a new tab), uma plataforma e API de desenvolvedores de blockchain que nos permite nos comunicar com a cadeia Ethereum sem ter que executar os nossos próprios nós.

Neste tutorial, também aproveitaremos as ferramentas de desenvolvedor da Alchemy para fins de monitoramento e análise, para entender o que está acontecendo nos bastidores da nossa implantação de contrato inteligente. Se você ainda não tiver uma conta da Alchemy, inscreva-se gratuitamente aqui(opens in a new tab).

Etapa 2: Criar seu aplicativo (e chave de API)

Assim que criar uma conta na Alchemy, você pode gerar uma chave de API criando um "app". Isso nos permitirá fazer solicitações à rede de teste Sepolia. Confira este guia(opens in a new tab) se você está curioso para aprender mais sobre as redes de teste.

  1. Vá até a página "Create App" no painel da Alchemy, passe o mouse sobre a palavra "Apps" na barra de navegação e clique em "Create App"

Crie seu aplicativo

  1. Nomeie seu app (nós escolhemos “Meu primeiro NFT!”), ofereça uma breve descrição, selecione “Ethereum” para a rede e escolha “Sepolia” para sua rede. Desde a fusão, as outras redes de teste foram descontinuadas.

Configure e publique seu aplicativo

  1. Clique em "Create App", e é isso e tudo! Seu app deveria aparecer na tabela abaixo.

Etapa 3: Criar uma conta Ethereum (endereço)

Precisamos de uma conta Ethereum para enviar e receber transações. Para este tutorial, usaremos uma carteira virtual no navegador, a MetaMask, para gerenciar o endereço da sua conta Ethereum. Se você quiser entender mais sobre como as transações no Ethereum funcionam, confira esta página na Fundação Ethereum.

Você pode baixar e criar uma conta MetaMask gratuitamente neste link(opens in a new tab). Quando você estiver criando uma conta, ou se você já tiver uma, certifique-se de mudar para a “Sepolia Test Network” no canto superior direito (para que não lidemos com dinheiro real).

Defina Sepolia como sua rede

Etapa 4: Adicionar ether de um faucet

Para implementar nosso contrato inteligente na rede de teste, precisaremos de alguns ETHs de imitação. Para obter ETH, você pode acessar a Torneira da Sepolia(opens in a new tab) hospedada pela Alchemy, fazer login, inserir o endereço da sua conta e clicar em "Enviar-me ETH". Você deveria ver o ETH na sua conta MetaMask logo depois!

Etapa 5: Verificar seu saldo

Para verificar novamente que temos saldo, vamos fazer uma solicitação através da ferramenta eth_getBalance(opens in a new tab) fornecida pelo compositor da Alchemy(opens in a new tab). Ele mostrará a quantidade de ETH em nossa carteira. Depois de inserir o endereço da sua conta da MetaMask e clicar em "Send Request", você verá uma resposta como esta:

1`{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}`

Nota Este resultado está em wei, não em ETH. Lembre-se de que o wei é a menor unidade do ether. A conversão de wei para ETH é 1 eth = 1018 wei. Então, se convertemos 0xde0b6b3a7640000 para decimal, temos 1*1018 wei, que é igual a 1 ETH.

Ufa! O nosso dinheiro falso está todo lá.

Etapa 6: Dar início a nosso projeto

Primeiro, precisamos criar uma pasta para o nosso projeto. Navegue até sua linha de comando e digite:

1mkdir my-nft
2cd my-nft

Agora que estamos dentro da pasta do nosso projeto, vamos usar npm init para inicializá-lo. Se você ainda não tiver o npm instalado, siga estas instruções(opens in a new tab) (nós também vamos precisar do Node.js(opens in a new tab), então baixe isso também!).

1npm init

Não importa realmente como você responde às questões de instalação; aqui está o que utilizamos de referência:

1package name: (my-nft)
2version: (1.0.0)
3description: My first NFT!
4entry point: (index.js)
5test command:
6git repository:
7keywords:
8author:
9license: (ISC)
10About to write to /Users/thesuperb1/Desktop/my-nft/package.json:
11
12{
13 "name": "my-nft",
14 "version": "1.0.0",
15 "description": "My first NFT!",
16 "main": "index.js",
17 "scripts": {
18 "test": "echo \"Error: no test specified\" && exit 1"
19 },
20 "author": "",
21 "license": "ISC"
22}
Exibir tudo

Aprove o package.json e estamos prontos para começar!

Etapa 7: Instalar o Hardhat(opens in a new tab)

Hardhat é um ambiente de desenvolvimento para compilar, implementar, testar e depurar seu software de Ethereum. Ele ajuda os desenvolvedores na criação de contratos inteligentes e dapps localmente antes de implantar na cadeia real.

Dentro do nosso projeto my-nft execute:

1npm install --save-dev hardhat

Para mais detalhes, confira esta página sobre as instruções de instalação(opens in a new tab).

Etapa 8: Criar o projeto Hardhat

Dentro da nossa pasta de projeto, execute:

1npx hardhat

Você deve então ver uma mensagem de boas-vindas e a opção de selecionar o que quer fazer. Selecione "criar uma hardhat.config.js vazia":

1888 888 888 888 888
2888 888 888 888 888
3888 888 888 888 888
48888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
5888 888 "88b 888P" d88" 888 888 "88b "88b 888
6888 888 .d888888 888 888 888 888 888 .d888888 888
7888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
8888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888
9👷 Welcome to Hardhat v2.0.11 👷‍
10? O que você deseja fazer? …
11Create a sample project
12❯ Create an empty hardhat.config.js
13Quit
Exibir tudo

Isso vai gerar um arquivo hardhat.config.js, no qual especificaremos todas as configurações para o nosso projeto (no passo 13).

Etapa 9: Adicionar as pastas do projeto

Para manter a organização do nosso projeto, vamos criar duas novas pastas. Navegue até o diretório raiz do seu projeto na sua linha de comando e digite:

1mkdir contracts
2mkdir scripts
  • contracts/ é onde manteremos o nosso código de contrato inteligente para o NFT

  • scripts/ é onde manteremos scripts para implantar e interagir com nosso contrato inteligente

Etapa 10: Escrever nosso contrato

Agora que nosso ambiente de trabalho está configurado, iremos para a parte mais emocionante: escrever nosso contrato de código inteligente!

Abra o projeto my-nft no seu editor favorito (nós gostamos do VSCode(opens in a new tab)). Os contratos inteligentes são escritos em uma linguagem chamada Solidity, que usaremos para escrever nosso contrato inteligente MyNFT.sol.

  1. Navegue até a pasta de contracts e crie um novo arquivo chamado MyNFT.sol

  2. Abaixo está o nosso código de contrato inteligente NFT, nossa base para a implementação do ERC-721 da biblioteca OpenZeppelin(opens in a new tab). Copie e cole o conteúdo abaixo no seu arquivo MyNFT.sol.

    1//Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721)
    2// SPDX-License-Identifier: MIT
    3pragma solidity ^0.8.0;
    4
    5import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
    6import "@openzeppelin/contracts/utils/Counters.sol";
    7import "@openzeppelin/contracts/access/Ownable.sol";
    8import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
    9
    10contract MyNFT is ERC721URIStorage, Ownable {
    11 using Counters for Counters.Counter;
    12 Counters.Counter private _tokenIds;
    13
    14 constructor() ERC721("MyNFT", "NFT") {}
    15
    16 function mintNFT(address recipient, string memory tokenURI)
    17 public onlyOwner
    18 returns (uint256)
    19 {
    20 _tokenIds.increment();
    21
    22 uint256 newItemId = _tokenIds.current();
    23 _mint(recipient, newItemId);
    24 _setTokenURI(newItemId, tokenURI);
    25
    26 return newItemId;
    27 }
    28}
    Exibir tudo
    Copiar
  3. Como estamos herdando classes da biblioteca de contratos OpenZeppelin, na linha de comando execute npm install @openzeppelin/contracts para instalar a biblioteca em nossa pasta.

Então, o que esse código faz exatamente? Vamos por partes, linha por linha.

No topo do nosso contrato inteligente, importamos três classes de contrato inteligente OpenZeppelin(opens in a new tab):

  • @openzeppelin/contracts/token/ERC721/ERC721.sol contém a implementação do padrão ERC-721, que nosso contrato inteligente NFT herdará. (Para ser um NFT válido, seu contrato inteligente deve implementar todos os métodos do padrão ERC-721.) Para saber mais sobre as funções herdadas do ERC-721, confira a definição da interface aqui(opens in a new tab).

  • @openzeppelin/contracts/utils/Counters.sol fornece contadores que só podem ser incrementados ou diminuídos por um. Nosso contrato inteligente usa um contador para acompanhar o número total de NFTs impressos e definir o ID exclusivo em nosso novo NFT. (Cada NFT cunhado usando um contrato inteligente deve ter um ID único – aqui nosso ID exclusivo é determinado pelo número total de NFTs existentes. Por exemplo, o primeiro NFT que cunhamos com o nosso contrato inteligente tem um ID igual a "1," nosso segundo NFT tem um ID igual a "2," etc.)

  • @openzeppelin/contratos/access/Ownable.sol configura controle de acesso(opens in a new tab) em nosso contrato inteligente, então apenas o proprietário do contrato inteligente (você) pode 'cunhar' NFTs. (Observação, incluir controle de acesso é inteiramente uma preferência. Se você quer que qualquer pessoa consiga gerar um NFT usando seu contrato inteligente, remove a palavra "Ownable" na linha 10 e "onlyOwner" na linha 17.)

Depois de seguir nossas instruções de importação, temos o nosso contrato inteligente de NFT, que é surpreendentemente curto – contém apenas um contador, um construtor e uma única função! Isso se deve aos nossos contratos OpenZeppelin herdados, que implementam a maioria dos métodos de que precisamos para criar um NFT, tal como ownerOf, que retorna o proprietário do NFT, e transferFrom, que transfere a propriedade do NFT de uma conta para outra.

No nosso construtor ERC-721, você notará que transmitimos duas cadeias de caracteres: "MyNFT" e "NFT" A primeira variável é o nome do contrato inteligente e a segunda é símbolo dele. Você pode nomear cada uma dessas variáveis como quiser!

Finalmente, temos nossa função mintNFT(destinatário de endereço, string memory tokenURI), que nos permite cunhar um NFT! Você vai notar que essa função recebe duas variáveis:

  • address recipient especifica o endereço que receberá o seu NFT recém-cunhado

  • string memory tokenURI é uma string que deve ser resolvida em um documento JSON que descreve os metadados do NFT. Os metadados de um NFT são o que realmente o torna realidade, permitindo que tenha propriedades configuráveis, como um nome, descrição, imagem e outros atributos. Na parte 2 deste tutorial, descreveremos como configurar este metadado.

mintNFT chama alguns métodos da biblioteca ERC-721 herdada, e retorna um número que representa a ID do NFT recém-cunhado.

Etapa 11: Vincular as contas MetaMask e Alchemy a seu projeto

Agora que criamos uma carteira MetaMask, uma conta Alchemy, e escrevemos o nosso contrato inteligente, é hora de vincular os três.

Toda transação enviada da sua carteira virtual requer uma assinatura, usando sua chave privada única. Para fornecer esta permissão a nosso programa, podemos armazenar nossa chave privada (e a chave Alchemy API) em um arquivo de ambiente.

Para saber mais sobre o envio de transações, confira este tutorial sobre o envio de transações usando web3.

Primeiro, instale o pacote dotenv na pasta do seu projeto:

1npm install dotenv --save

Então crie um arquivo .env no diretório raiz do nosso projeto e adicione sua chave privada do MetaMask e sua URL HTTP da API Alchemy a ele.

Copie o URL da API Alchemy

Seu arquivo .env ficará assim:

1API_URL="https://eth-sepolia.g.alchemy.com/v2/your-api-key"
2PRIVATE_KEY="your-metamask-private-key"

Para realmente conectá-las ao nosso código, referenciaremos essas variáveis em nosso arquivo hardhat.config.js na etapa 13.

page-tutorials-env-banner

Etapa 12: Instalar o Ethers.js

Ethers.js é uma biblioteca que facilita a interação e o envio de solicitações ao Ethereum ao incorporar métodos padrões JSON-RPC a outros métodos mais amigáveis ao usuário.

Hardhat torna muito fácil a integração de plugins(opens in a new tab), para ferramentas adicionais e funcionalidades extendidas. Aproveitaremos o plugin Ethers(opens in a new tab) para implantação de contratos. (Ethers.js(opens in a new tab) tem alguns métodos de implantação de contratos bastante claros).

No diretório do projeto, digite:

1npm install --save-dev @nomiclabs/hardhat-ethers ethers@^5.0.0

Também precisaremos de ethers em nosso hardhat.config.js na próxima etapa.

Etapa 13: Atualizar hardhat.config.js

Até aqui, já adicionamos diversas dependências e plugins. Agora precisamos atualizar o hardhat.config.js para que nosso projeto reconheça todos eles.

Atualize seu hardhat.config.js para ficar assim:

1/**
2* @type import('hardhat/config').HardhatUserConfig
3*/
4require('dotenv').config();
5require("@nomiclabs/hardhat-ethers");
6const { API_URL, PRIVATE_KEY } = process.env;
7module.exports = {
8 solidity: "0.8.1",
9 defaultNetwork: "sepolia",
10 networks: {
11 hardhat: {},
12 sepolia: {
13 url: API_URL,
14 accounts: [`0x${PRIVATE_KEY}`]
15 }
16 },
17}
Exibir tudo

Etapa 14: Compilar nosso contrato

Para ter certeza de que tudo está funcionando, vamos compilar nosso contrato. A tarefa de compilação é uma das tarefas integradas do Hardhat.

Na linha de comando, execute:

1npx hardhat compile

Você pode receber o aviso do identificador de licença SPDX não fornecido no arquivo fonte, mas não há necessidade de se preocupar com isso. Esperemos que tudo mais esteja bem! Se não, você sempre pode enviar uma mensagem no discord Alchemy(opens in a new tab).

Etapa 15: Escrever nosso script de implantação

Agora que nosso contrato está escrito e nosso arquivo de configuração está pronto, é hora de escrever o script de implantação do contrato.

Navegue até a pasta scripts/ e crie um novo arquivo chamado deploy.js, adicionando o seguinte conteúdo:

1async function main() {
2 const MyNFT = await ethers.getContractFactory("MyNFT")
3
4 // Start deployment, returning a promise that resolves to a contract object
5 const myNFT = await MyNFT.deploy()
6 await myNFT.deployed()
7 console.log("Contract deployed to address:", myNFT.address)
8}
9
10main()
11 .then(() => process.exit(0))
12 .catch((error) => {
13 console.error(error)
14 process.exit(1)
15 })
Exibir tudo
Copiar

A Hardhat fez um trabalho incrível ao explicar o que cada uma dessas linhas de código faz em seu Tutorial sobre contratos(opens in a new tab). Adotamos aqui as explicações deles.

1const MyNFT = await ethers.getContractFactory("MyNFT");

Uma ContractFactory em ethers.js é uma abstração usada para implantar novos contratos inteligentes, então a MyNFT aqui representa uma fábrica para instâncias do nosso contrato NFT. Ao usar o plug-in hardhat-ethers, as instâncias ContractFactory e Contract são conectadas ao primeiro signatário por padrão.

1const myNFT = await MyNFT.deploy();

Ao chamar deploy() em uma ContractFactory, a implantação se iniciará e retornará uma Promise que se resolve em um Contract. Este é o objeto que tem um método para cada uma de nossas funções de contrato inteligente.

Etapa 16: Implantar nosso contrato

Finalmente estamos prontos para implantar o nosso contrato inteligente! Navegue de volta para a raiz do diretório do seu projeto e, na linha de comando, execute:

1npx hardhat --network sepo lia run scripts/deploy.js

Você deverá ver algo assim:

1Contrato implantado no endereço: 0x4C5266cCc4b3F426965d2f51b6D910325a0E7650

Se nós formos ao Sepolia etherscan(opens in a new tab) e procurarmos o endereço do nosso contrato, poderemos ver que ele foi implantado com sucesso. Se você não puder ver o endereço imediatamente, por favor, aguarde um momento, pois pode levar algum tempo. A transação ficará parecida com isto:

Veja o seu endereço de transação no Etherscan

O endereço do remetente (From) deve corresponder ao seu endereço da conta MetaMask e o endereço do destinatário (To) deve dizer "Contract Creation". Se clicarmos na transação, veremos o nosso endereço de contrato no campo "To":

Veja o seu endereço de contrato no Etherscan

Sim! Você acabou de implantar seu contrato inteligente NFT na cadeia Ethereum (testnet)!

Para entender o que está acontecendo nos bastidores, vamos navegar até a guia Explorer no painel do Alchemy(opens in a new tab). Se você tem vários aplicativos Alchemy certifique-se de filtrar por app e selecionar "MyNFT".

Exibir chamadas feitas "em segundo plano" com o Explorer Dashboard do Alquimia

Aqui você verá um punhado de chamadas JSON-RPC que Hardhat/Ethers fizeram em segundo plano para nós quando chamamos a função .deploy() . Dois importantes pontos a destacar aqui são eth_sendRawTransaction, que é a solicitação para realmente escrever nosso contrato inteligente na cadeia Sepolia, e eth_getTransactionByHash, que é uma solicitação para ler informações sobre nossa transação dado o hash (um padrão típico ao enviar transações). Para saber mais sobre o envio de transações, confira este tutorial sobre como enviar transações usando a web3.

Isso é tudo para a Parte 1 deste tutorial. Na Parte 2, interagiremos com o nosso contrato inteligente cunhando um NFT, e na Parte 3, mostraremos como ver o seu NFT na sua carteira Ethereum!

Última edição: @rafarocha(opens in a new tab), 19 de janeiro de 2024

Este tutorial foi útil?