Saltar al contenido principal

Verificando Contratos Inteligentes Usando Hardhat y Snowtrace

Este tutorial asume que el contrato fue desplegado usando Hardhat y que todas las dependencias de Hardhat están instaladas correctamente.

Después de desplegar un contrato inteligente, se puede verificar en Snowtrace en tres pasos:

  1. Aplanar el Contrato Inteligente
  2. Limpiar el contrato aplanado
  3. Verificar usando la interfaz gráfica de Snowtrace

Aplanar un Contrato Inteligente usando Hardhat

Para aplanar el contrato, ejecuta el siguiente comando: npx hardhat flatten <ruta-al-contrato> >> <nombre-contrato-aplanado>.sol

Limpiar el Contrato Inteligente aplanado

Es posible que sea necesario hacer algunas limpiezas para que el código compile correctamente en el Verificador de Contratos Snowtrace.

  • Elimina todas las licencias SPDX excepto la superior.

    • Si el contrato utiliza múltiples licencias SPDX, utiliza ambas licencias agregando AND: SPDX-License-Identifier: MIT AND BSD-3-Clause

Verificar el Contrato Inteligente usando la interfaz de usuario de Snowtrace

Snowtrace está trabajando actualmente en una nueva interfaz de usuario (UI) para la verificación de contratos inteligentes. Mientras tanto, puedes considerar usar su API para una experiencia de verificación de contratos inteligentes sin problemas.

Verificar el Contrato Inteligente Programáticamente Usando APIs

Asegúrate de tener Postman u otra plataforma de API instalada en tu computadora (o accesible a través de servicios en línea), junto con el código fuente de tu contrato y los parámetros utilizados durante el despliegue.

Aquí está la URL de la llamada de API para usar en una solicitud POST:

https://api.snowtrace.io/api?module=contract&action=verifysourcecode

Ten en cuenta que esta URL está específicamente configurada para verificar contratos en la Avalanche C-Chain Mainnet. Si deseas verificar en la Fuji Testnet, usa:

https://api-testnet.snowtrace.io/api?module=contract&action=verifysourcecode

Aquí está el cuerpo de la llamada de API con los parámetros requeridos:

{
"contractaddress": "TU_DIRECCIÓN_DE_CONTRATO",
"sourceCode": "TU_CÓDIGO_FUENTE_APLANADO",
"codeformat": "solidity-single-file",
"contractname": "NOMBRE_DE_TU_CONTRATO",
"compilerversion": "TU_VERSIÓN_DE_COMPILADOR",
"optimizationUsed": "TU_VALOR_DE_OPTIMIZACIÓN", // 0 si no está optimizado, 1 si está optimizado
"runs": "TUS_EJECUCIONES_DE_OPTIMIZACIÓN", // elimina si no corresponde
"licenseType": "TU_TIPO_DE_LICENCIA", // 1 si no está especificado
"apikey": "API_KEY_PLACEHOLDER", // no necesitas una clave de API, usa un marcador de posición
"evmversion": "TU_VERSIÓN_EVM_EN_REMIX",
"constructorArguments": "TUS_ARGUMENTOS_DE_CONSTRUCTOR" // Elimina si no corresponde
}

Verificando con Hardhat-Verify

Esta parte del tutorial asume que el contrato fue desplegado usando Hardhat y que todas las dependencias de Hardhat están instaladas correctamente, incluyendo '@nomiclabs/hardhat-etherscan'.

Necesitarás crear un archivo .env.json con tu Frase de Semilla de Billetera. No necesitas una clave de API para verificar en Snowtrace.

Ejemplo de .env.json:

{
"MNEMONIC": "tu-frase-de-semilla-de-billetera",
}

A continuación se muestra un ejemplo de hardhat.config.ts utilizado para el despliegue y la verificación (ver LN 45: etherscan)

import { task } from "hardhat/config"
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"
import { BigNumber } from "ethers"
import "@typechain/hardhat"
import "@nomiclabs/hardhat-ethers"
import "@nomiclabs/hardhat-waffle"
import "hardhat-gas-reporter"
import "@nomiclabs/hardhat-etherscan"
import { MNEMONIC, APIKEY } from "./.env.json"

// Al usar la red hardhat, puedes elegir bifurcar Fuji o Avalanche Mainnet
// Esto te permitirá depurar contratos usando la red hardhat mientras mantienes el estado de la red actual
// Para habilitar la bifurcación, activa uno de estos booleanos y luego ejecuta tus tareas/scripts usando ``--network hardhat``
// Para más información, consulta la guía de hardhat
// https://hardhat.org/hardhat-network/
// https://hardhat.org/guides/mainnet-forking.html
const FORK_FUJI = false
const FORK_MAINNET = false
const forkingData = FORK_FUJI
? {
url: "https://api.avax-test.network/ext/bc/C/rpc",
}
: FORK_MAINNET
? {
url: "https://api.avax.network/ext/bc/C/rpc",
}
: undefined

