WEB3DEV Español

Cover image for Desplegar un NFT animado en zkEVM con Hardhat.
Banana Labs
Banana Labs

Posted on

Desplegar un NFT animado en zkEVM con Hardhat.

Cómo desplegar un contrato de NFT ERC721 en la red de prueba zkEVM con Hardhat.

portada

¿Qué es zkEVM?

En resumen, Polygon zkEVM es una solución de escalado de capa 2 (L2) que apunta a la equivalencia con EVM y te permite desplegar contratos de manera más barata, rápida, segura y sin pasos adicionales utilizando tu código Solidity existente.

¿Quieres entender más a fondo? Consulta mi otro artículo sobre cómo desplegar un contrato de token ERC20 en la red de pruebas zkEVM.

Red, tokens de la red de pruebas Goerli y puente
Para configurar y hacer el puente rápidamente, recomiendo usar el sitio de Polygon zkEVM Bridge para agregar la red a nuestra cartera y hacer la transferencia de cualquier token Goerli a la red de pruebas zkEVM.

testnet

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

Requisitos

Antes de empezar, asegúrate de tener lo siguiente instalado en tu computadora y de haber configurado tu billetera y tokens de la red de pruebas Goerli en puente para la red de pruebas zkEVM. Si quieres ver cómo hacer esto, consulta mi otro artículo Cómo desplegar un contrato ERC20 en la red de pruebas zkEVM.

NVM o Node v18.15.0

Desplegando un Contrato con Hardhat

Vamos a construir un NFT ERC721 y desplegarlo en zkEVM con Hardhat.

Asegurándonos de que empezamos desde cero, vamos a utilizar la plantilla de Hardhat para generar un proyecto básico en TypeScript para nosotros.

# 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

A continuación, vamos a instalar las dependencias.

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

Creando nuestro NFT

Para nuestro NFT, vamos a hacer que destaque un poco introduciendo un SVG animado.

Primero, elimina el contrato modelo que se generó y crea uno nuevo en su lugar.

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

En el archivo, copia y pega el siguiente código Solidity para NFTs.

Archivo: ./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 {
   // Extendiendo la funcionalidad
   using Strings for uint256;

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

   /**
    * Función principal de acuñación
    */
   function safeMint(address to, uint256 tokenId) public {
       _safeMint(to, tokenId);
   }

   // Las siguientes funciones son reemplazos requeridos por Solidity.
   /**
    * @dev See {ERC721}
    */
   function _burn(uint256 tokenId) internal override(ERC721) {
       super._burn(tokenId);
   }

   /**
    *Función pública o quema    */
   function burn (uint256 tokenId) public {
       _burn(tokenId);
   }

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

       // Imagen 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 devuelto
       return string(
           abi.encodePacked(
               "data:application/json;base64,",
               Base64.encode(dataURI)
           )
       );
   }
}
Enter fullscreen mode Exit fullscreen mode

Configurando Hardhat

Estamos casi allí. A continuación, vamos a configurar el archivo de configuración de Hardhat para permitir que las variables de entorno se carguen, configurar el soporte de red y ajustar para la optimización.

Archivo: ./hardhat.config.ts

// Importaciones
// ========================================================
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import dotenv from "dotenv";

// Ajustes
// ========================================================
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}`]
       : [],
   }
 },
};

// Exportaciones
// ========================================================
export default config;
Enter fullscreen mode Exit fullscreen mode

Adición de variables de ambiente para Hardhat

Cuando terminemos la configuración de Hardhat, crearemos un archivo de variable de ambiente para almacenar nuestros valores clave.

touch .env;
Enter fullscreen mode Exit fullscreen mode

NOTA: recuerda mantener tu clave privada protegida de miradas indiscretas.
Archivo: ./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

Finalmente, vamos a modificar nuestro script de despliegue para apuntar al contrato correcto.

Archivo: ./scripts/deploy.ts

// Importaciones
// ========================================================
import { ethers } from "hardhat";

// Script de implementación principal
// ========================================================
async function main() {
 // Verifique que en la fábrica de contratos, coincida con el nombre del contrato en el archivo 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}`);
};

