Presiona ESC para cerrar

EIP-4844 y Blobs en Ethereum: Guía de Almacenamiento Barato

Marzo de 2024 reescribió la economía de la capa 2 para siempre. Antes de Dencun, los rollups como Arbitrum u Optimism se gastaban los presupuestos de los equipos solo para inyectar calldata en la red principal. Los smart contracts de Ethereum grababan esa matriz de bytes en el estado global para la posteridad, obligando a cada validador a almacenarla eternamente. Esto se tragaba hasta el noventa por ciento de los costos de los usuarios de L2.

El EIP-4844 rompió este esquema al introducir las transacciones de tipo 3 y los blobs. Pero detrás de las cifras bonitas de reducción de comisiones de 10x a 50x se esconde un montón de matices de ingeniería de los que los marketers suelen olvidarse.

Cómo funciona un blob a nivel de memoria y consenso

Un blob no es simplemente un archivo enviado a la blockchain. Es una matriz de datos aislada de exactamente 131,072 bytes (128 KB) que existe en paralelo con la ejecución de la EVM. Los smart contracts en Ethereum no pueden leer el contenido de un blob dentro de una llamada CALL o STATICCALL. Solo tienen acceso a un único bytecode: el opcode especial BLOBHASH, que devuelve la versión y el hash de compromiso.

  • Tamaño del bloque: el objetivo es de 3 blobs (~384 KB), con un pico máximo de 6 blobs (~768 KB).
  • Tiempo de vida: unas 4096 épocas (aproximadamente 18 días), tras lo cual los nodos de consenso purgan los datos de sus discos.
  • Aislamiento del mempool: los blobs no corren en el execution mempool común. Tienen su propia pool a nivel de clientes de consenso (P2P blob pool), lo que protege las colas de transacciones principales de sufrir un overload.

Parámetro | Calldata clásico | Blob según EIP-4844 (Type 3)
Dónde residen los datos: En el EVM state permanente | En la p2p-pool de consenso temporal
Tiempo de retención: Para siempre | ~18 días
Acceso desde la EVM: Directo (mediante lectura de bytes) | Indirecto (solo vía hash y KZG)
Modelo de precios: Execution gas compartido | Mercado de blob gas independiente (EIP-1559)

Trucos ocultos y trampas de arquitectura del proto-danksharding

Poca gente le presta atención a cómo opera el sistema de precios del blob gas. A diferencia del gas estándar, que salta con cada mínimo movimiento en DeFi, el mercado de blobs se rige por un algoritmo de corrección independiente. Si los rollups saturan los slots por encima de los tres blobs objetivo, el precio empieza a subir de forma exponencial. Si los slots se quedan vacíos, cae al umbral mínimo. En la práctica, esto genera un escenario donde enviar un blob en horas valle cuesta fracciones microscópicas de centavo, pero en momentos de alta congestión en la red, el precio puede dispararse cientos de veces más rápido que en la execution layer.

Otro detalle sutil es la verificación criptográfica mediante compromisos KZG (Kate-Zaverucha-Goldberg). Los validadores no necesitan descargarse los 128 KB enteros para comprobar que los datos son correctos; les basta con chequear un polinomio de 48 bytes. Esto reduce los requisitos de CPU para los validadores, pero le transfiere toda la carga al ancho de banda de la red.

Dónde tirar data "incómoda" en el mundo real

La naturaleza efímera de los blobs los convierte en el contenedor ideal para información que no requiere contabilidad eterna, pero sí inmutabilidad criptográfica durante una ventana de validación corta:

  • Dumps de oráculos y métricas raw: matrices de datos intermedias firmadas por los proveedores antes de ser agregadas en el smart contract.
  • Snapshots de estado de L3 y mundos de gaming: cambios de estado delta a los que solo les basta con certificar su validez durante la última semana.
  • Logs de auditoría de backend: paquetes de transacciones o recibos que deben ser públicamente verificables, pero que pierden su valor operativo al mes.

Mandar carga útil a un blob mediante scripts de Python con web3.py exige empaquetar por separado los bytes en polinomios y generar un hash versionado con prefijo 0x01. Calcular mal el maxFeePerBlobGas al momento de enviar la transacción te garantiza que se va a quedar colgada en el mempool.

La teoría y la economía están claras, pero ¿cómo se ve trabajar con blobs a nivel de código? Usar una llamada estándar de send_transaction va a lanzar un error, ya que las transacciones de tercer tipo exigen preparar manualmente los compromisos KZG, generar las pruebas y calcular un límite de gas por separado.

Envío de una transacción Type-3 en Python

A continuación se muestra un patrón funcional para enviar un blob utilizando las bibliotecas actuales para interactuar con un nodo (Geth o Reth) compatible con el upgrade Dencun:

