Logo
Nuevos usuarios de RPC: 35% de descuento el primer mesVer oferta
OnFinality Learn
Fiabilidad y consistencia13 min de lectura

Huella digital del nodo RPC con el que hablas: chainId, net_version, clientVersion

Una verificación de identidad previa al vuelo para cualquier endpoint RPC de Ethereum: verifica el ID de cadena, el ID de red, la versión del cliente y el hash del bloque génesis antes de confiarle tráfico de producción.

TL;DR

Cada endpoint RPC de Ethereum puede ser identificado antes de enviarle tráfico de producción llamando a un pequeño conjunto de métodos de identidad de solo lectura: eth_chainId devuelve el ID de cadena EIP-155 como una cantidad hexadecimal, net_version devuelve una cadena decimal heredada del ID de red, web3_clientVersion devuelve una cadena de cliente de formato libre, y eth_getBlockByNumber('0x0', false) devuelve el bloque génesis cuyo hash identifica de forma única la cadena. El ID de cadena y el ID de red no son el mismo valor y no deben usarse indistintamente en la firma de transacciones; el ID de cadena es el valor vinculado a las firmas con protección contra repetición, mientras que el ID de red es un identificador heredado cuya semántica varía según el cliente. Un endpoint de testnet mal configurado para servir datos de mainnet seguirá respondiendo a eth_chainId, por lo que la detección fiable consiste en comparar tanto el ID de cadena devuelto como el hash génesis con las constantes esperadas. La identificación es barata, de solo lectura y almacenable en caché por endpoint, pero no puede confirmar la capacidad de archivo, la política de límite de velocidad ni que web3_clientVersion sea veraz, ya que esa cadena es autoinformada y puede ser enmascarada por un proxy.

Por qué la identidad del endpoint es un requisito previo al vuelo

Una URL RPC es una cadena opaca hasta que le pides al nodo que hay detrás que se identifique. Antes de enrutar transacciones de usuarios, lecturas de indexadores o tráfico de conmutación por error a través de un endpoint, necesitas saber qué cadena sirve y qué software cliente responde. La especificación JSON-RPC de Ethereum define los métodos de identidad, y el esquema execution-apis es la fuente autorizada para sus formas de solicitud y respuesta.

Las verificaciones de identidad son baratas: son llamadas de solo lectura que devuelven cargas útiles pequeñas y no tocan el estado. Eso las hace adecuadas como sonda de inicio, verificación periódica de estado o puerta en un balanceador de carga. También son la primera línea de defensa contra una clase de mala configuración silenciosa en la que un endpoint de testnet sirve datos de mainnet, o en la que una ruta de conmutación por error apunta a una cadena completamente distinta.

Este artículo separa tres cosas que a menudo se confunden: el comportamiento documentado del protocolo (lo que la especificación dice que devuelven estos métodos), el comportamiento específico del proveedor (lo que realmente devuelve un host dado, que varía) y los métodos de medición que puedes ejecutar tú mismo contra tus propios endpoints. Donde un valor sería un punto de referencia, este artículo describe cómo medirlo en lugar de afirmar un número.

  • Documentado: eth_chainId devuelve el ID de cadena EIP-155 como una cantidad hexadecimal.
  • Documentado: net_version devuelve un ID de red decimal como una cadena.
  • Varía según el cliente: si net_version coincide con el ID de cadena y si eth_protocolVersion está implementado siquiera.
  • Varía según el proveedor: si web3_clientVersion se pasa, se reescribe o se enmascara.

Los métodos de identidad y qué prueba realmente cada uno

eth_chainId devuelve el ID de cadena como una cantidad hexadecimal, por ejemplo 0x1 para Ethereum mainnet. Este es el valor que aparece en las firmas de transacciones con protección contra repetición EIP-155, por lo que es el campo de identidad que más importa para la corrección de la firma. Si una billetera firma contra el ID de cadena incorrecto, la transacción se rechaza o, peor aún, es válida en una cadena diferente.

net_version devuelve una cadena decimal, por ejemplo "1". Es anterior a EIP-155 y es un identificador de red heredado. En muchas cadenas resulta ser igual al ID de cadena, pero eso es una convención, no una garantía. Algunos clientes lo proxyean de forma inconsistente, y algunas cadenas divergen deliberadamente ambos valores. Trata net_version como una señal secundaria, nunca como la autoridad para firmar.

