Pular para o conteúdo principal

Como criar um NFT (Segunda parte da série de tutoriais sobre NFT)

ERC-721alchemysoliditycontratos inteligentes
Iniciante
Sumi Mudgil
22 de abril de 2021
9 minutos de leitura minute read

Beeple(opens in a new tab): 69 milhões de doláres 3LAU(opens in a new tab): 11 milhões de doláres Grimes(opens in a new tab): 6 milhões de doláres

All of them minted their NFTs using Alchemy’s powerful API. Neste tutorial, vamos te ensinar a fazer o mesmo em < 10 minutos.

"Cunhar um NFT" é o ato de publicar uma instância única do seu token ERC-721 na blockchain. Usando nosso contrato inteligente da Parte 1 desta série de tutoriais NFT, vamos usar nossas habilidades Web3 e criar um NFT. No final deste tutorial, você será capaz de cunhar tantos NFTs quanto seu coração (e sua carteira) desejar!

Vamos começar!

Etapa 1: Instalar a Web3

Se você seguiu o primeiro tutorial sobre a criação do seu contrato inteligente NFT, você já tem experiência usando a Ethers.js. Web3 é semelhante a Ethers, uma vez que é uma biblioteca usada para facilitar a criação de solicitações para a blockchain Ethereum. Neste tutorial, usaremos a Alchemy Web3(opens in a new tab), que é uma biblioteca Web3 aprimorada que oferece novas tentativas automáticas e um suporte WebSocket sólido.

No diretório inicial do seu projeto execute:

1yarn add @alch/alchemy-web3

Etapa 2: Criar um arquivo mint-nft.js

Dentro do seu diretório de scripts, crie um arquivo mint-nft.js e adicione as seguintes linhas de código:

1require("dotenv").config()
2const API_URL = process.env.API_URL
3const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
4const web3 = createAlchemyWeb3(API_URL)
Copiar

Etapa 3: Conseguir sua ABI de contrato

Nossa ABI (Interface binária de aplicativo) de contrato é a interface para interagir com nosso contrato inteligente. Você pode aprender mais sobre ABIs de contratos aqui(opens in a new tab). O Hardhat automaticamente gera uma ABI para nós e a salva no arquivo MyNFT.json. Para usar isso, precisaremos distribuir o conteúdo adicionando as seguintes linhas de código ao nosso arquivo mint-nft.js:

1const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json")
Copiar

Se quiser ver a ABI, pode imprimi-la no console:

1console.log(JSON.stringify(contract.abi))
Copiar

Para executar o mint-nft.js e ver seu ABI impresso no console, navegue até seu terminal e execute:

1node scripts/mint-nft.js
Copiar

Etapa 4: Configurar os metadados para seu NFT usando IPFS

Se você se lembra do nosso tutorial na Parte 1, nossa função do contrato inteligente mintNFT assume um parâmetro tokenURI que deve resolver em um documento JSON, descrevendo os metadados do NFT, o que realmente dá vida ao NFT, permitindo que ele tenha propriedades configuráveis, tais como: nome, descrição, imagem e outros atributos.

Interplanetary File System (IPFS) é um protocolo descentralizado e uma rede peer-to-peer para armazenar e compartilhar dados em um sistema de arquivos distribuído.

Usaremos o Pinata, uma API IPFS e um kit de ferramentas práticos, para armazenar nossos ativos e metadados NFT para garantir que nosso NFT seja realmente descentralizado. Se você não tem uma conta em Pinata, cadastre-se aqui(opens in a new tab) gratuitamente e conclua as etapas de confirmação de seu e-mail.

Assim que você tiver criado sua conta:

  • Navegue até a página "Files" e clique no botão azul "Upload" no canto superior esquerdo da página.

  • Faça o upload de uma imagem no Pinata — este será o recurso de imagem para o seu NFT. Sinta-se à vontade para nomear o ativo da forma que quiser

  • Após o upload, você verá as informações do arquivo na tabela da página "Arquivos". Você também verá a coluna CID. Você pode copiar o CID clicando no botão de cópia ao lado dele. Você pode ver seu ‘upload’ em: https://gateway.pinata.cloud/ipfs/<CID>. Você pode encontrar a imagem que usamos no IPFS aqui(opens in a new tab), por exemplo.

Para os que aprendem de maneira mais visual, os passos acima são resumidos aqui:

Como fazer o upload de sua imagem para Pinata

Agora, nós queremos enviar mais um documento para o Pinata. Mas antes, precisamos criá-lo!

Em seu diretório raiz, faça um novo arquivo chamado nft-metadata.json e adicione o seguinte código json:

