WEB3DEV

Cover image for Implantar um NFT animado na zkEVM com o Hardhat
Rafael Ojeda
Rafael Ojeda

Posted on

Implantar um NFT animado na zkEVM com o Hardhat

Implantar um NFT animado na zkEVM com o Hardhat

Como implantar um contrato de NFT ERC721 na rede de teste zkEVM com o Hardhat

Image description

O que é zkEVM?

Em resumo, a Polygon zkEVM é uma solução de escalonamento de camada 2 (L2) que tem como objetivo a equivalência à EVM e permite que você implante contratos de forma mais barata, rápida, segura e sem etapas adicionais usando seu código Solidity existente.

Quer entender mais a fundo? Confira meu outro artigo sobre como implantar um contrato de token ERC20 na rede de testes zkEVM.

Rede, tokens da rede de teste Goerli e ponte

Para configurar e fazer a ponte rapidamente, recomendo usar o site da Polygon zkEVM Bridge para adicionar a rede à nossa carteira e fazer a transferência de qualquer token Goerli para a rede de teste zkEVM.

Image description

https://public.zkevm-test.net/

Requisitos

Antes de começar, certifique-se de ter o seguinte instalado em seu computador e de ter configurado sua carteira e tokens da rede de teste Goerli em ponte para a rede de teste zkEVM. Se você quiser ver como fazer isso, confira meu outro artigo Como implantar um contrato ERC20 na rede de teste zkEVMt.

NVM ou Node v18.15.0

Implantando um Contrato com Hardhat

Vamos construir um NFT ERC721 e implantá-lo na zkEVM com Hardhat.

Certificando-nos de que começamos do zero, vamos utilizar o modelo do Hardhat para gerar um projeto básico em TypeScript para nós.

# Create our project folder
mkdir zkevm-erc721-hardhat;
cd zkevm-erc721-hardhat;

npx hardhat;

# Expected Output:
# Ok to proceed? (y) y
# 888    888                      888 888               888
# 888    888                      888 888               888
# 888    888                      888 888               888
# 8888888888  8888b.  888d888 .d88888 88888b.   8888b.  888888
# 888    888     "88b 888P"  d88" 888 888 "88b     "88b 888
# 888    888 .d888888 888    888  888 888  888 .d888888 888
# 888    888 888  888 888    Y88b 888 888  888 888  888 Y88b.
# 888    888 "Y888888 888     "Y88888 888  888 "Y888888  "Y888
#
# 👷 Welcome to Hardhat v2.13.0 👷‍
#
# ? What do you want to do? …
#   Create a JavaScript project
# ❯ Create a TypeScript project
#   Create an empty hardhat.config.js
#   Quit
#
# ✔ What do you want to do? · Create a TypeScript project
# ✔ Hardhat project root: · /path/to/zkevm-erc721-hardhat
# ✔ Do you want to add a .gitignore? (Y/n) · y
# ✔ Do you want to install this sample project's dependencies with npm (hardhat @nomicfoundation/hardhat-toolbox)? (Y/n) · y
Enter fullscreen mode Exit fullscreen mode

Em seguida, vamos instalar as dependências.

npme install;
npm install @openzeppelin/contracts dotenv;
Enter fullscreen mode Exit fullscreen mode

Criando nosso NFT

Para o nosso NFT, vamos fazer com que ele se destaque um pouco introduzindo um SVG animado.

Primeiro, remova o contrato modelo que foi gerado e crie um novo em seu lugar.

rm contracts/Lock.sol;
touch contracts/zkEVMNFT.sol;
Enter fullscreen mode Exit fullscreen mode

No arquivo, copie e cole o seguinte código Solidity para NFTs.

Arquivo: ./contracts/zkEVMNFT.sol

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

// Imports
// ========================================================
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/Base64.sol";

