EIP-6780: обезвреживаем SELFDESTRUCT
SELFDESTRUCT мог стереть код контракта и освободить его адрес — что позволяло переразвернуть другой контракт по тому же адресу («метаморфный» контракт) и превращало «контракт может просто исчезнуть» в головную боль для всего дизайна состояния Ethereum. Полное удаление опкода сломало бы существующее, поэтому EIP-6780 его ограничивает: он по-настоящему удаляет только если контракт был создан в той же транзакции.
- контракты, код и storage
- CREATE2
Cancun, март 2024. Две более ранние главы оставили незавязанную нить. Глава про CREATE2 предупреждала о метаморфных контрактах — размещении разного кода по одному адресу, — а сокращение возвратов уже лишило SELFDESTRUCT возврата газа. Эта глава завязывает нить. SELFDESTRUCT был одной из самых опасных инструкций EVM: единственный опкод, способный полностью стереть контракт — код исчезает, storage очищается, адрес освобождается. Эта сила открывала настоящую поверхность атаки и тихо блокировала долгосрочные планы Ethereum. EIP-6780 обезвреживает её, не ломая контракты, которые используют её легитимно. Давайте выведем это.
Проблема: контракт мог по-настоящему исчезнуть
Исходный SELFDESTRUCT делал три радикальные вещи одновременно: удалял код контракта, очищал его storage и освобождал адрес — отправляя оставшийся баланс получателю. Освобождение адреса — опасная часть, потому что CREATE2 позволяет развернуться по выбранному адресу. Свяжите их в цепочку — и получите метаморфный контракт (metamorphic contract) Контракт, меняющий свой код по фиксированному адресу: разверните код через CREATE2, сделайте SELFDESTRUCT, чтобы освободить адрес, затем снова CREATE2 по тому же адресу с другим кодом. Ломает предположение о том, что код по адресу неизменен. : развернуть, самоуничтожиться, переразвернуть другой код по тому же адресу. Адрес, который кто-то аудировал или которому доверял, мог незаметно стать чем-то совершенно иным.
Есть вторая, более тихая цена. Опкод, способный удалить произвольное состояние одним выстрелом, — кошмар для дорожной карты к бессостоятельность (statelessness) Направление для Ethereum, где клиенты верифицируют блоки, используя компактные доказательства (свидетельства), затрагивающие только то состояние, которого касается блок, вместо хранения всего состояния. Деревья Verkle — структура, делающая это возможным. Опкод, способный удалить целые аккаунты, сильно усложняет генерацию таких доказательств и рассуждения о них. и деревьев Verkle: если любой аккаунт может подмигнуть и исчезнуть из существования, генерация свидетельств состояния и рассуждения о них сильно усложняются. «Контракт может исчезнуть» осложняло всё, что строилось на этом дальше.
→ Шаг 2: сохраняем полную силу только там, где безопасно.
EIP-6780: полное удаление только в создающей транзакции
Инсайт в том, что единственный по-настоящему безопасный момент, чтобы полностью удалить контракт, — это когда он был только что создан и никогда не покидал транзакцию, — распространённый паттерн для одноразового помощника, развёрнутого и снесённого в рамках одного вызова. Поэтому EIP-6780 сохраняет полное поведение «удалить код + очистить storage + освободить адрес» только если контракт был создан в той же транзакции, что и SELFDESTRUCT. Во всех остальных случаях — обычном, когда долгоживущий контракт делает selfdestruct позже, — SELFDESTRUCT теперь лишь переводит баланс получателю и оставляет код и storage на месте. Контракт продолжает существовать.
→ Шаг 3: да — и дорожной карте становится легче дышать.
Выигрыш: больше никаких меняющих форму адресов
Метаморфному трюку требовалось, чтобы SELFDESTRUCT освобождал адрес между транзакциями, чтобы более поздний CREATE2 мог его занять. Теперь, когда развёрнутый контракт делает selfdestruct в более поздней транзакции, его код остаётся, а адрес остаётся занятым — так что CREATE2 не может разместить там новый код. Метаморфные контракты фактически мертвы: код по аудированному адресу больше нельзя подменить у вас из-под ног. А поскольку контракты больше не исчезают, семантика состояния становится драматически проще, устраняя препятствие на пути к бессостоятельности. Тем временем легитимный паттерн «создать и уничтожить в одной транзакции» не тронут, так что ничего реального не ломается.