1{
2 "attributes": [
3 {
4 "trait_type": "Breed",
5 "value": "Maltipoo"
6 },
7 {
8 "trait_type": "Eye color",
9 "value": "Mocha"
10 }
11 ],
12 "description": "The world's most adorable and sensitive pup.",
13 "image": "ipfs://QmWmvTJmJU3pozR9ZHFmQC2DNDwi2XJtf3QGyYiiagFSWb",
14 "name": "Ramses"
15}
Exibir tudo
Copiar

Sinta-se à vontade para mudar os dados no json. Você pode remover ou adicionar na seção de atributos. O mais importante é se certificar de que o campo de imagem aponta para a localização da sua imagem IPFS — caso contrário, seu NFT incluirá uma foto de um cachorro (bem bonito, por sinal).

Uma vez terminada a edição do arquivo JSON, salve-o e faça o upload para o Pinata, seguindo os mesmos passos que fizemos para o upload da imagem.

Como fazer o upload de seu nft-metadata.json para Pinata

Etapa 5: Criar uma instância de seu contrato

Agora, para interagir com o nosso contrato, precisamos criar uma instância dele em nosso código. Para fazer isso, precisaremos do nosso endereço de contrato, obtido na implantação ou no Etherscan(opens in a new tab), procurando o endereço que você usou para implantar o contrato.

Veja o seu endereço de contrato no Etherscan

No exemplo acima, o endereço do contrato é 0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778.

Em seguida, usaremos o método do contrato(opens in a new tab) Web3 para criar nosso contrato usando a ABI e o endereço. Em seu arquivo mint-nft.js, adicione o seguinte:

1const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778"
2
3const nftContract = new web3.eth.Contract(contract.abi, contractAddress)
Copiar

Etapa 6: Atualize o arquivo .env

Agora, para criar e enviar transações para a cadeia Ethereum, usaremos seu endereço de conta Ethereum para obter o nonce da conta (explicaremos abaixo).

Adicione sua chave pública ao seu arquivo .env — se você concluiu a parte 1 do tutorial, nosso arquivo .env deve ficar assim:

1API_URL = "https://eth-sepolia.g.alchemy.com/v2/your-api-key"
2PRIVATE_KEY = "your-private-account-address"
3PUBLIC_KEY = "your-public-account-address"
Copiar

Etapa 7: Criar sua transação

Primeiro, vamos definir a função nomeada mintNFT(tokenData) e criar nossa transação através do seguinte:

  1. Pegue a PRIVATE_KEY e a PUBLIC_KEY do arquivo .env.

  2. Em seguida, precisaremos descobrir qual é o nonce da conta. A especificação nonce é usada para acompanhar o número de transações enviadas a partir do seu endereço — que precisamos para fins de segurança e evitar ataques de replay(opens in a new tab). Para obter o número de transações enviadas a partir do seu endereço, usamos getTransactionCount(opens in a new tab).

  3. Finalmente, vamos configurar nossa transação com as seguintes informações:

  • 'from': PUBLIC_KEY: a origem da nossa transação é nosso endereço público

  • 'to': contractAddress: o contrato com o qual queremos interagir e ao qual enviar a transação

  • 'nonce': nonce — O nonce da conta com o número de transações enviadas do nosso endereço

  • 'gas': estimatedGas: o gás estimado necessário para completar a transação

  • 'data': nftContract.methods.mintNFT(PUBLIC_KEY, md).encodeABI(): o cálculo que queremos realizar nesta transação que, neste caso, é cunhar um NFT

Seu arquivo mint-nft.js deverá ficar assim:

1 require('dotenv').config();
2 const API_URL = process.env.API_URL;
3 const PUBLIC_KEY = process.env.PUBLIC_KEY;
4 const PRIVATE_KEY = process.env.PRIVATE_KEY;
5
6 const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
7 const web3 = createAlchemyWeb3(API_URL);
8
9 const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json");
10 const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778";
11 const nftContract = new web3.eth.Contract(contract.abi, contractAddress);
12
13 async function mintNFT(tokenURI) {
14 const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest'); //get latest nonce
15
16 //the transaction
17 const tx = {
18 'from': PUBLIC_KEY,
19 'to': contractAddress,
20 'nonce': nonce,
21 'gas': 500000,
22 'data': nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI()
23 };
24 }
Exibir tudo
Copiar

Etapa 8: Assinar a transação

Agora que criamos a nossa transação, precisamos assiná-la para poder enviá-la. É aqui que usaremos nossa chave privada.

web3.eth.sendSignedTransaction nos dará o hash da transação, que podemos usar para ter certeza de que nossa transação foi minerada e não foi descartada pela rede. Você vai notar na seção de assinatura de transações que adicionamos alguma verificação de erro para saber se nossa transação foi processada com sucesso.