// Contract
// ========================================================
contract ZkEVMNFT is ERC721 {
   // Extending functionality
   using Strings for uint256;

   /**
    * Construtor principal
    */
   constructor() ERC721("zkEVMNFT", "zkNFT") {}

   /**
    * Função de cunhagem principal
    */
   function safeMint(address to, uint256 tokenId) public {
       _safeMint(to, tokenId);
   }

   // As funções a seguir são substituições exigidas pelo Solidity.
   /**
    * @dev See {ERC721}
    */
   function _burn(uint256 tokenId) internal override(ERC721) {
       super._burn(tokenId);
   }

   /**
    * Função pública ou queima
    */
   function burn (uint256 tokenId) public {
       _burn(tokenId);
   }

   /**
    * @dev See {IERC721Metadata-tokenURI}.
    */
   function tokenURI(uint256 tokenId)
       public
       view
       override(ERC721)
       returns (string memory)
   {
       // Validação
       require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

       // Imagem SVG
       bytes memory imageSVG = abi.encodePacked(
           "<svg width=\"256\" height=\"256\" viewBox=\"0 0 256 256\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">",
           "<style xmlns=\"http://www.w3.org/2000/svg\">@keyframes rainbow-background { 0% { fill: #ff0000; } 8.333% { fill: #ff8000; } 16.667% { fill: #ffff00; } 25.000% { fill: #80ff00; } 33.333% { fill: #00ff00; } 41.667% { fill: #00ff80; } 50.000% { fill: #00ffff; } 58.333% { fill: #0080ff; } 66.667% { fill: #0000ff; } 75.000% { fill: #8000ff; } 83.333% { fill: #ff00ff; } 91.667% { fill: #ff0080; } 100.00% { fill: #ff0000; }} #background { animation: rainbow-background 5s infinite; } #text { font-family: \"Helvetica\", \"Arial\", sans-serif; font-weight: bold; font-size: 72px; }</style>",
           "<g clip-path=\"url(#clip0_108_2)\">",
           "<rect id=\"background\" width=\"256\" height=\"256\" fill=\"#ff0000\"/>",
           "<rect x=\"28\" y=\"28\" width=\"200\" height=\"200\" fill=\"white\"/>",
           "</g>",
           "<defs>",
           "<clipPath id=\"clip0_108_2\">",
           "<rect width=\"256\" height=\"256\" fill=\"white\"/>",
           "</clipPath>",
           "</defs>",
           "<text xmlns=\"http://www.w3.org/2000/svg\" id=\"text\" x=\"128\" y=\"150\" fill=\"black\" style=\"width: 256px; display: block; text-align: center;\" text-anchor=\"middle\">", tokenId.toString(), "</text>",
           "</svg>"
       );

       // JSON
       bytes memory dataURI = abi.encodePacked(
           "{",
               "\"name\": \"NUMSVG #", tokenId.toString(), "\",",
               "\"image\": \"data:image/svg+xml;base64,", Base64.encode(bytes(imageSVG)), "\"",
           "}"
       );

       // JSON Retornado
       return string(
           abi.encodePacked(
               "data:application/json;base64,",
               Base64.encode(dataURI)
           )
       );
   }
}
Enter fullscreen mode Exit fullscreen mode

Configurando o Hardhat

Estamos quase lá. Em seguida, vamos configurar o arquivo de configuração do Hardhat para permitir que as variáveis ​​de ambiente sejam carregadas, configurar o suporte à rede e ajustar para a otimização.

Arquivo: ./hardhat.config.ts

// Importações
// ========================================================
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import dotenv from "dotenv";

// Configurações
// ========================================================
dotenv.config();
const config: HardhatUserConfig = {
 solidity: {
   version: "0.8.18",
   settings: {
     optimizer: {
       enabled: true,
       runs: 200,
     }
   }
 },
 networks: {
   mumbai: {
     url: `${process.env.RPC_MUMBAI_URL || ''}`,
     accounts: process.env.WALLET_PRIVATE_KEY
       ? [`0x${process.env.WALLET_PRIVATE_KEY}`]
       : [],
   },
   zkevmTestnet: {
     url: `${process.env.RPC_ZKEVM_URL || ''}`,
     accounts: process.env.WALLET_PRIVATE_KEY
       ? [`0x${process.env.WALLET_PRIVATE_KEY}`]
       : [],
   }
 },
};

// Exportações
// ========================================================
export default config;
Enter fullscreen mode Exit fullscreen mode

Adição de variáveis de ambiente para o Hardhat

Quando terminarmos a configuração do Hardhat, criaremos um arquivo de variável de ambiente para armazenar nossos valores-chave.

touch .env;
Enter fullscreen mode Exit fullscreen mode

OBSERVAÇÃO: lembre-se de manter sua chave privada protegida contra olhares indiscretos.

Arquivo: ./env

RPC_MUMBAI_URL=https://rpc.ankr.com/polygon_mumbai
RPC_ZKEVM_URL=https://rpc.public.zkevm-test.net
WALLET_PRIVATE_KEY=<YOUR-WALLET-PRIVATE-KEY>
Enter fullscreen mode Exit fullscreen mode

Por fim, vamos modificar nosso script de implantação para apontar para o contrato correto.

Arquivo: ./scripts/deploy.ts

// Importações
// ========================================================
import { ethers } from "hardhat";

// Script Principal de Implantação
// ========================================================
async function main() {
 // Verifique se na fábrica de contratos, ele corresponde ao nome do contrato no arquivo solidity
 // Exemplo: contrato zkEVMNFT
 const zkERC721Contract = await ethers.getContractFactory("ZkEVMNFT");
 const contract = await zkERC721Contract.deploy();

 await contract.deployed();

 console.log(`zkEVMNFT deployed to ${contract.address}`);
};

// Inicialização
// ========================================================
// Recomendamos esse padrão para poder usar async/await em todos os lugares
// e lidar corretamente com erros.
main().catch((error) => {
 console.error(error);
 process.exitCode = 1;
});
Enter fullscreen mode Exit fullscreen mode

Implantação do contrato de NFT

