Logo
Nuevos usuarios de RPC: 35% de descuento el primer mesVer oferta
OnFinality Learn
Integración y desarrollo11 min de lectura

Dapps Web3: arquitectura, integración RPC y una verificación de estado reproducible

Una guía práctica sobre cómo las dapps Web3 conectan contratos inteligentes, frontends, billeteras e infraestructura RPC, con diagnósticos ejecutables y un procedimiento de medición.

TL;DR

Una dapp Web3 es un frontend más uno o varios contratos inteligentes, conectados a través de billeteras y una capa RPC que lee el estado de la cadena y envía transacciones. El contrato es la lógica del backend, pero el endpoint RPC es la dependencia en tiempo de ejecución que determina si los usuarios pueden interactuar realmente. Este artículo explica la ruta de la solicitud, muestra comprobaciones ejecutables con curl y JavaScript contra un RPC_URL de marcador de posición, y ofrece un procedimiento de medición que puedes ejecutar tú mismo en lugar de confiar en benchmarks publicados. También cubre modos de fallo comunes, compensaciones entre acceso RPC público y dedicado, y próximos pasos para reforzar una dapp antes del lanzamiento.

Qué es realmente una dapp Web3

Una dapp Web3 (aplicación descentralizada) es una aplicación cuya lógica de negocio principal reside en contratos inteligentes desplegados en una blockchain, con un frontend que lee y escribe ese estado a través de una billetera y un endpoint RPC. El contrato es inmutable una vez desplegado, a menos que incluya mecanismos de actualización, por lo que el frontend y la capa RPC son donde ocurre la mayor parte del cambio operativo.

Este artículo se centra en el lado de integración y operaciones: cómo viaja una solicitud de dapp desde un navegador hasta un contrato, cómo verificar cada salto con código ejecutable y cómo medir el comportamiento RPC que experimentarán tus usuarios. Asume que tienes un contrato desplegado o de prueba, una billetera y un RPC_URL para la red objetivo. Para la selección de endpoints en lugar de la metodología, consulta la guía del Asistente RPC sobre cómo elegir un proveedor RPC para proyectos Web3.

  • Contrato inteligente: lógica y estado en cadena, el backend de la dapp.
  • Frontend: interfaz que codifica llamadas y muestra resultados decodificados.
  • Billetera: firma transacciones y gestiona claves; no ejecuta la lógica del contrato.
  • Endpoint RPC: la puerta de enlace HTTP o WebSocket que reenvía lecturas y difunde transacciones firmadas.

La ruta de la solicitud desde el navegador hasta el contrato

Una llamada de lectura como balanceOf o una función view es un eth_call: el frontend codifica con ABI el selector de función y los argumentos, la billetera o el proveedor envía la llamada al endpoint RPC, y el nodo la ejecuta contra el estado más reciente sin producir una transacción. Una llamada de escritura es diferente: el frontend construye una transacción, la billetera la firma y el endpoint RPC la difunde al mempool. Luego el nodo devuelve un hash de transacción y la confirmación llega más tarde a través de recibos o registros.

Esta distinción es importante para la depuración. Los fallos de lectura suelen indicar disponibilidad del endpoint, desajuste de cadena o calldata mal formada. Los fallos de escritura suelen indicar problemas de firma, conflictos de nonce, gas insuficiente o un nodo que aceptó la transacción pero no la propagó. Mantener las dos rutas separadas en tus registros acorta considerablemente el diagnóstico.

Requisitos previos y suposiciones

Los ejemplos siguientes utilizan un RPC_URL y una PRIVATE_KEY de marcador de posición. Reemplázalos con valores para tu propio entorno; nunca confirmes claves reales. Necesitas Node.js 18 o posterior para los ejemplos de JavaScript, curl para las comprobaciones de shell y una dirección de contrato con un método de lectura conocido. Los ejemplos utilizan métodos JSON-RPC estándar (eth_chainId, eth_blockNumber, eth_getBalance, eth_call) que están ampliamente implementados, pero confirma la compatibilidad de métodos para tu red específica antes de confiar en ellos en producción.

