El contrato de depósito es el punto de entrada on-chain a través del cual el ETH y los datos de depósito de los validadores ingresan al sistema de prueba de participación de Ethereum. No se limita a aceptar ETH; valida la estructura de cada depósito, calcula una raíz de Merkle sobre los datos de depósito y emite un evento que los clientes de la cadena de balizas consumen. Este artículo explica el formato de los datos de depósito, las reglas de validación que aplica el contrato y un procedimiento reproducible para verificar un depósito mediante llamadas JSON-RPC estándar. También cubre los modos de fallo comunes, los límites de lo que el contrato puede y no puede comprobar, y cómo elegir un acceso RPC fiable para los flujos de verificación.
Alcance y los dos significados de contrato de depósito
En el uso legal y financiero general, un contrato de depósito es un acuerdo privado en el que una parte coloca fondos con otra en calidad de garantía, pago de reserva o garantía de cumplimiento. Ese significado aparece en reservas de propiedades, depósitos de seguridad de alquileres y acuerdos de depósito bancario. Este artículo no cubre esos instrumentos. Se centra en el significado técnico que domina la ingeniería blockchain: el Contrato de Depósito de Balizas de Ethereum, un contrato inteligente desplegado en la red principal de Ethereum que acepta depósitos de staking y emite los datos que los nodos de baliza necesitan para activar validadores.
La distinción importa porque ambos conceptos comparten nombre pero casi nada más. Un contrato de depósito legal se hace cumplir por los tribunales y especifica condiciones de devolución o pérdida. El contrato de depósito on-chain se hace cumplir por el bytecode y especifica una clave pública fija de 48 bytes, credenciales de retiro de 32 bytes, una firma de 96 bytes y una raíz de datos de depósito de 32 bytes. Comprender la versión on-chain requiere leer su lógica de validación en lugar de sus términos legales.
- Contrato de depósito legal: acuerdo privado, dependiente de la jurisdicción, cubre fondos de reserva o garantía.
- Contrato de depósito de Ethereum: contrato inteligente inmutable, valida la estructura del depósito, emite DepositEvent.
- Esta guía cubre solo el contrato on-chain y el flujo de verificación que lo rodea.
Qué valida realmente el contrato de depósito
El contrato de depósito es deliberadamente mínimo. Por cada depósito que recibe, comprueba que la cantidad de ETH sea un múltiplo entero de 1 ETH, que la raíz de datos de depósito proporcionada coincida con la raíz del árbol de hash calculada a partir de la clave pública, las credenciales de retiro y la firma, y que la cantidad codificada en los datos de depósito coincida con el valor enviado. Si alguna comprobación falla, la transacción se revierte. Si todas las comprobaciones pasan, el contrato añade el depósito a un árbol de Merkle interno, actualiza el contador de depósitos y emite un DepositEvent que contiene la clave pública, las credenciales de retiro, la cantidad, la firma y el índice.
Fundamentalmente, el contrato no verifica la firma BLS, no confirma que el validador sea elegible para activarse y no comprueba si las credenciales de retiro apuntan a una dirección legítima o a una clave de retiro BLS válida. Esas comprobaciones ocurren más tarde, fuera de la cadena, en el software del cliente de la cadena de balizas. Esta separación es intencionada: la verificación de firmas es costosa y corresponde a la capa de consenso, mientras que el contrato de la capa de ejecución solo garantiza la integridad de los datos y la emisión de eventos.
- Aplicado on-chain: granularidad de 1 ETH, coincidencia de la raíz de datos de depósito, consistencia de la cantidad.
- No aplicado on-chain: validez de la firma BLS, elegibilidad para la activación del validador, propiedad de las credenciales de retiro.
- Emitido por depósito: clave pública, credenciales de retiro, cantidad, firma, índice de Merkle.
Formato de los datos de depósito y la raíz de Merkle
Un depósito se define por cuatro campos: pubkey (48 bytes), withdrawal_credentials (32 bytes), signature (96 bytes) y amount (8 bytes, little-endian, en Gwei). La raíz de datos de depósito es la raíz del árbol de hash SHA-256 de estos campos, calculada con las mismas reglas de contenedor SSZ que se usan en toda la capa de consenso. El contrato recalcula esta raíz a partir de los datos de llamada y la compara con el argumento deposit_data_root; una discrepancia revierte la transacción.
El contrato también mantiene un árbol de Merkle de todos los depósitos. Cada nuevo depósito se inserta en el siguiente índice, y el contrato almacena la rama necesaria para reconstruir la raíz. Los nodos de baliza leen los registros de DepositEvent y el contador de depósitos para reconstruir la lista completa de depósitos. Este diseño implica que un depósito solo es útil para la capa de consenso si tanto el evento como el estado de Merkle son consistentes, por lo que la verificación debe comprobar el registro de eventos y el contador de depósitos juntos en lugar de limitarse al recibo de la transacción.
Requisitos previos para un flujo de verificación
Para seguir el procedimiento a continuación, necesita un endpoint JSON-RPC de Ethereum que admita eth_getLogs, eth_call y eth_getTransactionReceipt. Los endpoints públicos a menudo limitan la tasa de consultas de registros, así que para verificaciones repetidas use un endpoint gestionado de la guía de endpoints RPC multicadena o aprovisione un nodo dedicado si necesita un rendimiento predecible. También necesita el hash de la transacción de depósito y la dirección del contrato de depósito de la red que está inspeccionando.
La dirección del contrato de depósito es específica de cada red. La red principal y las redes de prueba usan despliegues diferentes, así que confirme siempre la dirección con la configuración oficial de la red antes de consultar. No codifique de forma fija una dirección de un tutorial sin comprobarla con la cadena que está usando realmente. Los ejemplos siguientes usan RPC_URL y DEPOSIT_CONTRACT_ADDRESS como marcadores de posición; sustituya los valores que haya verificado de forma independiente.
- Un endpoint RPC con soporte para registros y llamadas.
- El hash de la transacción de depósito.
- La dirección verificada del contrato de depósito para la red de destino.
- Opcional: una biblioteca local de SSZ o de raíz de árbol de hash para recalcular la raíz de forma independiente.
Verificar un depósito con curl y JSON-RPC
La primera comprobación es el recibo de la transacción. Una transacción de depósito exitosa tiene estado 0x1 y contiene al menos un registro emitido por el contrato de depósito. La siguiente solicitud recupera el recibo y confirma que el contrato emitió un evento. Reemplace los marcadores de posición con sus valores.
Una transacción revertida devuelve el estado 0x0 y ningún evento de depósito. Si el recibo falta por completo, la transacción puede seguir pendiente o el nodo RPC puede no haberla indexado todavía. En ese caso, vuelva a intentarlo con un endpoint diferente antes de concluir que el depósito falló.
curl -s -X POST "$RPC_URL" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_getTransactionReceipt",
"params": ["0xYOUR_TX_HASH"]
}'Leer el registro DepositEvent en JavaScript
El recibo por sí solo no demuestra que los datos de depósito estuvieran bien formados; solo demuestra que la transacción se realizó correctamente. Para inspeccionar la carga útil del depósito, decodifique el registro DepositEvent. La firma del evento es DepositEvent(bytes,bytes,bytes,bytes,bytes), y los cinco campos de datos son la clave pública, las credenciales de retiro, la cantidad, la firma y el índice. El siguiente ejemplo usa ethers para obtener y decodificar el registro. Imprime los campos para que pueda compararlos con el archivo de datos de depósito generado por su herramienta de staking.
Ejecute esto con el mismo hash de transacción usado anteriormente. Si la clave pública decodificada no coincide con la clave del validador que pretendía depositar, deténgase e investigue antes de asumir que el depósito es válido. Una discrepancia suele indicar que se envió el archivo de datos de depósito incorrecto.
import { JsonRpcProvider, Interface } from "ethers";
const provider = new JsonRpcProvider(process.env.RPC_URL);
const depositContract = process.env.DEPOSIT_CONTRACT_ADDRESS;
const txHash = process.env.DEPOSIT_TX_HASH;
const iface = new Interface([
"event DepositEvent(bytes pubkey, bytes withdrawal_credentials, bytes amount, bytes signature, bytes index)"
]);
const receipt = await provider.getTransactionReceipt(txHash);
if (!receipt || receipt.status !== 1) {
throw new Error("Deposit transaction did not succeed");
}
for (const log of receipt.logs) {
if (log.address.toLowerCase() !== depositContract.toLowerCase()) continue;
const parsed = iface.parseLog(log);
console.log({
pubkey: parsed.args.pubkey,
withdrawalCredentials: parsed.args.withdrawal_credentials,
amountGwei: parsed.args.amount,
signature: parsed.args.signature,
index: parsed.args.index
});
}Verificación cruzada del contador de depósitos y el estado de Merkle
El contrato de depósito expone una función get_deposit_count() que devuelve el número de depósitos registrados hasta el momento, codificado como un arreglo de bytes little-endian. Leerlo confirma que el estado del contrato avanzó después de su transacción. La siguiente eth_call recupera los datos de retorno sin procesar; decodifíquelos como un entero little-endian para obtener el contador.
Compare el contador antes y después de la transacción si necesita una evidencia más sólida. Un depósito que emitió un evento pero no incrementó el contador indicaría una inconsistencia del RPC o una reorganización, no un depósito válido. Para operaciones de alto valor, consulte dos endpoints independientes y compare los resultados antes de dar el depósito por definitivo.
curl -s -X POST "$RPC_URL" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_call",
"params": [{
"to": "'"$DEPOSIT_CONTRACT_ADDRESS"'",
"data": "0x621fd130"
}, "latest"]
}'Resultado esperado de la verificación
Un depósito enviado correctamente produce un recibo con estado 0x1, exactamente un DepositEvent del contrato de depósito, una clave pública decodificada que coincide con su clave de validador, una cantidad que es un múltiplo entero de 1 ETH y un contador de depósitos que aumentó en uno. Las credenciales de retiro deben coincidir con el formato que pretendía: ya sea un prefijo 0x00 para credenciales de retiro BLS o un prefijo 0x01 o 0x02 para direcciones de retiro de la capa de ejecución.
Si todo esto se cumple, la parte de la capa de ejecución del depósito está completa. No necesariamente el validador se activará de inmediato; la activación depende de la cola de depósitos de la cadena de balizas, la posición del validador y las condiciones de la red. La verificación del evento del contrato de depósito es una condición necesaria pero no suficiente para la activación.
- El estado del recibo es
0x1. - Un
DepositEventde la dirección del contrato esperada. - La pubkey decodificada coincide con la clave del validador prevista.
- La cantidad es un múltiplo entero de 1 ETH y coincide con los datos de depósito.
- El contador de depósitos aumentó en uno.
Solución de problemas comunes en los depósitos
La mayoría de los fallos en los depósitos se engloban en unas pocas categorías. Una transacción revertida con una discrepancia de raíz suele significar que la raíz de datos de depósito se calculó incorrectamente o que el archivo de datos de depósito se editó después de generar la raíz. Una transacción revertida con un error de cantidad significa que el valor de ETH enviado no era un múltiplo entero de 1 ETH o no coincidía con la cantidad codificada en los datos de depósito. Una transacción exitosa con una clave pública inesperada suele indicar que se usó el archivo de datos de depósito incorrecto.
Un depósito que se realiza correctamente on-chain pero nunca se activa es una clase de problema diferente. Las causas comunes incluyen una firma BLS inválida, credenciales de retiro que no corresponden a una clave que usted controle, o un validador que ya fue depositado con la misma clave. Estos problemas se diagnostican en la capa de consenso, no leyendo el contrato de depósito. Use herramientas del nodo de baliza o los comandos de verificación de depósitos de un cliente validador para investigar.
- Discrepancia de raíz: regenere los datos de depósito y recalcule la raíz.
- Discrepancia de cantidad: confirme la granularidad de 1 ETH y la cantidad codificada.
- Pubkey incorrecta: verifique el archivo de datos de depósito con la clave del validador.
- Sin activación: compruebe la firma BLS y las credenciales de retiro fuera de la cadena.
Limitaciones y compensaciones
El minimalismo del contrato de depósito es una característica, pero traslada la responsabilidad al depositante. Dado que el contrato no verifica las firmas, un depósito con una firma inválida seguirá teniendo éxito on-chain y consumirá ETH, pero el validador nunca se activará. No existe una vía de reembolso on-chain para tales errores. Por eso las herramientas de staking generan y verifican los datos de depósito localmente antes de transmitirlos.
La verificación mediante JSON-RPC también tiene límites. Las consultas de registros pueden estar limitadas en tasa, podadas o servidas por nodos que están por detrás de la cabeza de la cadena. Un recibo de un nodo retrasado puede faltar o ser inconsistente. Para flujos de producción, use endpoints con garantías de consistencia documentadas y considere consultar más de un proveedor. La página de precios de RPC y la descripción general del servicio de API describen opciones de acceso gestionado, mientras que el directorio de redes ayuda a confirmar qué redes son compatibles.
Próximos pasos para la verificación de depósitos a escala
Si verifica depósitos ocasionalmente, los ejemplos de curl y JavaScript anteriores son suficientes. Si opera un servicio de staking o monitorea muchos validadores, cree un pequeño servicio de verificación que obtenga recibos, decodifique eventos y los compare con sus registros internos de depósitos. Almacene el hash de la transacción, el índice de depósito y la clave pública decodificada juntos para que las auditorías posteriores no dependan de volver a consultar registros históricos.
Para los equipos que necesitan un rendimiento RPC predecible durante las ventanas de depósito, revise la guía de alojamiento de nodos blockchain y considere infraestructura dedicada. Para la selección de endpoints en concreto, el Asistente RPC puede recomendar proveedores según sus requisitos de red y latencia; este artículo evita deliberadamente nombrar un único proveedor porque la elección correcta depende de su volumen de verificación y sus necesidades de consistencia.
- Persista el índice de depósito y la pubkey decodificada junto con el hash de la transacción.
- Consulte dos endpoints independientes para depósitos de alto valor.
- Monitoree los cambios en el contador de depósitos como señal de consistencia.
- Use nodos dedicados cuando el volumen de verificación supere los límites de tasa públicos.