web3_clientVersion devuelve una cadena de formato libre como Geth/v1.14.x/linux-amd64/go1.22. Identifica la familia de cliente, la versión, el sistema operativo y el entorno de ejecución del lenguaje. Como es de formato libre, debes analizarla de forma defensiva y nunca asumir un formato fijo. eth_protocolVersion está obsoleto en muchos clientes y puede devolver un error o un valor desactualizado; no construyas lógica sobre él. eth_syncing informa el progreso de sincronización y es útil para confirmar que un endpoint está al día, lo cual se cubre con más profundidad en detectar un nodo RPC detrás de la punta de la cadena.

  • eth_chainId: cantidad hexadecimal, autoritativo para la firma EIP-155.
  • net_version: cadena decimal, heredado, semántica específica del cliente.
  • web3_clientVersion: cadena de formato libre, autoinformada, analizar de forma defensiva.
  • eth_protocolVersion: obsoleto en muchos clientes, evita depender de él.
  • eth_syncing: progreso de sincronización, no es un campo de identidad pero forma parte de una puerta de estado.

ID de cadena versus ID de red en la firma de transacciones

La distinción importa porque la firma de transacciones usa el ID de cadena, no el ID de red. EIP-155 vincula el ID de cadena a la firma para que una transacción firmada para una cadena no pueda reproducirse en otra. Si tu ruta de firma lee net_version y lo usa como ID de cadena, has introducido un error de corrección que puede que solo se manifieste en cadenas donde ambos valores difieren.

El patrón seguro es leer eth_chainId, compararlo con una constante esperada codificada para la red que pretendes usar y negarte a firmar si no coincide. El ID de red puede registrarse para diagnóstico, pero no debe condicionar la firma. En OnFinality, la página de la red Ethereum enumera las redes compatibles y sus ID de cadena para que puedas fijar el valor esperado en la configuración.

Un modo de fallo común es un archivo de configuración que almacena un único campo "network" usado tanto para visualización como para firma. Dividirlo en un campo chainId explícito y un campo networkId de diagnóstico separado elimina la ambigüedad.

  • Firma con el ID de cadena, nunca con el ID de red.
  • Fija el ID de cadena esperado como constante por entorno.
  • Registra net_version solo para diagnóstico.
  • Rechaza la firma cuando eth_chainId no coincida con la constante fijada.

Detectar un endpoint de testnet que sirve datos de mainnet silenciosamente

Un endpoint mal configurado puede responder correctamente a eth_chainId para la cadena que realmente sirve mientras tu aplicación cree que apunta a una testnet. El ID de cadena por sí solo no detectará esto si tu constante esperada es incorrecta o si el endpoint es un proxy que reescribe la respuesta. La verificación robusta es comparar dos valores independientes: el ID de cadena y el hash del bloque génesis.

eth_getBlockByNumber('0x0', false) devuelve el bloque génesis. Su hash es una función determinista de la configuración génesis de la cadena y es efectivamente una huella digital única. Comparar el hash génesis devuelto con una constante conocida y válida para la red prevista detecta un endpoint de testnet que sirve datos de mainnet, porque los hashes génesis difieren. Este es el mismo principio usado en verificaciones de consistencia RPC multi-endpoint, donde la concordancia de cabeza y génesis se usa para detectar divergencias.

Combina ambas verificaciones: el ID de cadena debe ser igual a la constante esperada, y el hash génesis debe ser igual a la constante esperada. Si cualquiera falla, el endpoint no es el que crees que es.

  • La verificación del ID de cadena detecta enrutamiento a la red incorrecta.
  • La verificación del hash génesis detecta un proxy que reescribe el ID de cadena.
  • Ambas verificaciones juntas son más fuertes que cualquiera por separado.
  • Almacena los hashes génesis esperados por red en la configuración.

Una rutina de huella digital previa al vuelo en Node.js

La rutina a continuación llama a eth_chainId, net_version, web3_clientVersion, eth_blockNumber y eth_getBlockByNumber('0x0', false), luego compara el ID de cadena y el hash génesis con las constantes esperadas. Es de solo lectura y segura para ejecutar al inicio o según una programación. Ejecútala contra cada endpoint de tu grupo y registra la salida.

La función devuelve un objeto de huella digital estructurado. En un balanceador de carga o controlador de conmutación por error, llamarías a esto antes de agregar un endpoint al grupo activo y rechazarías cualquier endpoint cuyo chainId o genesisHash no coincida. La guía de balanceo de carga y conmutación por error multi-proveedor cubre cómo integrar esto en un grupo.

const EXPECTED = {
  chainId: '0x1',
  genesisHash: '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3'
};

async function rpc(url, method, params = []) {
  const res = await fetch(url, {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params })
  });
  const json = await res.json();
  if (json.error) throw new Error(method + ': ' + JSON.stringify(json.error));
  return json.result;
}