Si aún estás seleccionando una red, el directorio de redes de OnFinality enumera las cadenas compatibles y sus endpoints. Para cargas de trabajo en producción, compara el acceso compartido a la API con la infraestructura de nodo dedicado antes de comprometerte con una arquitectura.

Verificar el salto RPC con curl

Comienza confirmando que el endpoint responde, informa la cadena esperada y está avanzando. Estas tres comprobaciones detectan las configuraciones incorrectas más comunes: una red equivocada, un nodo obsoleto o con balanceo de carga, y un endpoint que devuelve HTTP 200 con un cuerpo de error JSON-RPC.

Ejecuta cada solicitud e inspecciona tanto el estado HTTP como el campo de error JSON-RPC. Una respuesta con un objeto de error es un fallo incluso cuando el estado HTTP es 200.

curl -s -X POST "$RPC_URL" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'

curl -s -X POST "$RPC_URL" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"eth_blockNumber","params":[]}'

curl -s -X POST "$RPC_URL" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":3,"method":"eth_getBalance","params":["0x0000000000000000000000000000000000000000","latest"]}'

Resultado esperado de la verificación

Un endpoint saludable devuelve un objeto JSON con jsonrpc establecido en 2.0, el mismo id que enviaste y un campo result. eth_chainId debe devolver el ID de cadena codificado en hexadecimal que esperas; eth_blockNumber debe devolver una altura de bloque en hexadecimal que aumente entre llamadas; eth_getBalance debe devolver un valor en wei en hexadecimal. Si alguna respuesta contiene un objeto de error, registra el código y el mensaje antes de cambiar cualquier otra cosa.

Repite la llamada de número de bloque después de un intervalo corto. Si la altura no cambia, el endpoint puede estar fijado a un backend retrasado o la red puede estar estancada. Distingue ambos casos comprobando un segundo endpoint independiente antes de concluir que la red tiene la culpa.

Leer el estado del contrato desde un frontend de dapp

El siguiente ejemplo de Node.js utiliza ethers para leer un contrato a través de RPC_URL. Realiza un eth_call, decodifica el resultado y lo imprime. Esta es la misma ruta que sigue un frontend de navegador, menos la billetera, lo que lo convierte en una primera prueba de integración útil.

Mantén el ABI mínimo: incluye solo las funciones que llamas. Un ABI más pequeño reduce la posibilidad de errores de decodificación y hace que la prueba sea más fácil de auditar.

import { JsonRpcProvider, Contract } from 'ethers';

const provider = new JsonRpcProvider(process.env.RPC_URL);
const abi = ['function totalSupply() view returns (uint256)'];
const contract = new Contract(process.env.CONTRACT_ADDRESS, abi, provider);

const [network, blockNumber, supply] = await Promise.all([
  provider.getNetwork(),
  provider.getBlockNumber(),
  contract.totalSupply()
]);

console.log({ chainId: network.chainId.toString(), blockNumber, supply: supply.toString() });

Enviar una transacción firmada de forma segura

Las rutas de escritura requieren un firmante. El ejemplo siguiente envía una transacción y espera una confirmación. Utiliza una PRIVATE_KEY de marcador de posición y solo debe ejecutarse contra una red de prueba con una clave de prueba financiada. En producción, la firma corresponde a la billetera o a un firmante gestionado, nunca al código del frontend.

Antes de difundir, obtén el nonce y los datos de tarifas actuales del mismo endpoint que utilizarás para el envío. Mezclar endpoints entre la consulta de nonce y la difusión es una fuente común de errores de transacción de reemplazo.

import { JsonRpcProvider, Wallet } from 'ethers';

const provider = new JsonRpcProvider(process.env.RPC_URL);
const wallet = new Wallet(process.env.PRIVATE_KEY, provider);

const tx = await wallet.sendTransaction({
  to: process.env.RECIPIENT_ADDRESS,
  value: 0n
});
console.log('broadcast', tx.hash);

const receipt = await tx.wait(1);
console.log('confirmed', receipt.status, receipt.blockNumber);

