Часть III · Глава 24 из 43 · London

EIP-3541: резервируем байт для будущего

Как оставить место для добавления совершенно нового формата контрактов позже, если каждый возможный первый байт кода уже является валидным опкодом? Никак — если только не сделать один байт запретным намеренно. EIP-3541 запрещает деплой нового кода, начинающегося с 0xEF, превращая этот байт в зарезервированное пространство, на котором строятся более поздние апгрейды (EOF и делегирующий дескриптор EIP-7702).

Обновлено 24 июн. 2026 г. · 8 мин
Предполагается
  • код контракта и опкоды
  • деплой контрактов

London, август 2021 года. Наряду с рынком комиссий и исправлением возвратов, London принёс изменение, которое само по себе ничего не делает — оно просто заставляет определённый деплой провалиться. Звучит бессмысленно, пока не увидишь, для чего это нужно. Ethereum хотел оставить себе пространство для внедрения совершенно нового формата кода контрактов в будущем форке — структурированного, версионированного, проверяемого заранее — вместо сегодняшнего байткода, который принимается как есть. Но добавление нового формата требует способа отличить его от старого, и это оказывается на удивление сложным. EIP-3541 — небольшой, дальновидный ход, который делает это возможным. Выведем его.

1 шаг Ни один байт не свободен

Проблема: каждый байт уже опкод

Код контракта — это просто последовательность байтов, и EVM читает их как опкоды Однобайтовые инструкции EVM. Код контракта — это сырая байтовая строка, интерпретируемая по одному опкоду за раз — 0x60 это PUSH1, 0x01 это ADD и так далее. Нет ни заголовка, ни тега типа; первый байт — это просто первая инструкция. . Чтобы внедрить новый формат, хотелось бы иметь магический префикс — первый байт, говорящий: «не читай меня как обычный байткод, я — новая вещь». Проблема в том, что каждое значение байта от 0x00 до 0xff уже что-то значит как опкод (или является определённой недействительной инструкцией), так что нет значения, которое можно объявить маркером, не будучи уже валидным кодом. Новому формату нечем заявить о себе.

контракт — это просто байты, и каждый байт уже опкод 60 PUSH1 02 arg 60 PUSH1 03 arg 01 ADD какой байт мог бы значить «это новый формат»? свободных нет — каждое значение 0x00–0xff уже опкод будущий формат кода не сможет заявить о себе
Код контракта — это сырая байтовая строка, читаемая опкод за опкодом — 60 это PUSH1, 01 это ADD. Каждый из 256 возможных первых байтов уже декодируется как некая инструкция, так что ни один не свободен, чтобы переназначить его в маркер «это новый формат».

→ Шаг 2: намеренно сделать один байт запретным.

2 шаг Резервируем 0xEF

EIP-3541: отклоняем новый код, начинающийся с 0xEF

Решение — это правило, а не механизм: начиная с London, любая попытка задеплоить новый код контракта, чей первый байт — 0xEF, проваливается — создание откатывается, и контракт не создаётся. Этот единственный запрет превращает 0xEF в зарезервированный префикс Значение байта, с которого протокол запрещает начинать новый код контракта, чтобы будущие апгрейды могли безопасно придать ему особое значение. EIP-3541 зарезервировал таким образом 0xEF. — байт, гарантированно никогда не начинающий обычный байткод, а значит свободный для будущего формата. (0xEF выбрали, потому что это был неопределённый опкод, напоминающий «EVM Format»; горстка уже задеплоенных контрактов, начинающихся с 0xEF, получает освобождение задним числом, поскольку правило блокирует только новые деплои.)

байт зарезервирован директивно: 0xEF код деплоя 0xEF… ✗ отклонено — revert код деплоя 0x60… ✓ всё в порядке — как раньше с London код нового контракта не может начинаться с 0xEF → 0xEF теперь зарезервирован — гарантированно свободен (старые контракты с 0xEF — исключение)
Начиная с London, деплой кода, начинающегося с 0xEF, отклоняется полностью, а любой другой первый байт деплоится как раньше. Это делает 0xEF зарезервированным префиксом — гарантированно свободным, — которому будущий форк может придать значение без всякого риска столкновения с настоящим байткодом.

→ Шаг 3: обналичить резервацию.

3 шаг Что это открыло

Итог: магический префикс для новых форматов

Когда 0xEF гарантированно свободен, будущий форк может безопасно объявить: «код, начинающийся с 0xEF…, — не устаревший байткод, интерпретируй его особо», с нулевым риском неверно прочитать настоящий контракт. На этом напрямую строятся две вещи. EOF EVM Object Format — структурированный, версионированный контейнер контракта (заголовок, секции кода/данных, проверяемый при деплое), начинающийся с магических байтов 0xEF00. Он полагается на то, что 3541 зарезервировал 0xEF. использует префикс 0xEF00 для своего версионированного контейнера. А ещё — связь, замыкающая петлю в этой книге, — делегирующий дескриптор EIP-7702 — это 0xef0100 ‖ address: когда 7702 присваивает коду EOA это значение, он использует зарезервированный префикс 0xEF именно для того, чтобы это значение нельзя было спутать с обычным байткодом.

теперь будущий форк может задать смысл 0xEF… 0xEF контейнер EOF 0xEF00 · versioned code EIP-7702 designator 0xef0100 · delegate pointer один зарезервированный байт — основа для EOF и делегирования 7702
Поскольку 0xEF зарезервирован, форк может однозначно определить, что значит 0xEF…: контейнер EOF (0xEF00 + версионированный код) и делегирующий дескриптор EIP-7702 (0xef0100 + адрес делегата) — оба живут за этим одним зарезервированным байтом.
04 Глубже Куда двигаться дальше