Agents
DESCRIPCIÓN GENERAL
Este documento proporciona información completa para desplegar smart contracts en Polkadot Hub TestNet (Paseo) usando Claude Code. Incluye configuraciones verificadas, problemas comunes, soluciones y estrategias de optimización.
CRÍTICO: Siempre inicializa nuevos proyectos con kitdot@latest init
para una configuración adecuada de red y gestión de dependencias.
INFORMACIÓN DE RED
Detalles de Paseo TestNet
Nombre de Red: Polkadot Hub TestNet
Chain ID: 420420422 (0x1911f0a6 en hex)
URL RPC: https://testnet-passet-hub-eth-rpc.polkadot.io
Explorador de Bloques: https://blockscout-passet-hub.parity-testnet.parity.io
Moneda: PAS
Faucet: https://faucet.polkadot.io/?parachain=1111
Estado: Vista Previa de PolkaVM (etapa de desarrollo temprano)
Características Clave
Compatibilidad EVM: Despliegue de smart contracts compatible con Ethereum
PolkaVM: Requiere configuración específica para compatibilidad
Límite de Bytecode: ~100KB tamaño máximo de contrato
Modelo de Gas: Mecánica de gas estándar de EVM
Advertencia de Versión de Node: Funciona con Node.js v21+ a pesar de las advertencias
DEPENDENCIAS REQUERIDAS
Dependencias Principales
npm install --save-dev @parity/hardhat-polkadot [email protected]
npm install --force @nomicfoundation/hardhat-toolbox
npm install dotenv
Requisitos de Package.json
{
"devDependencies": {
"@nomicfoundation/hardhat-toolbox": "^5.0.0",
"@parity/hardhat-polkadot": "^0.1.7",
"solc": "^0.8.28",
"hardhat": "^2.22.0"
},
"dependencies": {
"dotenv": "^17.0.1",
"ethers": "^6.13.5"
}
}
CRÍTICO: Usa la bandera --force
al instalar hardhat-toolbox para resolver conflictos de dependencias.
CONFIGURACIÓN DE HARDHAT
hardhat.config.js Completo y Funcional
require("@nomicfoundation/hardhat-toolbox");
require("@parity/hardhat-polkadot");
const { vars } = require("hardhat/config");
module.exports = {
solidity: "0.8.28",
resolc: {
version: "0.3.0",
compilerSource: "npm",
},
networks: {
hardhat: {
polkavm: true,
},
localNode: {
polkavm: true,
url: "http://127.0.0.1:8545",
},
passetHub: {
polkavm: true,
url: "https://testnet-passet-hub-eth-rpc.polkadot.io",
accounts: [vars.get("PRIVATE_KEY")],
},
},
gasReporter: {
enabled: process.env.REPORT_GAS !== undefined,
currency: "USD",
},
paths: {
sources: "./contracts",
tests: "./test",
cache: "./cache",
artifacts: "./artifacts",
},
};
Requisitos de Configuración
Debe usar formato string para versión de Solidity:
solidity: "0.8.28"
Debe incluir configuración resolc: Requerido para compatibilidad con PolkaVM
Debe establecer polkavm: true: En todas las configuraciones de red
Debe usar hardhat vars: Para gestión de claves privadas
Nombre de red: Usar
passetHub
(no paseo u otros nombres)
PROCESO DE CONFIGURACIÓN
Paso 1: Inicializar Proyecto con kitdot@latest (Recomendado)
npm install -g kitdot@latest
kitdot init tu-proyecto
cd tu-proyecto
Configuración Manual Alternativa:
mkdir tu-proyecto
cd tu-proyecto
npm init -y
¿Por qué kitdot@latest? Configura automáticamente las configuraciones de red adecuadas, dependencias y estructura del proyecto. Elimina errores comunes de configuración.
Paso 2: Instalar Dependencias
Si usas kitdot@latest: Las dependencias se instalan automáticamente.
Instalación manual:
npm install --save-dev @parity/hardhat-polkadot [email protected]
npm install --force @nomicfoundation/hardhat-toolbox
npm install dotenv
Paso 3: Inicializar Plugin de Polkadot
Si usas kitdot@latest: Ya está configurado.
Configuración manual:
npx hardhat-polkadot init
Paso 4: Configurar Clave Privada
npx hardhat vars set PRIVATE_KEY
# Ingresa tu clave privada cuando se solicite (sin prefijo 0x)
Paso 5: Obtener Tokens de Prueba
Visita https://faucet.polkadot.io/?parachain=1111
Ingresa la dirección de tu billetera
Solicita tokens PAS
Verifica el saldo en tu billetera o explorador de bloques
Paso 6: Crear Configuración de Hardhat
Si usas kitdot@latest: El archivo de configuración ya está creado con las configuraciones apropiadas.
Configuración manual: Copia la configuración exacta de arriba en hardhat.config.js
DESARROLLO DE CONTRATOS
Requisitos de Versión de Solidity
Versión Requerida: ^0.8.28
Objetivo EVM: paris (por defecto)
Optimizador: Habilitado por defecto
Ejemplo de Contrato Simple
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
contract SimpleStorage {
uint256 public value;
constructor() {
value = 42;
}
function setValue(uint256 _value) external {
value = _value;
}
function getValue() external view returns (uint256) {
return value;
}
}
Limitaciones de Tamaño de Contrato
Bytecode Máximo: ~100KB
Impacto de OpenZeppelin: Las importaciones estándar a menudo exceden el límite
Optimización Requerida: Eliminar dependencias innecesarias
PROCESO DE DESPLIEGUE
Usando Hardhat Ignition (Recomendado)
Paso 1: Crear Módulo de Ignition
// ignition/modules/TuModulo.js
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules");
module.exports = buildModule("TuModulo", (m) => {
const contract = m.contract("TuContrato", [
// argumentos del constructor
]);
return { contract };
});
Paso 2: Compilar Contratos
npx hardhat compile
# Debería mostrar: "Successfully compiled X Solidity files"
Paso 3: Desplegar a Paseo
npx hardhat ignition deploy ./ignition/modules/TuModulo.js --network passetHub
# Confirma con 'y' cuando se solicite
Estados de Despliegue
Estado Limpio:
rm -rf ignition/deployments/
para empezar de nuevoReanudar: Ignition reanuda automáticamente despliegues interrumpidos
Rastrear Transacciones: Usa el explorador de bloques para rastrear transacciones fallidas
ERRORES COMUNES Y SOLUCIONES
1. Error "CodeRejected"
Error: Failed to instantiate contract: Module(ModuleError { index: 60, error: [27, 0, 0, 0], message: Some("CodeRejected") })
Causas:
Falta configuración PolkaVM
Configuraciones de red incorrectas
Falta configuración resolc
Soluciones:
Asegurar
polkavm: true
en configuración de redAgregar bloque de configuración resolc
Usar formato exacto de hardhat.config.js de arriba
2. Error "initcode is too big"
Error: initcode is too big: 125282
(o número similar)
Causa: El bytecode del contrato excede el límite de ~100KB
Soluciones:
Eliminar dependencias de OpenZeppelin
Usar implementaciones mínimas de contratos
Dividir contratos grandes en componentes más pequeños
Implementar versiones ligeras personalizadas
3. Errores de Configuración
Error: Cannot read properties of undefined (reading 'settings')
Solución: Usar formato string para versión de Solidity: solidity: "0.8.28"
4. Problemas de Dependencias
Error: Cannot find module 'run-container'
o similar
Soluciones:
Instalar dependencias con bandera
--force
Limpiar node_modules y reinstalar
Verificar compatibilidad de versión @parity/hardhat-polkadot
5. Problemas de Clave Privada
Error: No signers found
o fallas de autenticación
Soluciones:
Establecer clave privada vía
npx hardhat vars set PRIVATE_KEY
Asegurar que la cuenta tiene tokens PAS
Verificar formato de clave privada (sin prefijo 0x en vars)
OPTIMIZACIÓN DE CONTRATOS
Eliminando Dependencias de OpenZeppelin
En lugar de OpenZeppelin Ownable:
contract SimpleOwnable {
address public owner;
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
constructor() {
owner = msg.sender;
}
function transferOwnership(address newOwner) external onlyOwner {
owner = newOwner;
}
}
En lugar de OpenZeppelin ReentrancyGuard:
contract SimpleReentrancyGuard {
bool private locked;
modifier nonReentrant() {
require(!locked, "Reentrant call");
locked = true;
_;
locked = false;
}
}
Implementación Mínima ERC721:
contract MinimalERC721 {
mapping(uint256 => address) private _owners;
mapping(address => uint256) private _balances;
mapping(uint256 => address) private _tokenApprovals;
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
function ownerOf(uint256 tokenId) public view returns (address) {
return _owners[tokenId];
}
function balanceOf(address owner) public view returns (uint256) {
return _balances[owner];
}
function approve(address to, uint256 tokenId) public {
address owner = ownerOf(tokenId);
require(msg.sender == owner, "Not authorized");
_tokenApprovals[tokenId] = to;
emit Approval(owner, to, tokenId);
}
function transferFrom(address from, address to, uint256 tokenId) public {
require(_isApprovedOrOwner(msg.sender, tokenId), "Not authorized");
_transfer(from, to, tokenId);
}
function _mint(address to, uint256 tokenId) internal {
require(to != address(0), "Invalid address");
require(_owners[tokenId] == address(0), "Already minted");
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
}
function _transfer(address from, address to, uint256 tokenId) internal {
require(ownerOf(tokenId) == from, "Not owner");
require(to != address(0), "Invalid address");
delete _tokenApprovals[tokenId];
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
}
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
address owner = ownerOf(tokenId);
return (spender == owner || _tokenApprovals[tokenId] == spender);
}
}
INTEGRACIÓN FRONTEND
Problemas de Transacciones Frontend (Problemas de Estimación de Gas/Legacy)
CRÍTICO PARA AGENTES: Las aplicaciones frontend frecuentemente encuentran problemas de estimación de gas al enviar transacciones a redes de Polkadot. Siempre implementa estas estrategias:
Método 1: Estimación de Gas Legacy con Buffer
// Usa estimación de gas legacy con buffer de seguridad
const gasLimit = await provider.estimateGas({
to: contractAddress,
data: contractInterface.encodeFunctionData("functionName", [args]),
});
// Agrega buffer de 10-20% para seguridad
const adjustedGasLimit = gasLimit.mul(120).div(100);
// Envía transacción con gas explícito y tipo legacy
const tx = await contract.functionName(args, {
gasLimit: adjustedGasLimit,
type: 0, // Usa tipo de transacción legacy
});
Método 2: Límites de Gas Fijos
// Usa límites de gas fijos para operaciones predecibles
const tx = await contract.functionName(args, {
gasLimit: 100000, // Ajusta basado en complejidad de función
type: 0, // Tipo de transacción legacy
gasPrice: ethers.utils.parseUnits("20", "gwei"), // Opcional: establecer precio de gas
});
Configuración de Red para MetaMask
const paseoConfig = {
chainId: "0x1911f0a6", // 420420422 en hex
chainName: "Polkadot Hub TestNet",
nativeCurrency: {
name: "PAS",
symbol: "PAS",
decimals: 18,
},
rpcUrls: ["https://testnet-passet-hub-eth-rpc.polkadot.io"],
blockExplorerUrls: ["https://blockscout-passet-hub.parity-testnet.parity.io"],
};
// Agregar red a MetaMask
await window.ethereum.request({
method: "wallet_addEthereumChain",
params: [paseoConfig],
});
Interacción con Contratos usando Ethers.js
import { ethers } from "ethers";
// Conectar a Paseo
const provider = new ethers.JsonRpcProvider(
"https://testnet-passet-hub-eth-rpc.polkadot.io"
);
// Instancia del contrato
const contract = new ethers.Contract(contractAddress, abi, signer);
// Llamar funciones
const result = await contract.someFunction();
TESTING Y VERIFICACIÓN
Verificación de Compilación
npx hardhat compile
# Salida esperada: "Successfully compiled X Solidity files"
# NO debería mostrar advertencias de tamaño de contrato para contratos <100KB
Verificación de Despliegue
Salida de Despliegue Exitoso:
[ TuModulo ] successfully deployed 🚀
Deployed Addresses
TuModulo#TuContrato - 0x1234567890abcdef...
Verificación en Explorador de Bloques:
Visita https://blockscout-passet-hub.parity-testnet.parity.io
Busca la dirección del contrato
Verifica la transacción de creación del contrato
Prueba de Interacción con Contrato:
npx hardhat console --network passetHub
> const Contract = await ethers.getContractFactory("TuContrato");
> const contract = Contract.attach("0x...");
> await contract.someFunction();
ESTRATEGIAS DE DEBUGGING
Verificar Conectividad de Red
curl -X POST -H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":1}' \
https://testnet-passet-hub-eth-rpc.polkadot.io
Verificar Saldo de Cuenta
npx hardhat console --network passetHub
> await ethers.provider.getBalance("TU_DIRECCION")
Limpieza de Build y Despliegue
npx hardhat clean
rm -rf ignition/deployments/
npx hardhat compile
npx hardhat ignition deploy ./ignition/modules/TuModulo.js --network passetHub
Rastreo de Transacciones
Si el despliegue falla:
Revisa el explorador de bloques para transacciones de la cuenta
Busca transacciones fallidas con errores de gas
Usa
npx hardhat ignition track-tx <txHash> <deploymentId> --network passetHub
MEJORES PRÁCTICAS
Flujo de Trabajo de Desarrollo
Empezar Simple: Despliega contratos básicos primero para verificar configuración
Optimizar Temprano: Verifica tamaños de contratos durante el desarrollo
Probar Localmente: Usa la red local de hardhat para pruebas iniciales
Despliegue Incremental: Despliega componentes por separado si son demasiado grandes
Documentar Direcciones: Mantén registro de todas las direcciones de contratos desplegados
Diseño de Contratos para Paseo
Minimizar Dependencias: Evita bibliotecas pesadas
Implementaciones Personalizadas: Escribe versiones mínimas de contratos estándar
Diseño Modular: Divide funcionalidad entre múltiples contratos
Optimización de Gas: Usa estructuras de datos y algoritmos eficientes
Patrones Proxy: Considera contratos actualizables para lógica compleja
Consideraciones de Seguridad
Gestión de Claves Privadas: Siempre usar hardhat vars, nunca hacer commit de claves
Solo Red de Prueba: Paseo es para pruebas, no para valor de producción
Verificación de Código: Verifica contratos en el explorador de bloques cuando sea posible
Controles de Acceso: Implementa sistemas apropiados de propiedad y permisos
COMANDOS DE REFERENCIA
Comandos Esenciales
# Configuración de proyecto
npm install --save-dev @parity/hardhat-polkadot [email protected]
npm install --force @nomicfoundation/hardhat-toolbox
npx hardhat-polkadot init
# Configuración
npx hardhat vars set PRIVATE_KEY
npx hardhat vars list
# Desarrollo
npx hardhat compile
npx hardhat clean
npx hardhat test
# Despliegue
npx hardhat ignition deploy ./ignition/modules/Modulo.js --network passetHub
rm -rf ignition/deployments/ # Limpiar estado de despliegue
# Debugging
npx hardhat console --network passetHub
npx hardhat node # Desarrollo local
Variables de Entorno
# Configuración .env opcional
REPORT_GAS=true
ETHERSCAN_API_KEY=tu_clave_aqui
DESPLIEGUE EN POLKADOT CLOUD (APILLON)
Configuración de Cuenta Apillon y UUID del Sitio Web
CRÍTICO PARA AGENTES: Al desplegar aplicaciones frontend en Polkadot Cloud, sigue estos pasos:
Paso 1: Crear Cuenta Apillon
INSTRUIR AL USUARIO PARA:
Visitar Consola Apillon: https://app.apillon.io
Registrar Cuenta: Usar email y crear contraseña segura
Verificar Email: Completar proceso de verificación de email
Conectar Wallet: Vincular tu wallet Polkadot/Substrate para pagos
Generar Credenciales API:
Ir a Settings → API Keys
Hacer clic en Create New API Key
Nombrarlo (ej. "Proyecto Hackathon")
Copiar API Key y API Secret inmediatamente
Almacenar de forma segura - API Secret solo se muestra una vez
Paso 2: Crear Proyecto de Sitio Web
INSTRUIR AL USUARIO PARA:
Navegar a Sección Hosting: En consola Apillon
Crear Nuevo Sitio Web: Hacer clic en botón "New Website"
Configurar Proyecto:
Project Name: [Nombre de Tu Proyecto] Environment: Production Domain: [Dominio personalizado opcional]
Copiar UUID del Sitio Web: Después de la creación, copiar el UUID generado (formato:
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
)Proporcionar UUID al Agente: Compartir el UUID del Sitio Web para que el agente pueda configurar el despliegue
Paso 3: Obtener UUID del Sitio Web para Despliegue
# Ejemplo formato UUID
WEBSITE_UUID="12345678-1234-5678-9abc-123456789def"
Configuración MCP para Hosting en Polkadot Cloud
Configuración del Protocolo de Contexto de Modelo (MCP):
Paso 1: Configuración del Servidor MCP
CRÍTICO PARA AGENTES: Configura tu cliente MCP para usar el servidor MCP de Apillon.
Para Claude Desktop:
Agrega esto a tu archivo de configuración MCP:
{
"mcpServers": {
"apillon-mcp-server": {
"command": "npx",
"args": ["-y", "@apillon/mcp-server"],
"env": {
"APILLON_API_KEY": "<APILLON_API_KEY>",
"APILLON_API_SECRET": "<APILLON_API_SECRET>"
}
},
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/tu-usuario/Desktop"
]
}
}
}
Pasos de Configuración Claude Desktop:
Localizar archivo config MCP: Usualmente en
~/Library/Application Support/Claude/claude_desktop_config.json
(macOS)Agregar servidor Apillon: Insertar la configuración de arriba
Reemplazar placeholders: Actualizar
<APILLON_API_KEY>
y<APILLON_API_SECRET>
con valores realesActualizar ruta filesystem: Cambiar
/Users/tu-usuario/Desktop
a tu directorio de proyectoReiniciar Claude Desktop: Requerido para que cambios MCP surtan efecto
Para Cursor IDE:
Configuración MCP en Cursor:
Instalar extensión MCP: En Cursor, ir a Extensions y buscar "Model Context Protocol"
Abrir configuraciones Cursor:
Cmd/Ctrl + ,
→ Buscar "MCP"Agregar configuración servidor:
{
"mcp.servers": {
"apillon-mcp-server": {
"command": "npx",
"args": ["-y", "@apillon/mcp-server"],
"env": {
"APILLON_API_KEY": "<APILLON_API_KEY>",
"APILLON_API_SECRET": "<APILLON_API_SECRET>"
}
}
}
}
Pasos de Configuración Cursor:
Abrir settings.json:
Cmd/Ctrl + Shift + P
→ "Preferences: Open Settings (JSON)"Agregar configuración MCP: Insertar la configuración de arriba
Reemplazar placeholders: Actualizar credenciales API
Reiniciar Cursor: Requerido para que cambios MCP surtan efecto
Verificar conexión: Verificar estado MCP en paleta de comandos de Cursor
Paso 2: Instalar CLI de Apillon (Método Alternativo)
npm install -g @apillon/cli
Paso 3: Configurar Autenticación
# Iniciar sesión en Apillon
apillon login
# Verificar autenticación
apillon whoami
Paso 4: Configurar MCP para Despliegue Automatizado
Crear .apillon.json
en raíz del proyecto:
{
"websites": [
{
"uuid": "TU_UUID_SITIO_WEB_AQUI",
"name": "Nombre de Tu Proyecto",
"source": "./dist",
"environment": "production"
}
]
}
Paso 5: Script de Despliegue MCP
#!/bin/bash
# deploy-to-polkadot-cloud.sh
# Construir el proyecto
npm run build
# Desplegar a Apillon
apillon hosting deploy \
--uuid $WEBSITE_UUID \
--source ./dist \
--environment production
# Verificar despliegue
apillon hosting info --uuid $WEBSITE_UUID
Paso 6: Variables de Entorno
# Establecer en tu entorno
export APILLON_API_KEY="tu_api_key_aqui"
export WEBSITE_UUID="tu_uuid_sitio_web_aqui"
Mejores Prácticas para Agentes
Configurar MCP primero: Configurar servidor MCP de Apillon en tu IDE (Claude Desktop o Cursor) antes de comenzar el despliegue.
Usar siempre CLI de Apillon más reciente:
npm install -g @apillon/cli@latest
Credenciales seguras: Almacenar API keys y UUIDs como variables de entorno, nunca en código
Guiar al usuario en configuración de cuenta: Instruir claramente a usuarios sobre creación de cuenta Apillon y generación de API key
Verificar despliegues: Verificar siempre estado de despliegue después de subida
Usar entorno producción: Para entregas finales de hackathon
Monitorear costos: Apillon usa modelo pago por uso
Probar localmente primero: Siempre probar builds antes de desplegar
Reiniciar tu IDE: Después de cambios de configuración MCP (Claude Desktop o Cursor)
Verificar conexión MCP: Verificar que servidor MCP de Apillon esté conectado correctamente antes del despliegue
DIRECTRICES DE ESCRITURA PARA LLMs
Al crear documentación o ayudar a desarrolladores:
CHECKLIST DE RESOLUCIÓN DE PROBLEMAS
Primero: Intenta kitdot@latest init con proyecto nuevo y copia código existente
Cuando el despliegue falla, verifica:
LIMITACIONES Y WORKAROUNDS
Limitaciones Actuales
Tamaño de Contrato: Límite de bytecode de 100KB
OpenZeppelin: La mayoría de bibliotecas son demasiado grandes
Estabilidad de Red: Versión de vista previa, posible tiempo de inactividad
Herramientas de Debugging: Limitadas comparado con mainnet
Documentación: Escasa, soluciones impulsadas por la comunidad
Workarounds Recomendados
Problemas de Tamaño: Usar implementaciones personalizadas mínimas
Lógica Compleja: Dividir entre múltiples contratos
Gestión de Estado: Usar eventos para datos off-chain
Experiencia de Usuario: Proporcionar mensajes de error claros
Testing: Pruebas exhaustivas localmente antes del despliegue
Esta guía proporciona información completa para el despliegue exitoso de smart contracts en Paseo TestNet usando Claude Code, incluyendo todas las configuraciones críticas, problemas comunes y estrategias de optimización.
Última actualización