Agents
VISÃO GERAL
Este documento fornece informações abrangentes para implantar smart contracts na Polkadot Hub TestNet (Paseo) usando Claude Code. Inclui configurações verificadas, problemas comuns, soluções e estratégias de otimização.
CRÍTICO: Sempre inicie novos projetos com kitdot@latest init
para configuração adequada de rede e gerenciamento de dependências.
INFORMAÇÕES DA REDE
Detalhes da Paseo TestNet
Nome da Rede: Polkadot Hub TestNet
Chain ID: 420420422 (0x1911f0a6 em hex)
RPC URL: https://testnet-passet-hub-eth-rpc.polkadot.io
Block Explorer: https://blockscout-passet-hub.parity-testnet.parity.io
Moeda: PAS
Faucet: https://faucet.polkadot.io/?parachain=1111
Status: PolkaVM Preview Release (estágio inicial de desenvolvimento)
Características Principais
Compatibilidade EVM: Implantação de smart contracts compatível com Ethereum
PolkaVM: Requer configuração específica para compatibilidade
Limite de Bytecode: ~100KB tamanho máximo do contrato
Modelo de Gas: Mecânica padrão de gas EVM
Aviso de Versão Node: Funciona com Node.js v21+ apesar dos avisos
DEPENDÊNCIAS OBRIGATÓRIAS
Dependências Principais
npm install --save-dev @parity/hardhat-polkadot [email protected]
npm install --force @nomicfoundation/hardhat-toolbox
npm install dotenv
Requisitos do 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: Use a flag --force
ao instalar hardhat-toolbox para resolver conflitos de dependência.
CONFIGURAÇÃO DO HARDHAT
hardhat.config.js Completo e 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 Configuração
Deve usar formato string para versão do Solidity:
solidity: "0.8.28"
Deve incluir configuração resolc: Necessário para compatibilidade PolkaVM
Deve definir polkavm: true: Em todas as configurações de rede
Deve usar hardhat vars: Para gerenciamento de chave privada
Nome da rede: Use
passetHub
(não paseo ou outros nomes)
PROCESSO DE CONFIGURAÇÃO
Passo 1: Inicializar Projeto com kitdot@latest (Recomendado)
npm install -g kitdot@latest
kitdot init seu-projeto
cd seu-projeto
Configuração Manual Alternativa:
mkdir seu-projeto
cd seu-projeto
npm init -y
Por que kitdot@latest? Configura automaticamente configurações de rede, dependências e estrutura de projeto adequadas. Elimina erros comuns de configuração.
Passo 2: Instalar Dependências
Se usando kitdot@latest: Dependências são instaladas automaticamente.
Instalação manual:
npm install --save-dev @parity/hardhat-polkadot [email protected]
npm install --force @nomicfoundation/hardhat-toolbox
npm install dotenv
Passo 3: Inicializar Plugin Polkadot
Se usando kitdot@latest: Já configurado.
Configuração manual:
npx hardhat-polkadot init
Passo 4: Configurar Chave Privada
npx hardhat vars set PRIVATE_KEY
# Digite sua chave privada quando solicitado (sem prefixo 0x)
Passo 5: Obter Tokens de Teste
Visite https://faucet.polkadot.io/?parachain=1111
Digite o endereço da sua carteira
Solicite tokens PAS
Verifique o saldo na carteira ou block explorer
Passo 6: Criar Configuração Hardhat
Se usando kitdot@latest: Arquivo de configuração já criado com configurações adequadas.
Configuração manual: Copie a configuração exata acima para hardhat.config.js
DESENVOLVIMENTO DE CONTRATOS
Requisitos da Versão Solidity
Versão Obrigatória: ^0.8.28
Target EVM: paris (padrão)
Optimizer: Habilitado por padrão
Exemplo de Contrato Simples
// 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;
}
}
Limitações de Tamanho do Contrato
Bytecode Máximo: ~100KB
Impacto OpenZeppelin: Imports padrão frequentemente excedem o limite
Otimização Necessária: Remover dependências desnecessárias
PROCESSO DE IMPLANTAÇÃO
Usando Hardhat Ignition (Recomendado)
Passo 1: Criar Módulo Ignition
// ignition/modules/SeuModulo.js
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules");
module.exports = buildModule("SeuModulo", (m) => {
const contract = m.contract("SeuContrato", [
// argumentos do construtor
]);
return { contract };
});
Passo 2: Compilar Contratos
npx hardhat compile
# Deve mostrar: "Successfully compiled X Solidity files"
Passo 3: Implantar na Paseo
npx hardhat ignition deploy ./ignition/modules/SeuModulo.js --network passetHub
# Confirme com 'y' quando solicitado
Estados de Implantação
Estado Limpo:
rm -rf ignition/deployments/
para começar do zeroRetomar: Ignition retoma automaticamente implantações interrompidas
Rastrear Transações: Use block explorer para rastrear transações falhadas
ERROS COMUNS E SOLUÇÕES
1. Erro "CodeRejected"
Erro: Failed to instantiate contract: Module(ModuleError { index: 60, error: [27, 0, 0, 0], message: Some("CodeRejected") })
Causas:
Configuração PolkaVM ausente
Configurações de rede incorretas
Configuração resolc ausente
Soluções:
Certifique-se de ter
polkavm: true
na configuração de redeAdicione bloco de configuração resolc
Use formato exato do hardhat.config.js acima
2. Erro "initcode is too big"
Erro: initcode is too big: 125282
(ou número similar)
Causa: Bytecode do contrato excede limite de ~100KB
Soluções:
Remover dependências OpenZeppelin
Usar implementações mínimas de contratos
Dividir contratos grandes em componentes menores
Implementar versões customizadas e leves
3. Erros de Configuração
Erro: Cannot read properties of undefined (reading 'settings')
Solução: Use formato string para versão do Solidity: solidity: "0.8.28"
4. Problemas de Dependência
Erro: Cannot find module 'run-container'
ou similar
Soluções:
Instalar dependências com flag
--force
Limpar node_modules e reinstalar
Verificar compatibilidade da versão @parity/hardhat-polkadot
5. Problemas de Chave Privada
Erro: No signers found
ou falhas de autenticação
Soluções:
Definir chave privada via
npx hardhat vars set PRIVATE_KEY
Certificar-se de que a conta tem tokens PAS
Verificar formato da chave privada (sem prefixo 0x nas vars)
OTIMIZAÇÃO DE CONTRATOS
Removendo Dependências OpenZeppelin
Em vez 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;
}
}
Em vez de OpenZeppelin ReentrancyGuard:
contract SimpleReentrancyGuard {
bool private locked;
modifier nonReentrant() {
require(!locked, "Reentrant call");
locked = true;
_;
locked = false;
}
}
Implementação ERC721 Mínima:
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);
}
}
INTEGRAÇÃO FRONTEND
Problemas de Transações Frontend (Problemas de Estimação de Gas/Legacy)
CRÍTICO PARA AGENTES: Aplicações frontend frequentemente encontram problemas de estimação de gas ao enviar transações para redes Polkadot. Sempre implemente essas estratégias:
Método 1: Estimação de Gas Legacy com Buffer
// Use estimação de gas legacy com buffer de segurança
const gasLimit = await provider.estimateGas({
to: contractAddress,
data: contractInterface.encodeFunctionData("functionName", [args]),
});
// Adicione buffer de 10-20% para segurança
const adjustedGasLimit = gasLimit.mul(120).div(100);
// Envie transação com gas explícito e tipo legacy
const tx = await contract.functionName(args, {
gasLimit: adjustedGasLimit,
type: 0, // Use tipo de transação legacy
});
Método 2: Limites de Gas Fixos
// Use limites de gas fixos para operações previsíveis
const tx = await contract.functionName(args, {
gasLimit: 100000, // Ajuste baseado na complexidade da função
type: 0, // Tipo de transação legacy
gasPrice: ethers.utils.parseUnits("20", "gwei"), // Opcional: definir preço do gas
});
Método 3: Tratamento de Erros e Lógica de Retry
async function sendTransactionWithRetry(
contract,
functionName,
args,
retries = 3
) {
for (let i = 0; i < retries; i++) {
try {
// Tente com gas estimado primeiro
const estimatedGas = await contract.estimateGas[functionName](...args);
const tx = await contract[functionName](...args, {
gasLimit: estimatedGas.mul(120).div(100),
type: 0,
});
return tx;
} catch (error) {
if (i === retries - 1) throw error;
// Fallback para limite de gas fixo
try {
const tx = await contract[functionName](...args, {
gasLimit: 200000, // Limite fixo mais alto
type: 0,
});
return tx;
} catch (fallbackError) {
if (i === retries - 1) throw fallbackError;
}
}
}
}
Configuração de Rede para MetaMask
const paseoConfig = {
chainId: "0x1911f0a6", // 420420422 em 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"],
};
// Adicionar rede ao MetaMask
await window.ethereum.request({
method: "wallet_addEthereumChain",
params: [paseoConfig],
});
Interação com Contrato usando Ethers.js
import { ethers } from "ethers";
// Conectar à Paseo
const provider = new ethers.JsonRpcProvider(
"https://testnet-passet-hub-eth-rpc.polkadot.io"
);
// Instância do contrato
const contract = new ethers.Contract(contractAddress, abi, signer);
// Chamar funções
const result = await contract.someFunction();
TESTES E VERIFICAÇÃO
Verificação de Compilação
npx hardhat compile
# Saída esperada: "Successfully compiled X Solidity files"
# NÃO deve mostrar avisos de tamanho de contrato para contratos <100KB
Verificação de Implantação
Saída de Implantação Bem-sucedida:
[ SeuModulo ] successfully deployed 🚀
Deployed Addresses
SeuModulo#SeuContrato - 0x1234567890abcdef...
Verificação no Block Explorer:
Visite https://blockscout-passet-hub.parity-testnet.parity.io
Procure pelo endereço do contrato
Verifique a transação de criação do contrato
Teste de Interação com Contrato:
npx hardhat console --network passetHub
> const Contract = await ethers.getContractFactory("SeuContrato");
> const contract = Contract.attach("0x...");
> await contract.someFunction();
ESTRATÉGIAS DE DEPURAÇÃO
Verificar Conectividade da Rede
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 da Conta
npx hardhat console --network passetHub
> await ethers.provider.getBalance("SEU_ENDERECO")
Build e Deploy Limpos
npx hardhat clean
rm -rf ignition/deployments/
npx hardhat compile
npx hardhat ignition deploy ./ignition/modules/SeuModulo.js --network passetHub
Rastreamento de Transação
Se a implantação falhar:
Verifique o block explorer para transações da conta
Procure por transações falhadas com erros de gas
Use
npx hardhat ignition track-tx <txHash> <deploymentId> --network passetHub
MELHORES PRÁTICAS
Fluxo de Trabalho de Desenvolvimento
Comece Simples: Implante contratos básicos primeiro para verificar a configuração
Otimize Cedo: Verifique tamanhos de contratos durante o desenvolvimento
Teste Localmente: Use rede hardhat local para testes iniciais
Implantação Incremental: Implante componentes separadamente se muito grandes
Documente Endereços: Mantenha registro de todos os endereços de contratos implantados
Design de Contrato para Paseo
Minimizar Dependências: Evite bibliotecas pesadas
Implementações Customizadas: Escreva versões mínimas de contratos padrão
Design Modular: Divida funcionalidade entre múltiplos contratos
Otimização de Gas: Use estruturas de dados e algoritmos eficientes
Padrões Proxy: Considere contratos atualizáveis para lógica complexa
Considerações de Segurança
Gerenciamento de Chave Privada: Sempre use hardhat vars, nunca faça commit de chaves
Apenas Rede de Teste: Paseo é para testes, não valor de produção
Verificação de Código: Verifique contratos no block explorer quando possível
Controles de Acesso: Implemente sistemas adequados de propriedade e permissão
COMANDOS DE REFERÊNCIA
Comandos Essenciais
# Configuração do projeto
npm install --save-dev @parity/hardhat-polkadot [email protected]
npm install --force @nomicfoundation/hardhat-toolbox
npx hardhat-polkadot init
# Configuração
npx hardhat vars set PRIVATE_KEY
npx hardhat vars list
# Desenvolvimento
npx hardhat compile
npx hardhat clean
npx hardhat test
# Implantação
npx hardhat ignition deploy ./ignition/modules/Module.js --network passetHub
rm -rf ignition/deployments/ # Limpar estado de implantação
# Depuração
npx hardhat console --network passetHub
npx hardhat node # Desenvolvimento local
Variáveis de Ambiente
# Configuração .env opcional
REPORT_GAS=true
ETHERSCAN_API_KEY=your_key_here
IMPLANTAÇÃO NO POLKADOT CLOUD (APILLON)
Configuração de Conta Apillon e UUID do Website
CRÍTICO PARA AGENTES: Ao implantar aplicações frontend no Polkadot Cloud, siga estes passos:
Passo 1: Criar Conta Apillon
INSTRUIR O USUÁRIO PARA:
Visitar Console Apillon: https://app.apillon.io
Registrar Conta: Usar email e criar senha segura
Verificar Email: Completar processo de verificação de email
Conectar Carteira: Vincular sua carteira Polkadot/Substrate para pagamentos
Gerar Credenciais API:
Ir para Settings → API Keys
Clicar em Create New API Key
Nomeá-la (ex. "Projeto Hackathon")
Copiar API Key e API Secret imediatamente
Armazenar com segurança - API Secret só é mostrado uma vez
Passo 2: Criar Projeto de Website
INSTRUIR O USUÁRIO PARA:
Navegar para Seção Hosting: No console Apillon
Criar Novo Website: Clicar no botão "New Website"
Configurar Projeto:
Project Name: [Nome do Seu Projeto] Environment: Production Domain: [Domínio personalizado opcional]
Copiar UUID do Website: Após criação, copiar o UUID gerado (formato:
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
)Fornecer UUID ao Agente: Compartilhar o UUID do Website para que o agente possa configurar a implantação
Passo 3: Obter UUID do Website para Implantação
# Exemplo formato UUID
WEBSITE_UUID="12345678-1234-5678-9abc-123456789def"
Configuração MCP para Hosting no Polkadot Cloud
Configuração do Protocolo de Contexto de Modelo (MCP):
Passo 1: Configuração do Servidor MCP
CRÍTICO PARA AGENTES: Configure seu cliente MCP para usar o servidor MCP do Apillon.
Para Claude Desktop:
Adicione isso ao seu arquivo de configuração 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/seu-usuario/Desktop"
]
}
}
}
Passos de Configuração Claude Desktop:
Localizar arquivo config MCP: Geralmente em
~/Library/Application Support/Claude/claude_desktop_config.json
(macOS)Adicionar servidor Apillon: Inserir a configuração acima
Substituir placeholders: Atualizar
<APILLON_API_KEY>
e<APILLON_API_SECRET>
com valores reaisAtualizar caminho filesystem: Mudar
/Users/seu-usuario/Desktop
para seu diretório de projetoReiniciar Claude Desktop: Necessário para que as mudanças MCP tenham efeito
Para Cursor IDE:
Configuração MCP no Cursor:
Instalar extensão MCP: No Cursor, ir para Extensions e buscar "Model Context Protocol"
Abrir configurações Cursor:
Cmd/Ctrl + ,
→ Buscar "MCP"Adicionar configuração 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>"
}
}
}
}
Passos de Configuração Cursor:
Abrir settings.json:
Cmd/Ctrl + Shift + P
→ "Preferences: Open Settings (JSON)"Adicionar configuração MCP: Inserir a configuração acima
Substituir placeholders: Atualizar credenciais API
Reiniciar Cursor: Necessário para que as mudanças MCP tenham efeito
Verificar conexão: Verificar status MCP na paleta de comandos do Cursor
Passo 2: Instalar CLI do Apillon (Método Alternativo)
npm install -g @apillon/cli
Passo 3: Configurar Autenticação
# Login no Apillon
apillon login
# Verificar autenticação
apillon whoami
Passo 4: Configurar MCP para Implantação Automatizada
Criar .apillon.json
na raiz do projeto:
{
"websites": [
{
"uuid": "SEU_UUID_WEBSITE_AQUI",
"name": "Nome do Seu Projeto",
"source": "./dist",
"environment": "production"
}
]
}
Passo 5: Script de Implantação MCP
#!/bin/bash
# deploy-to-polkadot-cloud.sh
# Construir o projeto
npm run build
# Implantar no Apillon
apillon hosting deploy \
--uuid $WEBSITE_UUID \
--source ./dist \
--environment production
# Verificar implantação
apillon hosting info --uuid $WEBSITE_UUID
Passo 6: Variáveis de Ambiente
# Definir no seu ambiente
export APILLON_API_KEY="sua_api_key_aqui"
export WEBSITE_UUID="seu_uuid_website_aqui"
Melhores Práticas para Agentes
Configurar MCP primeiro: Configurar servidor MCP do Apillon no seu IDE (Claude Desktop ou Cursor) antes de começar a implantação.
Sempre usar CLI Apillon mais recente:
npm install -g @apillon/cli@latest
Credenciais seguras: Armazenar API keys e UUIDs como variáveis de ambiente, nunca no código
Guiar usuário na configuração da conta: Instruir claramente usuários sobre criação de conta Apillon e geração de API key
Verificar implantações: Sempre verificar status da implantação após upload
Usar ambiente produção: Para entregas finais de hackathon
Monitorar custos: Apillon usa modelo pay-per-use
Testar localmente primeiro: Sempre testar builds antes de implantar
Reiniciar seu IDE: Após mudanças de configuração MCP (Claude Desktop ou Cursor)
Verificar conexão MCP: Verificar se servidor MCP do Apillon está conectado corretamente antes da implantação
DIRETRIZES DE ESCRITA PARA LLMs
Ao criar documentação ou ajudar desenvolvedores:
CHECKLIST DE SOLUÇÃO DE PROBLEMAS
Primeiro: Tente kitdot@latest init com projeto novo e copie código existente
Quando a implantação falhar, verifique:
LIMITAÇÕES E SOLUÇÕES ALTERNATIVAS
Limitações Atuais
Tamanho do Contrato: Limite de 100KB de bytecode
OpenZeppelin: A maioria das bibliotecas são muito grandes
Estabilidade da Rede: Preview release, possível tempo de inatividade
Ferramentas de Depuração: Limitadas comparadas à mainnet
Documentação: Escassa, soluções dirigidas pela comunidade
Soluções Alternativas Recomendadas
Problemas de Tamanho: Use implementações customizadas mínimas
Lógica Complexa: Divida entre múltiplos contratos
Gerenciamento de Estado: Use eventos para dados off-chain
Experiência do Usuário: Forneça mensagens de erro claras
Testes: Testes locais extensivos antes da implantação
Este guia fornece informações abrangentes para implantação bem-sucedida de smart contracts na Paseo TestNet usando Claude Code, incluindo todas as configurações críticas, problemas comuns e estratégias de otimização.
Última actualización