import os
from eth_account import Account
from web3 import Web3
w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:8545"))
key = os.environ["OPERATOR_KEY"]
acct = Account.from_key(key)
FE_COUNT, FE_PAYLOAD = 4096, 31  # 31 bytes de datos por elemento de campo
def encode_blob(data: bytes) -> bytes:
    data = len(data).to_bytes(4, "big") + data
    if len(data) > FE_COUNT * FE_PAYLOAD:
        raise ValueError("el payload no cabe en un solo blob")
    data = data.ljust(FE_COUNT * FE_PAYLOAD, b"\x00")
    # el byte más significativo de cada elemento = 0 para que el valor < módulo BLS
    return b"".join(b"\x00" + data[i:i + FE_PAYLOAD]
                    for i in range(0, len(data), FE_PAYLOAD))
blob = encode_blob(b"EXMON Infrastructure DA Payload: batch #98412")
# Precio actual del blob gas con margen para absorber picos
blob_base_fee = int(w3.provider.make_request("eth_blobBaseFee", [])["result"], 16)
base_fee = w3.eth.get_block("latest")["baseFeePerGas"]
tx = {
    "type": 3,
    "chainId": w3.eth.chain_id,
    "nonce": w3.eth.get_transaction_count(acct.address),
    "gas": 21000,
    "maxPriorityFeePerGas": w3.to_wei(1, "gwei"),
    "maxFeePerGas": base_fee * 2 + w3.to_wei(1, "gwei"),
    "maxFeePerBlobGas": max(blob_base_fee * 2, w3.to_wei(1, "gwei")),
    "to": acct.address,  # no es creación de contrato: `to` es obligatorio en blob-tx
    "value": 0,
    "data": b"",
}
# ckzg calcula el compromiso, las pruebas y el versioned hash; el sidecar se inyecta en la raw tx
signed = Account.sign_transaction(tx, key, blobs=[blob])
tx_hash = w3.eth.send_raw_transaction(signed.raw_transaction)
print(f"Blob-tx enviada: {tx_hash.to_0x_hex()}")

Si no contemplas la volatilidad del maxFeePerBlobGas, en momentos de alta congestión de los rollups tu transacción se va a quedar colgada en el mempool de consenso hasta que el mercado se enfríe.

El problema de los nodos de archivo: a dónde van a parar los datos tras 18 días

La trampa principal al diseñar una arquitectura basada en blobs tiene que ver con su eliminación. Los clientes de consenso almacenan los cuerpos de los blobs durante al menos 4096 épocas (unos 18 días), tras lo cual los borran. La transacción en sí y el compromiso KZG se quedan en la blockchain para siempre, pero recuperar el contenido del blob a partir de ellos es imposible. Si un mes después necesitas consultar los datos del blob, un nodo estándar te devolverá un error.

Los equipos que construyen productos sobre EIP-4844 se ven obligados a resolver este problema de una de estas tres formas:

  • Scrapers de archivo propios: desplegar servicios en segundo plano que descarguen los blobs de la red P2P en el instante en que aparecen y los guarden en almacenamiento frío (buckets compatibles con S3).
  • Archivos descentralizados: usar redes como Celestia, Avail o The Graph para el almacenamiento a largo plazo de Data Availability.
  • Renunciar al histórico profundo: almacenar índices locales únicamente para la ventana activa de dos semanas, descartando los agregados antiguos en formato comprimido.

La práctica de EXMON: optimización del almacenamiento

En la infraestructura de EXMON utilizamos espacios de blobs temporales para descargar los logs de transacciones intermedios pesados, dumps de servicio y snapshots de verificación.

Esto nos permite resolver dos frentes al mismo tiempo:

  • Ahorro de presupuesto: los costos de publicación de datos se redujeron drásticamente en comparación con los métodos antiguos mediante calldata.
  • Limpieza de la blockchain: el estado global de la red no se satura con basura que pierde vigencia en cuestión de una semana, manteniendo al mismo tiempo una verificabilidad criptográfica del 100 % en el intervalo del ciclo de vida de los datos.
Resumir esta publicación de blog con:

FAQ

EIP-4844 introduce el proto-danksharding mediante transacciones de tipo 3 que transportan contenedores temporales de 128 KB llamados blobs, evitando saturar el estado persistente de la EVM. Estos datos se procesan exclusivamente en la capa de consenso P2P y se validan mediante compromisos KZG sin acceso directo de ejecución desde los contratos inteligentes.

Los nodos de consenso de Ethereum retienen los datos de los blobs durante exactamente 4096 épocas, lo que equivale a unos 18 días, antes de eliminarlos permanentemente de sus discos locales. Debido a esta purga automática, recuperar datos históricos sin procesar después de ese período requiere indexadores descentralizados externos o nodos de archivo dedicados en lugar de la capa L1 nativa.

El envío de una transacción de blob en Python requiere construir un diccionario de transacción de tipo 3 a través de web3.py con un parámetro separado maxFeePerBlobGas y un arreglo blobVersionedHashes. El payload se empaqueta en hashes de compromiso KZG, y la transacción se firma con la clave privada del operador para propagarse directamente al mempool de consenso P2P.
Astra EXMON

Astra is the official voice of EXMON and the editorial collective dedicated to bringing you the most timely and accurate information from the crypto market. Astra represents the combined expertise of our internal analysts, product managers, and blockchain engineers.

...

Escribe una opinión

Tu correo electrónico no será publicado. Los campos obligatorios están marcados *