async function fingerprint(url) {
  const [chainId, netVersion, clientVersion, blockNumber, genesis] = await Promise.all([
    rpc(url, 'eth_chainId'),
    rpc(url, 'net_version'),
    rpc(url, 'web3_clientVersion'),
    rpc(url, 'eth_blockNumber'),
    rpc(url, 'eth_getBlockByNumber', ['0x0', false])
  ]);
  const genesisHash = genesis && genesis.hash;
  return {
    url,
    chainId,
    netVersion,
    clientVersion,
    blockNumber,
    genesisHash,
    chainIdOk: chainId === EXPECTED.chainId,
    genesisOk: genesisHash === EXPECTED.genesisHash
  };
}

fingerprint('https://your-endpoint.example')
  .then(fp => console.log(JSON.stringify(fp, null, 2)))
  .catch(err => console.error('fingerprint failed:', err.message));

Cadenas de versión de cliente en Geth, Nethermind, Erigon, Besu y Reth

web3_clientVersion difiere según la familia de cliente. Geth normalmente devuelve una cadena que comienza con Geth/, Nethermind con Nethermind/, Erigon con erigon/, Besu con besu/ y Reth con reth/. El formato exacto no está estandarizado, así que analiza el token inicial y trata el resto como metadatos opacos.

Las diferencias de versión menor importan para el soporte de métodos. Los espacios de nombres trace y debug no están disponibles de manera uniforme entre clientes o versiones, y un proveedor puede deshabilitarlos por completo. Si tu aplicación depende de métodos trace_* o debug_*, identificar la versión del cliente es una verificación necesaria pero no suficiente: también debes sondear el método específico que pretendes llamar. La guía del nodo RPC de Ethereum cubre la disponibilidad de métodos con más detalle.

Como la cadena es autoinformada, un proxy puede reescribirla o enmascararla. Un proveedor que pone múltiples versiones de cliente detrás de una URL puede devolver una cadena genérica. Trata la versión del cliente como una pista para diagnóstico y planificación de capacidades, no como un límite de seguridad.

  • Geth, Nethermind, Erigon, Besu y Reth usan cada uno un token inicial distinto.
  • Las versiones menores pueden cambiar qué espacios de nombres están habilitados.
  • Sondea el método específico que necesitas; no lo infieras solo de la cadena de versión.
  • Un proxy puede enmascarar o reescribir la cadena.

Almacenar en caché la huella digital y volver a verificar ante cambios

Identificar en cada solicitud es un desperdicio. El ID de cadena y el hash génesis de un endpoint dado son efectivamente inmutables, así que almacénalos en caché por endpoint y vuelve a validarlos solo cuando el endpoint cambie o cuando falle una verificación de estado. La versión del cliente y el número de bloque son más volátiles y pueden actualizarse con una programación más lenta.

Una política práctica es: identificar una vez en el registro del endpoint, almacenar en caché chainId y genesisHash indefinidamente, actualizar clientVersion y blockNumber cada pocos minutos, y volver a ejecutar la identificación completa si falla alguna verificación de estado o si cambia la URL del endpoint. Esto mantiene el costo cerca de cero mientras sigue detectando a un proveedor que cambia silenciosamente el backend detrás de una URL.

La guía de monitoreo de endpoints RPC cubre cómo integrar estas verificaciones en un bucle de verificación de estado más amplio, y el centro de aprendizaje de OnFinality recopila temas de fiabilidad relacionados.

  • Almacena en caché chainId y genesisHash por endpoint; son inmutables.
  • Actualiza clientVersion y blockNumber con una programación más lenta.
  • Vuelve a ejecutar la identificación completa ante fallo de verificación de estado o cambio de URL.
  • Alerta cuando un chainId o genesisHash en caché cambie inesperadamente.

Un método de medición que puedes ejecutar contra tus propios endpoints

La tabla a continuación es una plantilla para registrar huellas digitales en tu grupo de endpoints. Complétala ejecutando la rutina de Node.js anterior contra cada URL. No confíes en los números de este artículo; mide tus propios endpoints y registra los resultados. Este es el método verificado por el lector: los valores son tuyos, no nuestros.

Registra la URL del endpoint, el ID de cadena devuelto, el ID de red devuelto, la cadena de versión del cliente, el último número de bloque, el hash génesis y si el ID de cadena y el hash génesis coinciden con tus constantes esperadas. Vuelve a ejecutar la tabla después de cualquier cambio de proveedor o incidente.

  • URL del endpoint: la URL RPC exacta que estás probando.
  • chainId: el valor hexadecimal devuelto por eth_chainId.
  • netVersion: la cadena decimal devuelta por net_version.
  • clientVersion: la cadena de formato libre devuelta por web3_clientVersion.
  • blockNumber: el valor hexadecimal devuelto por eth_blockNumber.
  • genesisHash: el campo hash de eth_getBlockByNumber('0x0', false).
  • chainIdOk / genesisOk: coincidencia booleana con tus constantes esperadas.

