Crie um Token ERC-721 (NFT)

Chegou o momento de criar nosso primeiro NFT! Vamos utilizar o Remix IDE e faremos o upload da imagem e dos metadados no IPFS.

Passo 1: Configurar o ambiente

Vamos usar o Remix como ambiente de desenvolvimento.

  • Instalação do OpenZeppelin: Se você já criou um token ERC-20 anteriormente, a biblioteca de contratos do OpenZeppelin já estará disponível no seu ambiente Remix.

Passo 2: Criar ou escolher uma imagem

Crie uma imagem com seu editor favorito (como Canva, DALL·E, Paint, etc.).

Para este exemplo, utilizaremos uma imagem quadrada (1:1).

Passo 3: Subir a imagem no IPFS

Vamos usar o serviço gratuito Pinata para subir arquivos ao IPFS de forma simples.

  1. Crie uma conta no Pinata.

  2. Acesse a aba Files.

  3. Clique em Upload e envie sua imagem.

  4. Após o upload, será gerado um CID (Content Identifier) — o identificador único da imagem (um hash).

Passo 4: Criar o JSON do NFT e subi-lo ao IPFS

Como aprendemos nos fundamentos de Solidity, os contratos usam o formato JSON para representar dados (como o ABI). Esse formato também é muito usado para guardar metadados de NFTs.

Criaremos um arquivo .json com informações simples do nosso NFT:

{
    "name": "Meu primeiro NFT",
    "description": "Um NFT criado no Ethereum Developer Pack",
    "image": "<https://ipfs.io/ipfs/Qmdae238wjRaCrNuBzNTJDeJNbuemGWQB9tioDKrrjosMY>"
}

Importante: substitua o CID da imagem (Qmdae...) pelo CID gerado no seu upload no passo anterior.

Agora salve esse conteúdo como MeuNFT.json no seu computador e faça o upload do arquivo JSON também via Pinata.

Você receberá um novo CID — no nosso exemplo: QmVjHeKjQk5snH1KAcVUPXzwSrW2e7oX1KmVQHHoPwKkuJ

Passo 5: Criar e implantar o smart contract na rede Sepolia

Vamos usar a biblioteca OpenZeppelin para aproveitar uma implementação segura do padrão ERC-721.

Abra o Remix e crie um novo contrato com o seguinte código (exemplo básico):

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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

contract MyNFT is ERC721 {
    uint256 token_count;

    constructor() ERC721("My NFT", "MNFT") {}

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_ownerOf(tokenId) != address(0), "ERC721Metadata: URI query for nonexistent token");
        return "<https://ipfs.io/ipfs/QmVjHeKjQk5snH1KAcVUPXzwSrW2e7oX1KmVQHHoPwKkuJ>";
    }

    function mintNFT(address to) public
    {
        token_count  += 1;
        _mint(to, token_count);
    }
}

Antes de implantar:

  • Certifique-se de substituir o token URI pelo link completo: ipfs://QmVjHeKjQk5snH1KAcVUPXzwSrW2e7oX1KmVQHHoPwKkuJ

Implante o contrato na testnet Sepolia, conectando sua carteira (como MetaMask) ao Remix.

Passo 6: Mintar o NFT

Com o contrato implantado, vamos usar a função mintNFT.

  1. Execute a função mintNFT.

  2. No campo to, insira seu próprio endereço (para que você seja o proprietário).

  3. No campo tokenURI, insira o link do JSON no IPFS: ipfs://QmVjHeKjQk5snH1KAcVUPXzwSrW2e7oX1KmVQHHoPwKkuJ

Confirme a transação. Pronto! Você criou seu primeiro NFT.

Você pode validar o contrato no Etherscan da Sepolia e interagir com ele diretamente por lá também.

Passo 7: Verifique que seu NFT foi criado

Para verificar que o nosso NFT foi criado e que todas as informações estão corretas, podemos acessar um marketplace de NFT como o OpenSea. Para isso, acessamos o ambiente de testes do OpenSea, já que implantamos nosso contrato em uma testnet como a Sepolia. O endereço é: https://testnets.opensea.io/

Conectamos a mesma carteira com a qual fizemos o mint do NFT. Vamos à seção de dados da conta e selecionamos o nosso perfil (Profile) para ver os NFTs que são de nossa propriedade.

Se seguirmos os passos corretamente, poderemos encontrar o nosso NFT no marketplace.

Clicando sobre ele, poderemos verificar que os metadados estão registrados corretamente.

Podemos fazer a mesma verificação no Rarible: https://testnet.rarible.com/

Parabéns por ter completado este desafio.

🫶🏻 Nota: Agradecemos a Ahmed Casto (@filosofiacodigo) por nos dar a inspiração para desenvolver esta seção.

Last updated