Нажмите ESC, чтобы закрыть

EIP-4844 и блобы в Ethereum: как дешево хранить данные

Март 2024 года перекроил экономику второго уровня навсегда. До Dencun роллапы вроде Arbitrum или Optimism сжигали бюджеты команд на прокачку calldata в основной сети. Смарт-контракты Ethereum забивали этот массив байтов в глобальное состояние навсегда, заставляя каждого валидатора хранить его вечно. На это уходило до девяноста процентов костов пользователей L2.

EIP-4844 сломал эту схему, введя транзакции третьего типа и блобы. Но за красивыми цифрами снижения комиссий в 10–50 раз скрывается масса инженерных нюансов, о которых обычно молчат маркетологи.

Как устроен блоб на уровне памяти и консенсуса

Блоб - это не просто файл, отправленный в блокчейн. Это изолированный массив данных размером ровно 131 072 байта (128 КБ), который существует параллельно с выполнением EVM. Смарт-контракты в Ethereum не могут прочитать содержимое блоба внутри вызова CALL или STATICCALL. У них есть доступ только к одному байт-коду - специальному опкоду BLOBHASH, который возвращает версию и хэш обязательства.

  • Размер блока: целевой показатель составляет 3 блоба (~384 КБ), максимум на пике — 6 блобов (~768 КБ).
  • Срок жизни: около 4096 эпох (примерно 18 суток), после чего ноды консенсуса вычищают данные с дисков.
  • Изоляция мемпула: блобы не крутятся в обычном execution-меморипуле. У них собственный пул на уровне консенсус-клиентов (P2P blob pool), что защищает основные очереди транзакций от оверлода.

Параметр | Классический calldata | Блоб по EIP-4844 (Type 3)
Где лежат данные: В постоянном EVM state | Во временном p2p-пуле консенсуса
Время хранения: Навсегда | ~18 дней
Доступ из EVM: Прямой (через чтение байтов) | Косвенный (только через хэш и KZG)
Ценообразование: Общий execution gas | Независимый рынок blob gas (EIP-1559)

Неочевидные фишки и архитектурные ловушки proto-danksharding

Мало кто заостряет внимание на том, как работает ценообразование блоб-газа. В отличие от стандартного газа, который прыгает от каждого чиха в DeFi, рынок блобов управляется независимым алгоритмом коррекции. Если роллапы забивают слоты выше целевых трех блобов, цена начинает экспоненциально расти. Если слоты пустуют — падает до минимального порога. На практике это приводит к ситуации, когда отправка блоба в тихие часы стоит микроскопические доли цента, но в момент резкого штурма сети цена может скакнуть в сотни раз быстрее, чем в execution-слое.

Еще один тонкий момент — криптографическая проверка через KZG-обязательства (Kate-Zaverucha-Goldberg). Валидаторам не нужно выкачивать все 128 КБ, чтобы убедиться в корректности данных. Им достаточно проверить 48-байтовый полином. Это снижает требования к процессорам валидаторов, но перекладывает всю нагрузку на сетевой канал.

Куда сливать «неудобную» инфу на практике

Временная природа блобов делает их идеальным контейнером для данных, которым не нужна вечная бухгалтерия, но требуется криптографическая неизменяемость на коротком интервале валидации:

  • Дампы оракулов и сырые метрики: промежуточные массивы данных, которые подписываются провайдерами перед агрегацией в смарт-контракт.
  • Слепки состояния L3 и игровых миров: дельта-изменения состояния, которым достаточно подтвердить корректность за последнюю неделю.
  • Аудиторские логи бэкенда: пакеты транзакций или чеки, которые должны быть публично верифицируемы, но через месяц теряют операционную ценность.

Закидывать нагрузку в блоб через Python-скрипты на web3.py требует отдельной упаковки байтов в полиномы и генерации версионного хэша с префиксом 0x01. Неверный расчет maxFeePerBlobGas в момент отправки гарантирует зависание транзакции в мемпуле.

Теория и экономика понятны, но как выглядит работа с блобами на уровне кода? Использование стандартного вызова send_transaction вызовет ошибку, так как транзакции третьего типа требуют ручной подготовки KZG-коммитментов, генерации пруфов и расчета отдельного лимита газа.