// Inicialización
// ========================================================
//Recomendamos este patrón para poder usar async/await en todas partes.
// y manejar correctamente los errores.
main().catch((error) => {
 console.error(error);
 process.exitCode = 1;
});
Enter fullscreen mode Exit fullscreen mode

Despliegue del contrato de NFT

Cuando todo esté listo, podemos desplegar nuestro contrato de NFT en la red de pruebas zkEVM.

# DE: ./zkevm-erc721-hardhat

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

# Salida esperada:
# zkEVMNFT deployed to 0x7F77cF06C84A7bae6D710eBfc78a48214E4937a7
Enter fullscreen mode Exit fullscreen mode

Si accedemos al contrato en el explorador, veremos el siguiente resultado:

contrato

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

Verificando nuestro Contrato de NFT en el explorador de bloques zkEVM

Podemos interactuar directamente con el contrato a través de Hardhat para la acuñación y lectura, pero usaremos el explorador de blockchain para conectarnos y acuñar un nuevo NFT.

Antes de iniciar el proceso de verificación, haremos la verificación a través de JSON de entrada estándar y necesitaremos un archivo para subir.

Si miramos en la carpeta build-info, podemos encontrar un archivo JSON donde necesitamos obtener solo la sección de entrada. Copia toda esa sección y crea un nuevo archivo llamado verify.json y pega los datos JSON en él.

Recuerda que necesitarás compilar el contrato con anticipación para generar estos archivos con npx hardhat compile.

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

contrato
Compilar archivo JSON

contrato
Nuestro nuevo archivo JSON de entrada predeterminado como verify.json

A continuación, accede al contrato en el explorador de bloques e inicia el proceso de verificación.

verificación
Verificar y publicar contrato en el Explorador de Bloques de la red de pruebas zkEVM.

verificación
Verificación del Explorador de Bloques a través de JSON de Entrada Estándar.

verificación
Configurar verificación del Explorador de Bloques de la red de pruebas zkEVM usando el archivo verify.json.

Después de la verificación, podemos ver el código completo de nuestro contrato en el explorador de bloques de la red de pruebas zkEVM.

explorador

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

Acuñando un NFT en la red de pruebas zkEVM

Ahora que nuestro contrato está verificado, podemos interactuar con él a través del explorador de bloques en la red de pruebas zkEVM y nuestra billetera.

Para los propósitos de este tutorial, vamos a acuñar un token NFT con el ID 4 en honor al número de días hasta el lanzamiento de la versión beta de la red principal de zkEVM - 27 de marzo de 2023.

NFT

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

NFT
Acuñando el NFT en la red de pruebas zkEVM

NFT
Confirmación de la acuñación exitosa de un NFT en la red de pruebas zkEVM.

Visualizando nuestro NFT de zkEVM

Hemos acuñado nuestro NFT en la red de pruebas zkEVM y ahora queremos visualizar ese NFT SVG en cadena (on-chain).

zkEVM
Leyendo NFT en el Explorador de Bloques en la red de pruebas zkEVM.

Copia la parte de los datos de la consulta tokenURI y, en Chrome, pégala en la barra de direcciones.

chrome

         Datos JSON del tokenURI del NFT en la red de pruebas zkEVM
Enter fullscreen mode Exit fullscreen mode

Copia el valor de la imagen del JSON y, en Chrome, pégalo en la barra de direcciones.

chrome
NFT SVG en la red de prueba zkEVM

🎉 ¡Listo! Hemos desplegado el contrato con éxito, verificado el contrato y hemos podido ver nuestro NFT creado.

Repositorio completo del código NFT de zkEVM
Consulta el repositorio completo para este tutorial aquí.

¿Qué sigue?
Mantente atento a los próximos tutoriales sobre zkEVM.

Si aún no has leído Cómo desplegar un contrato en la red de pruebas de Polygon zkEVM, léelo y, si quieres profundizar más en zkEVM, echa un vistazo a la Universidad Polygon.

Si te gustó este artículo, por favor, dale un corazón y sígueme también en Twitter (donde soy bastante activo) @codingwithmanny y en Instagram en @codingwithmanny.



Este artículo es una traducción realizada por @bananlabs. Puedes encontrar el artículo original aquí

Discussion (0)