Solución de problemas de discrepancias y respuestas inesperadas

Cuando falla una verificación de huella digital, el primer paso es determinar qué campo no coincidió. Una discrepancia en el ID de cadena generalmente significa que el endpoint apunta a una red diferente a la esperada, o que la constante esperada en tu configuración es incorrecta. Una discrepancia en el hash génesis con un ID de cadena correcto sugiere un proxy o una configuración de cadena no estándar.

Si net_version no concuerda con eth_chainId, no asumas que el endpoint está roto. En algunas cadenas los dos valores difieren legítimamente, y en algunos clientes net_version se proxya de forma inconsistente. Registra la discrepancia y sigue confiando en eth_chainId para firmar.

Si web3_clientVersion devuelve una cadena inesperada o genérica, el proveedor puede estar enmascarándola. Esto no es necesariamente una falla, pero significa que no puedes confiar en la cadena de versión para la planificación de capacidades. Sondea los métodos específicos que necesitas en su lugar. Si eth_protocolVersion devuelve un error, eso es esperado en muchos clientes modernos y no debe tratarse como una falla.

  • Discrepancia en el ID de cadena: verifica el enrutamiento de red y tu constante esperada.
  • Discrepancia en el hash génesis con ID de cadena correcto: sospecha de un proxy o cadena no estándar.
  • Desacuerdo en net_version: regístralo, confía en eth_chainId para firmar.
  • Versión de cliente genérica: sondea los métodos específicos que necesitas.
  • Error de eth_protocolVersion: esperado en muchos clientes, no es una falla.

Limitaciones, compensaciones y consideraciones de privacidad

La identificación es barata y de solo lectura, pero tiene límites reales. web3_clientVersion es autoinformada y puede ser falsificada o enmascarada por un proxy, por lo que no es un límite de seguridad. La semántica de net_version es específica del cliente y está documentada como variable según el cliente, por lo que no debe condicionar la firma. Ninguno de estos métodos confirma que un endpoint tenga capacidad de archivo, que respete un límite de velocidad particular o que permanezca estable bajo carga.

También hay una consideración de privacidad: la identificación enumera tu mezcla de clientes y la topología de endpoints. Si ejecutas muchos endpoints, el patrón de llamadas de identidad puede revelar de qué clientes y proveedores dependes. Esto es una preocupación menor para la mayoría de los equipos, pero vale la pena señalarlo para aquellos con requisitos estrictos de seguridad operativa.

Finalmente, las verificaciones de identidad son necesarias pero no suficientes. Deben combinarse con verificaciones de retraso de cabeza, verificaciones de consistencia entre endpoints y sondas a nivel de método. Las páginas de servicio API y precios RPC describen cómo OnFinality estructura el acceso a endpoints, y la guía del nodo RPC de Ethereum cubre el panorama operativo más amplio.

  • web3_clientVersion es autoinformada y puede ser falsificada o enmascarada.
  • La semántica de net_version varía según el cliente; no la uses para firmar.
  • Las verificaciones de identidad no confirman capacidad de archivo ni política de límite de velocidad.
  • La identificación enumera tu mezcla de clientes y topología de endpoints.
  • Combina las verificaciones de identidad con verificaciones de retraso de cabeza y consistencia.

Próximos pasos para la gobernanza de endpoints en producción

Convierte la rutina de huella digital en una puerta: ningún endpoint entra al grupo activo hasta que su ID de cadena y hash génesis coincidan con las constantes esperadas. Almacena en caché los campos inmutables, actualiza los volátiles y alerta ante cambios inesperados. Esta es la gobernanza de identidad mínima viable para cualquier aplicación que firme transacciones o enrute fondos de usuarios.

A partir de ahí, añade detección de retraso de cabeza, verificaciones de consistencia multi-endpoint y sondas a nivel de método para los espacios de nombres específicos de los que dependes. El centro de aprendizaje de OnFinality recopila estos temas, y la página de la red Ethereum enumera las redes compatibles y los ID de cadena para que puedas fijar los valores esperados en la configuración.

Si estás evaluando proveedores, ejecuta la tabla de huellas digitales contra cada endpoint candidato y compara los resultados. Los valores son tuyos para medir, y son la señal más fiable que tienes sobre lo que realmente hay detrás de una URL.

  • Condiciona la admisión de endpoints a la coincidencia de ID de cadena y hash génesis.
  • Almacena en caché los campos inmutables; actualiza los volátiles según una programación.
  • Añade verificaciones de retraso de cabeza, consistencia y sondas a nivel de método.
  • Ejecuta la tabla de huellas digitales contra proveedores candidatos antes de comprometerte.

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