Отправка Type-3 транзакции на Python

Ниже представлен рабочий паттерн отправки блоба с использованием актуальных библиотек для работы с нодой (Geth или Reth), поддерживающей апгрейд 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 байт данных на элемент поля
def encode_blob(data: bytes) -> bytes:
    data = len(data).to_bytes(4, "big") + data
    if len(data) > FE_COUNT * FE_PAYLOAD:
        raise ValueError("payload не помещается в один блоб")
    data = data.ljust(FE_COUNT * FE_PAYLOAD, b"\x00")
    # старший байт каждого элемента = 0, чтобы значение < модуля 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")
# Актуальная цена блоб-газа с запасом на рост
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,  # не контракт-создание: у blob-tx `to` обязателен
    "value": 0,
    "data": b"",
}
# ckzg считает обязательство, пруфы и versioned hash; сайдкар вшивается в raw tx
signed = Account.sign_transaction(tx, key, blobs=[blob])
tx_hash = w3.eth.send_raw_transaction(signed.raw_transaction)
print(f"Blob-tx отправлена: {tx_hash.to_0x_hex()}")

Если не учесть волатильность maxFeePerBlobGas, в моменты пиковой нагрузки роллапов транзакция зависнет в мемпуле консенсуса, пока рынок не остынет.

Проблема архивных нод: куда уходят данные через 18 дней

Главная ловушка при проектировании архитектуры на блобах связана с их удалением. Консенсус-клиенты хранят тела блобов не менее 4096 эпох (около 18 суток), после чего удаляют их. Сама транзакция и KZG-обязательство остаются в блокчейне навсегда, но восстановить содержимое блоба по ним нельзя. Если через месяц потребуется получить данные блоба, стандартная нода вернёт ошибку.

Команды, строящие продукты поверх EIP-4844, вынуждены решать эту проблему одним из трех путей:

  • Собственные архивные скупщики: развертывание фоновых сервисов, которые выкачивают блобы из P2P-сети в момент их появления и складывают в холодное хранилище (S3-совместимые бакеты).
  • Децентрализованные архивы: использование сетей вроде Celestia, Avail или The Graph для долгосрочного хранения Data Availability.
  • Отказ от глубокой истории: хранение локальных индексов только за активное двухнедельное окно, сбрасывая старые агрегаты в сжатом виде.

Практика EXMON: оптимизация хранения

В инфраструктуре EXMON мы используем временные пространства блобов для выноса тяжелых промежуточных логов транзакций, служебных дампов и верификационных слепков.

Это позволяет решать сразу две задачи:

  • Экономия бюджета: затраты на публикацию данных снизились на порядок по сравнению со старыми методами через calldata.
  • Чистота блокчейна: глобальное состояние сети не забивается мусором, который теряет актуальность уже через неделю, при этом сохраняется стопроцентная криптографическая проверяемость на интервале жизненного цикла данных.
Сделать краткую выжимку этой статьи с помощью:

FAQ

EIP-4844 реализует концепцию proto-danksharding через транзакции третьего типа, которые переносят временные контейнеры данных емкостью 128 килобайт, называемые блобами, в обход постоянного глобального состояния EVM. Данные блобов обрабатываются исключительно на уровне консенсуса P2P и проверяются с помощью KZG-обязательств без возможности прямого чтения смарт-контрактами.

Узлы консенсуса Ethereum сохраняют тела блобов ровно на 4096 эпох, что составляет примерно 18 суток, после чего данные автоматически удаляются с дисков валидаторов. Из-за этого для последующего доступа к историческим сырым байтам требуются сторонние децентрализованные индексаторы или специализированные архивные ноды, а не нативный уровень L1.

Отправка блоб-транзакции на Python требует формирования словаря транзакции третьего типа через web3.py с отдельным параметром maxFeePerBlobGas и массивом blobVersionedHashes. Полезная нагрузка упаковывается в хэш KZG-обязательства, после чего транзакция подписывается приватным ключом оператора и отправляется напрямую в мемпул консенсуса 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.

...

Поделитесь своим мнением

Ваш e-mail не будет опубликован. Обязательные поля отмечены *