task(
"accounts",
"Imprime la lista de cuentas",
async (args, hre): Promise<void> => {
const accounts: SignerWithAddress[] = await hre.ethers.getSigners()
accounts.forEach((account: SignerWithAddress): void => {
console.log(account.address)
})
}
)

task(
"balances",
"Imprime la lista de saldos de cuentas AVAX",
async (args, hre): Promise<void> => {
const accounts: SignerWithAddress[] = await hre.ethers.getSigners()
for (const account of accounts) {
const balance: BigNumber = await hre.ethers.provider.getBalance(
account.address
)
console.log(`${account.address} tiene un saldo de ${balance.toString()}`)
}
}
)
export default {
etherscan: {
// No necesitas una clave de API para Snowtrace
},



solidity: {
compilers: [
{
version: "0.8.0",
},
{
version: "0.8.10",
},
],
},
networks: {
hardhat: {
gasPrice: 225000000000,
chainId: 43114, // Solo especifica un chainId si no estamos haciendo un fork
// forking: {
// url: 'https://api.avax.network/ext/bc/C/rpc',
// },
},
fuji: {
url: "https://api.avax-test.network/ext/bc/C/rpc",
gasPrice: 225000000000,
chainId: 43113,
accounts: { mnemonic: MNEMONIC },
},
mainnet: {
url: "https://api.avax.network/ext/bc/C/rpc",
gasPrice: 225000000000,
chainId: 43114,
accounts: { mnemonic: MNEMONIC },
},
},
}

Una vez que el contrato esté desplegado, verifica con hardhat verify ejecutando lo siguiente:

npx hardhat verify <dirección del contrato> <argumentos> --network <red>

Ejemplo:

npx hardhat verify 0x3972c87769886C4f1Ff3a8b52bc57738E82192D5 MockNFT Mock ipfs://QmQ2RFEmZaMds8bRjZCTJxo4DusvcBdLTS6XuDbhp5BZjY 100 --network fuji

También puedes verificar contratos programáticamente a través de un script

Ejemplo:

import console from "console"
const hre = require("hardhat")

// Define el NFT
const name = "MockNFT"
const symbol = "Mock"
const _metadataUri = "ipfs://QmQ2RFEmZaMds8bRjZCTJxo4DusvcBdLTS6XuDbhp5BZjY"
const _maxTokens = "100"

async function main() {
await hre.run("verify:verify", {
address: "0x3972c87769886C4f1Ff3a8b52bc57738E82192D5",
constructorArguments: [name, symbol, _metadataUri, _maxTokens],
})
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error)
process.exit(1)
})

Primero crea tu script, luego ejecútalo a través de hardhat ejecutando lo siguiente:

npx hardhat run scripts/<nombre del script.ts> --network <red>

Ejemplo:

npx hardhat run scripts/5-verifyNFT.ts --network fuji

Verificar a través de la terminal no te permitirá pasar un arreglo como argumento, sin embargo, puedes hacer esto cuando verificas a través de un script incluyendo el arreglo en tus Constructor Arguments

Ejemplo: (ver LN13 _custodians, LN 30 _custodians)

import console from "console"
const hre = require("hardhat")

// Define el NFT
const name = "MockNFT"
const symbol = "Mock"
const _metadataUri =
"ipfs://QmQn2jepp3jZ3tVxoCisMMF8kSi8c5uPKYxd71xGWG38hV/Example"
const _royaltyRecipient = "0xcd3b766ccdd6ae721141f452c550ca635964ce71"
const _royaltyValue = "50000000000000000"
const _custodians = [
"0x8626f6940e2eb28930efb4cef49b2d1f2c9c1199",
"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"0xdd2fd4581271e230360230f9337d5c0430bf44c0",
]
const _saleLength = "172800"
const _claimAddress = "0xcd3b766ccdd6ae721141f452c550ca635964ce71"

async function main() {
await hre.run("verify:verify", {
address: "0x08bf160B8e56899723f2E6F9780535241F145470",
constructorArguments: [
name,
symbol,
_metadataUri,
_royaltyRecipient,
_royaltyValue,
_custodians,
_saleLength,
_claimAddress,
],
})
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error)
process.exit(1)
})

Was this page helpful?