Un procedimiento de medición RPC reproducible

Los números de latencia publicados rara vez son comparables porque dependen de la ubicación del cliente, la carga útil, la concurrencia y la hora del día. Ejecuta tu propia medición. Utiliza una carga útil fija (eth_blockNumber), un número fijo de muestras (por ejemplo, 200 solicitudes secuenciales) y registra p50, p95 y la tasa de error. Repite en tres momentos del día y desde la región donde se concentran tus usuarios.

Registra los resultados en una tabla como la siguiente. No rellenes números que no hayas medido; deja las celdas en blanco hasta que tengas datos. Compara endpoints en condiciones idénticas y trata la tasa de error como una métrica de primer nivel junto con la latencia.

  • Columnas de métricas: etiqueta del endpoint, región, número de muestras, p50 ms, p95 ms, tasa de error, notas.
  • Ejecuta el mismo script contra cada endpoint candidato y la misma red.
  • Conserva las muestras sin procesar para poder recalcular los percentiles más tarde.
  • Vuelve a ejecutar después de cualquier cambio de proveedor o red; no reutilices tablas obsoletas.

Solución de problemas comunes de dapps

La mayoría de los incidentes de dapps se engloban en un pequeño conjunto de categorías. Utiliza la ruta de solicitud anterior para localizar el fallo antes de cambiar el código.

Si las lecturas fallan pero el endpoint responde a eth_chainId, verifica la dirección del contrato y el ID de cadena en tu configuración. Si las escrituras fallan después de firmar, compara el nonce devuelto por eth_getTransactionCount con el nonce de la transacción firmada. Si los usuarios informan fallos intermitentes, mide la tasa de error por endpoint en lugar de confiar en una única reproducción.

  • Desajuste de cadena: la red de la billetera difiere de la red de despliegue del contrato.
  • Estado obsoleto: el endpoint sirve un bloque retrasado; compara las alturas de bloque entre endpoints.
  • Conflicto de nonce: una transacción pendiente de la misma clave bloquea la nueva.
  • Límite de velocidad: HTTP 429 o códigos de error JSON-RPC bajo tráfico frontend en ráfagas.
  • Llamada revertida: eth_call devuelve un error con datos de revert; decodifícalo antes de reintentar.

Limitaciones y compensaciones

Los endpoints RPC públicos son convenientes para prototipos, pero normalmente imponen límites de velocidad y no ofrecen compromiso de disponibilidad. Los nodos dedicados mejoran el aislamiento y la previsibilidad, pero añaden costo operativo y requieren monitoreo. Un patrón común es utilizar una API gestionada para lecturas y un endpoint dedicado o privado para escrituras y rutas sensibles a la latencia.

Ninguna medición única demuestra que un endpoint sea confiable. La latencia medida desde una región no predice otra, y una baja tasa de error durante una hora no garantiza el comportamiento durante la congestión. Trata cualquier elección de RPC como una hipótesis que debe volver a probarse y mantén configurado un endpoint de respaldo. Para planificación de precios y capacidad, revisa la página de precios de RPC y la descripción general del servicio API.

Próximos pasos para la preparación de producción

Una vez que las rutas de lectura y escritura funcionen, añade monitoreo en torno a las métricas que mediste: retraso de altura de bloque, latencia p95 y tasa de error por endpoint. Configura al menos un endpoint de respaldo y prueba la conmutación por error deliberadamente. Documenta el ID de cadena, las direcciones de los contratos y el tiempo de bloque esperado para cada despliegue, de modo que los respondedores de guardia puedan verificar la configuración rápidamente.

Para los equipos que estandarizan un proveedor, la comparación del Asistente RPC de endpoints RPC multicadena cubre las preguntas operativas que hay que plantear antes de comprometerse. Combínalo con la guía de alojamiento de nodos blockchain si planeas ejecutar tu propia infraestructura junto con el acceso gestionado.

Nunca te preocupes por la infraestructura nuevamente

OnFinality elimina la carga pesada de DevOps para que puedas construir de forma más inteligente y rápida.

Comenzar