Часть III · Глава 36 из 43 · Cancun · Deneb

EIP-6780: обезвреживаем SELFDESTRUCT

SELFDESTRUCT мог стереть код контракта и освободить его адрес — что позволяло переразвернуть другой контракт по тому же адресу («метаморфный» контракт) и превращало «контракт может просто исчезнуть» в головную боль для всего дизайна состояния Ethereum. Полное удаление опкода сломало бы существующее, поэтому EIP-6780 его ограничивает: он по-настоящему удаляет только если контракт был создан в той же транзакции.

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

Cancun, март 2024. Две более ранние главы оставили незавязанную нить. Глава про CREATE2 предупреждала о метаморфных контрактах — размещении разного кода по одному адресу, — а сокращение возвратов уже лишило SELFDESTRUCT возврата газа. Эта глава завязывает нить. SELFDESTRUCT был одной из самых опасных инструкций EVM: единственный опкод, способный полностью стереть контракт — код исчезает, storage очищается, адрес освобождается. Эта сила открывала настоящую поверхность атаки и тихо блокировала долгосрочные планы Ethereum. EIP-6780 обезвреживает её, не ломая контракты, которые используют её легитимно. Давайте выведем это.

1 шаг Стереть и переиспользовать

Проблема: контракт мог по-настоящему исчезнуть

Исходный SELFDESTRUCT делал три радикальные вещи одновременно: удалял код контракта, очищал его storage и освобождал адрес — отправляя оставшийся баланс получателю. Освобождение адреса — опасная часть, потому что CREATE2 позволяет развернуться по выбранному адресу. Свяжите их в цепочку — и получите метаморфный контракт (metamorphic contract) Контракт, меняющий свой код по фиксированному адресу: разверните код через CREATE2, сделайте SELFDESTRUCT, чтобы освободить адрес, затем снова CREATE2 по тому же адресу с другим кодом. Ломает предположение о том, что код по адресу неизменен. : развернуть, самоуничтожиться, переразвернуть другой код по тому же адресу. Адрес, который кто-то аудировал или которому доверял, мог незаметно стать чем-то совершенно иным.

SELFDESTRUCT стирал код и освобождал адрес контракт v1 0xAddr SELFDESTRUCT код стёрт 0xAddr свободен CREATE2 контракт v2 тот же 0xAddr другой код, тот же адрес = «metamorphic» проаудированный адрес мог бы незаметно измениться а контракты могли бы просто исчезнуть из состояния
SELFDESTRUCT стирал код и storage контракта и освобождал его адрес; CREATE2 затем мог переразвернуть другой код по тому же адресу — метаморфный контракт. Адрес, который вы аудировали, мог незаметно изменить то, что он делает.

Есть вторая, более тихая цена. Опкод, способный удалить произвольное состояние одним выстрелом, — кошмар для дорожной карты к бессостоятельность (statelessness) Направление для Ethereum, где клиенты верифицируют блоки, используя компактные доказательства (свидетельства), затрагивающие только то состояние, которого касается блок, вместо хранения всего состояния. Деревья Verkle — структура, делающая это возможным. Опкод, способный удалить целые аккаунты, сильно усложняет генерацию таких доказательств и рассуждения о них. и деревьев Verkle: если любой аккаунт может подмигнуть и исчезнуть из существования, генерация свидетельств состояния и рассуждения о них сильно усложняются. «Контракт может исчезнуть» осложняло всё, что строилось на этом дальше.

→ Шаг 2: сохраняем полную силу только там, где безопасно.

2 шаг Ограничить, а не убрать

EIP-6780: полное удаление только в создающей транзакции

Инсайт в том, что единственный по-настоящему безопасный момент, чтобы полностью удалить контракт, — это когда он был только что создан и никогда не покидал транзакцию, — распространённый паттерн для одноразового помощника, развёрнутого и снесённого в рамках одного вызова. Поэтому EIP-6780 сохраняет полное поведение «удалить код + очистить storage + освободить адрес» только если контракт был создан в той же транзакции, что и SELFDESTRUCT. Во всех остальных случаях — обычном, когда долгоживущий контракт делает selfdestruct позже, — SELFDESTRUCT теперь лишь переводит баланс получателю и оставляет код и storage на месте. Контракт продолжает существовать.

полное удаление — только если создан в той же транзакции создан и уничтожен в ТОЙ ЖЕ tx ✓ полное удаление code + storage gone временные помощники всё ещё работают уничтожен в tx ПОЗЖЕ (норма) → отправляет только свой баланс code + storage STAY контракт продолжает существовать нельзя убрать совсем — контракты зависят — поэтому ограничить
После EIP-6780 SELFDESTRUCT полностью удаляет только если контракт был создан в той же транзакции (безопасные одноразовые помощники по-прежнему работают). Уничтоженный в любой более поздней транзакции — обычный случай — он просто отправляет баланс прочь и оставляет код и storage нетронутыми.

→ Шаг 3: да — и дорожной карте становится легче дышать.

3 шаг Метаморфность мертва

Выигрыш: больше никаких меняющих форму адресов

Метаморфному трюку требовалось, чтобы SELFDESTRUCT освобождал адрес между транзакциями, чтобы более поздний CREATE2 мог его занять. Теперь, когда развёрнутый контракт делает selfdestruct в более поздней транзакции, его код остаётся, а адрес остаётся занятым — так что CREATE2 не может разместить там новый код. Метаморфные контракты фактически мертвы: код по аудированному адресу больше нельзя подменить у вас из-под ног. А поскольку контракты больше не исчезают, семантика состояния становится драматически проще, устраняя препятствие на пути к бессостоятельности. Тем временем легитимный паттерн «создать и уничтожить в одной транзакции» не тронут, так что ничего реального не ломается.

метаморфный редеплой больше не работает контракт по 0xAddr SELFDESTRUCT (later) код ОСТАЁТСЯ 0xAddr occupied ✗ CREATE2 не разместит там новый код — метаморфные мертвы ✓ контракты не исчезают → проще состояние, ближе к бессостоятельности создание-и-уничтожение в одной tx всё ещё работает — легитимное не ломается
Контракт, делающий selfdestruct в более поздней транзакции, сохраняет свой код, так что его адрес остаётся занятым, и CREATE2 не может переразвернуться поверх него — метаморфные контракты мертвы. То, что контракты никогда по-настоящему не исчезают, также упрощает работу с состоянием для бессостоятельности, а помощники в рамках одной транзакции по-прежнему работают.
04 Глубже Куда двигаться дальше