1require("dotenv").config()
2const API_URL = process.env.API_URL
3const PUBLIC_KEY = process.env.PUBLIC_KEY
4const PRIVATE_KEY = process.env.PRIVATE_KEY
5
6const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
7const web3 = createAlchemyWeb3(API_URL)
8
9const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json")
10const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778"
11const nftContract = new web3.eth.Contract(contract.abi, contractAddress)
12
13async function mintNFT(tokenURI) {
14 const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //get latest nonce
15
16 //the transaction
17 const tx = {
18 from: PUBLIC_KEY,
19 to: contractAddress,
20 nonce: nonce,
21 gas: 500000,
22 data: nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI(),
23 }
24
25 const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY)
26 signPromise
27 .then((signedTx) => {
28 web3.eth.sendSignedTransaction(
29 signedTx.rawTransaction,
30 function (err, hash) {
31 if (!err) {
32 console.log(
33 "The hash of your transaction is: ",
34 hash,
35 "\nCheck Alchemy's Mempool to view the status of your transaction!"
36 )
37 } else {
38 console.log(
39 "Something went wrong when submitting your transaction:",
40 err
41 )
42 }
43 }
44 )
45 })
46 .catch((err) => {
47 console.log(" Promise failed:", err)
48 })
49}
Exibir tudo
Copiar

Etapa 9: Chame mintNFT e execute o nó mint-nft.js

Lembra do metadata.json que você carregou no Pinata? Obtenha o seu hashcode no Pinata e transmita o seguinte como parâmetro para a função mintNFT https://gateway.pinata.cloud/ipfs/<metadata-hash-code>

Veja como obter o hashcode:

Como obter seu hashcode de metadados do nft no PinataComo obter seu hashcode de metadados do nft no Pinata

Verifique se o hashcode que você copiou se vincula ao metadata.json ao carregar https://gateway.pinata.cloud/ipfs/<metadata-hash-code> em uma janela separada. A página deve parecer semelhante à imagem abaixo:

Sua página deve exibir os metadados jsonSua página deve exibir os metadados json

O código deve parecer com isso:

1require("dotenv").config()
2const API_URL = process.env.API_URL
3const PUBLIC_KEY = process.env.PUBLIC_KEY
4const PRIVATE_KEY = process.env.PRIVATE_KEY
5
6const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
7const web3 = createAlchemyWeb3(API_URL)
8
9const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json")
10const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778"
11const nftContract = new web3.eth.Contract(contract.abi, contractAddress)
12
13async function mintNFT(tokenURI) {
14 const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //get latest nonce
15
16 //the transaction
17 const tx = {
18 from: PUBLIC_KEY,
19 to: contractAddress,
20 nonce: nonce,
21 gas: 500000,
22 data: nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI(),
23 }
24
25 const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY)
26 signPromise
27 .then((signedTx) => {
28 web3.eth.sendSignedTransaction(
29 signedTx.rawTransaction,
30 function (err, hash) {
31 if (!err) {
32 console.log(
33 "The hash of your transaction is: ",
34 hash,
35 "\nCheck Alchemy's Mempool to view the status of your transaction!"
36 )
37 } else {
38 console.log(
39 "Something went wrong when submitting your transaction:",
40 err
41 )
42 }
43 }
44 )
45 })
46 .catch((err) => {
47 console.log("Promise failed:", err)
48 })
49}
50
51mintNFT("ipfs://QmYueiuRNmL4MiA2GwtVMm6ZagknXnSpQnB3z2gWbz36hP")
Exibir tudo
Copiar

Agora, execute node scripts/mint-nft.js para implantar seu NFT. Depois de alguns segundos, você deverá ver uma resposta como essa no seu terminal:

1O hash de sua transação é: 0x301791fdf492001fcd9d5e5b12f3aa1bbbea9a88ed24993a8ab2cdae2d06e1e8
2
3Verifique o Mempool da Alquemy para ver o estado da sua transação!

Em seguida, acesse a mempool (área de espera) da Alchemy(opens in a new tab) para ver o estado da sua transação (se pendente, minerada ou recusada pela rede). Se a sua transação se perdeu, também é útil verificar no Sepolia Etherscan(opens in a new tab) e procurar o hash da transação.

Veja seu hash de transação NFT no EtherscanVeja seu hash de transação NFT no Etherscan

E pronto! Você agora implantou E cunhou um NFT na blockchain Ethereum

Using the mint-nft.js you can mint as many NFTs as your heart (and wallet) desires! Apenas certifique-se de transmitir um novo tokenURI descrevendo os metadados do NFT (caso contrário, você acaba criando um monte de identificações idênticas, com IDs diferentes).

Provavelmente você gostaria de poder exibir seu NFT na sua carteira — então certifique-se de conferir Parte 3: Como ver seu NFT na sua carteira!

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

Este tutorial foi útil?