Quando tudo estiver pronto, podemos implantar nosso contrato de NFT na rede de teste zkEVM.

# DE: ./zkevm-erc721-hardhat

npx hardhat run scripts/deploy.ts --network zkevmTestnet;

# Saída esperada:
# zkEVMNFT deployed to 0x7F77cF06C84A7bae6D710eBfc78a48214E4937a7
Enter fullscreen mode Exit fullscreen mode

Se acessarmos o contrato no explorador, veremos o seguinte resultado:

Image description

https://explorer.public.zkevm-test.net/address/0x7F77cF06C84A7bae6D710eBfc78a48214E4937a7

Verificando nosso Contrato de NFT no explorador de blocos zkEVM

Podemos interagir diretamente com o contrato por meio do Hardhat para a cunhagem e leitura, mas usaremos o explorador de blockchain para nos conectar e cunhar um novo NFT.

Antes de iniciarmos o processo de verificação, faremos a verificação via JSON de entrada padrão e precisaremos de um arquivo para fazer o upload.

Se olharmos para a pasta build-info, podemos encontrar um arquivo JSON onde precisamos obter apenas a seção de entrada. Copie toda essa seção e crie um novo arquivo chamado verify.json e cole os dados JSON nele.

Lembre-se de que você precisará compilar o contrato antecipadamente para gerar esses arquivos com npx hardhat compile.

Arquivo: ./artifacts/build-info/your-build-file.json

Image description

                                           Compilar arquivo JSON
Enter fullscreen mode Exit fullscreen mode

Image description

                   Nosso novo arquivo JSON de entrada padrão como verify.json
Enter fullscreen mode Exit fullscreen mode

Em seguida, acesse o contrato no explorador de blocos e inicie o processo de verificação.

Image description

        Verificar e publicar contrato no Explorador de Blocos da rede de teste zkEVM.
Enter fullscreen mode Exit fullscreen mode

Image description

       Verificação do Explorador de Blocos da através de JSON de Entrada Padrão.
Enter fullscreen mode Exit fullscreen mode

Image description

     Configurar verificação do Explorador de Blocos da rede de teste zkEVM usando o arquivo verify.json.
Enter fullscreen mode Exit fullscreen mode

Após a verificação, podemos ver o código completo do nosso contrato no explorador de blocos da rede de teste zkEVM

Image description

https://explorer.public.zkevm-test.net/address/0x7F77cF06C84A7bae6D710eBfc78a48214E4937a7/contracts#address-tabs

Cunhando um NFT na rede de teste zkEVM

Agora que nosso contrato está verificado, podemos interagir com ele através do explorador de blocos na rede de teste zkEVM e nossa carteira.

Para os propósitos deste tutorial, vamos cunhar um token NFT com o ID 4 em homenagem ao número de dias até o lançamento da versão beta da rede principal da zkEVM - 27 de março de 2023.

Image description

https://explorer.public.zkevm-test.net/address/0x7F77cF06C84A7bae6D710eBfc78a48214E4937a7/write-contract#address-tabs

Image description

                                      Cunhando o NFT na rede de teste zkEVM 
Enter fullscreen mode Exit fullscreen mode

Image description

           Confirmação da cunhagem bem-sucedida de um NFT na rede de teste zkEVM 
Enter fullscreen mode Exit fullscreen mode

Visualizando nosso NFT da zkEVM

Cunhamos nosso NFT na rede de teste zkEVM e agora queremos visualizar esse NFT SVG on-chain.

Image description

               Leitura de NFT no Explorador de Blocos na rede de teste zkEVM
Enter fullscreen mode Exit fullscreen mode

Copie a parte dos dados da consulta tokenURI e, no Chrome, cole-a na barra de endereços.

Image description

                  Dados JSON do tokenURI do NFT na rede de teste zkEVM
Enter fullscreen mode Exit fullscreen mode

Copie o valor da image do JSON e, no Chrome, cole-o na barra de endereços.

Image description

                                                 NFT SVG na rede de teste zkEVM 
Enter fullscreen mode Exit fullscreen mode

🎉 Pronto! Implantamos o contrato com sucesso, verificamos o contrato e pudemos ver nosso NFT criado.

Repositório completo do código NFT da zkEVM
Confira o repositório completo para este tutorial aqui.

O que vem a seguir?

Fique atento aos próximos tutoriais sobre a zkEVM.

Se você ainda não leu How To Deploy A Contract To Polygon zkEVM Testnet (Como implantar um contrato na rede de testes da Polygon zkEVM), leia-o e, se quiser se aprofundar mais na zkEVM, dê uma olhada na Polygon University.

Se você gostou deste artigo, por favor, de um coraçãozinho a ele e siga-me também no Twitter (onde sou bastante ativo) @codingwithmanny e no Instagram em @codingwithmanny.

Artigo escrito por Manny e traduzido por Rafael Ojeda

Você pode ler o artigo original aqui.

Top comments (0)