EOF в Ethereum: новый формат объектов EVM (EIP-3540 и связанные изменения)

EOF (EVM Object Format) — это новый структурированный формат байткода EVM, предложенный в EIP-3540. Он отделяет код от данных, вводит заголовок и секции и позволяет один раз валидировать контракт при деплое, а не анализировать его каждый раз при исполнении.

EOF задуман как «контейнер» для байткода с версионированием. Это даёт возможность постепенно эволюционировать EVM (менять правила, добавлять опкоды и проверки), не ломая старые контракты.

EOF в Ethereum: новый формат объектов EVM (EIP-3540 и связанные изменения)

Зачем вообще менять формат байткода EVM

Сейчас (в «легаси»-формате) байткод контракта в Ethereum:

  • представляет собой сырой поток байтов без структуры — код и данные перемешаны;
  • клиент при каждом выполнении вынужден анализировать байткод: искать допустимые точки перехода (JUMPDEST), следить за корректностью PUSH-инструкций и т.д.;
  • сложнее делать статический анализ и формальную верификацию — нет явного разделения кода/данных, нет метаданных о функциях.

EOF решает эти проблемы:

  • добавляет заголовок и секции, чтобы клиент понимал, где находится код и где данные;
  • позволяет один раз провалидировать объект при создании контракта;
  • создаёт базу для дальнейших изменений EVM без хака с «запретом отдельных опкодов» и ручных проверок.

Как устроен формат EOF (EIP-3540)

EIP-3540 описывает первую версию формата EOF v1. В общих чертах структура такая:​

  • Заголовок EOF
    • магическое значение 0xEF00 — идентификатор, что это именно EOF-объект;
    • далее версия EOF (сейчас 0x01);
    • затем идут описания секций: их тип, количество и длина.
  • Секции (sections)
    • секции кода (code sections) — непосредственно исполняемый байткод;
    • секции данных (data sections) — константы, таблицы, другие данные, к которым код может обращаться;
    • в следующих версиях EOF предусмотрены и другие типы секций (например, для типов/метаданных).

Идея такая:

  • клиент читает заголовок, понимает версию и структуру;
  • валидирует объект (корректные длины, разрешённые опкоды, отсутствие обрезанных PUSH и т.п.);
  • только после успешной проверки контракт может быть развёрнут.

Это отличается от текущей модели, где контракт можно задеплоить с байткодом, который будет «падать» только на рантайме.

EOF как пакет EIP’ов (Mega EOF / EIP-7692)

На практике EOF — это не один EIP, а целый набор предложений, которые развивают идею структурированного байткода. Meta-EIP 7692 агрегирует их как EOF-suite:

  • EIP-3540 — *EOF v1: контейнерный формат*

Вводит заголовок, секции и разделение кода и данных.

  • EIP-3670 — *EOF Code Validation*

Валидация кода при создании EOF-контракта: запрещаются обрезанные PUSH, невалидные инструкции и т.п.

  • EIP-4200 — *Static Relative Jumps*

Новые опкоды RJUMP, RJUMPI, RJUMPV с относительными смещениями, удобные для EOF-функций и оптимизации газа.

  • EIP-4750 — *EOF Functions*

Несколько секций кода как отдельные «функции» внутри контракта плюс новые опкоды CALLF и RETF для вызовов между ними.

  • EIP-5450 — *Stack Validation*

Расширенная статическая проверка стека (нет underflow/overflow в валидном EOF-коде).

  • Дополнительно в EOF-roadmap входят EIP-6206, EIP-7480, EIP-7620, EIP-7873 и др., которые развивают идеи функций, новых инструкций вызова и транзакций создания.

Все они опираются на базовый контейнерный формат EIP-3540: без него невозможно безопасно и предсказуемо развивать EVM дальше.

Что меняется для контрактов и создания

Для разработчика ключевые эффекты EOF выглядят так:

  • Отделение кода от данных
    • данные больше не маскируются под инструкции;
    • проще читать байткод, строить CFG и анализировать безопасность;
    • исчезает необходимость дорогого анализа JUMPDEST при каждом исполнении — это делается один раз на этапе валидации.
  • Жёсткая валидация при деплое
    • EOF-контракт либо проходит все проверки (корректные инструкции, стек, секции), либо вообще не попадает в сеть;
    • это снижает класс ошибок «контракт задеплоили, но он тривиально не работает».
  • Функции уровня байткода
    • вместо «ручных» JUMP/JUMPI вводятся опкоды CALLF и RETF для переходов между функциями в секциях;
    • новые относительные прыжки (RJUMP*) упрощают компиляцию и уменьшают размер кода.
  • Ограничения на разрушение кода
    • в рамках EOF-дискуссий рассматривается модель, при которой EOF-контракты не могут быть разрушены (или это сильно ограничено), что облегчает анализ инвариантов и состояние протоколов.

Влияние EOF на безопасность и анализ

EOF делает EVM более «дружественной» к анализу:

  • статические анализаторы и формальные методы могут:
    • полагаться на корректность структуры секций;
    • проще проверять свойства кода (например, отсутствие определённых опкодов или гарантии по стеку);
  • упрощается рассуждение о контроле потока (control flow), так как переходы и функции структурированы;
  • падает риск целого класса багов на уровне байткода (обрезанные PUSH, переход в середину данных и т.п.).

Для протоколов это означает:

  • более предсказуемое поведение контрактов;
  • меньше неявной магии вокруг байткода;
  • базу для будущих изменений (например, дальнейшей «зачистки» SELFDESTRUCT и эволюции модели газа) без слома старого кода.

Статус внедрения EOF и влияние на L2

По состоянию на 2025 год EOF рассматривается как одна из ключевых частей апгрейда Pectra:

  • EOF-suite тестируется в тестовых сетях (Sepolia, Holesky и др.);
  • Solidity уже добавляет экспериментальную поддержку компиляции в EOF-формат;
  • после включения в Mainnet ожидается, что многие L2-роллапы, стремящиеся к EVM-эквивалентности, также добавят поддержку EOF.

Для разработчиков на практическом уровне это означает:

  • в переходный период будут сосуществовать легаси-байткод и EOF-контракты;
  • инструменты (компиляторы, дебаггеры, анализаторы) постепенно научатся понимать EOF-структуру;
  • в долгосрочной перспективе EOF станет базовым форматом для новых контрактов в экосистеме.

См. также

Task Runner