Часть III · Глава 14 из 43 · Constantinople

EIP-1014: CREATE2 — знать адрес до того, как контракт существует

Раньше адрес контракта выводился из nonce развёртывающего аккаунта — счётчика, меняющегося с каждым развёртыванием, так что предсказать, куда попадёт контракт, было невозможно. CREATE2 выводит адрес из развёртывающего, выбранной вами соли и самого кода: без nonce. Теперь можно вычислить адрес, пополнить его и раздать до того, как контракт вообще развёрнут.

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

Constantinople, февраль 2019. Среди её опкодов был один, читающийся как сноска, — второй способ создать контракт, — но он незаметно открыл контрфактические кошельки, стейт-каналы, детерминированные фабрики и во многом то, как абстракция аккаунтов назначает адреса. Проблема, которую он решает, — загадка курицы и яйца: можно ли узнать адрес контракта до того, как он развёрнут? С исходным CREATE ответ был «нет», и это «нет» блокировало целый класс архитектур. EIP-1014 — это CREATE2, и он превращает это «нет» в «да». Давайте выведем его.

1 шаг Nonce делает адрес непознаваемым

Проблема: адрес CREATE зависит от nonce

Когда контракт (или аккаунт) развёртывает другой с помощью исходного CREATE, адрес нового контракта — это keccak256(rlp(sender, nonce))[12:] — хеш того, кто его развернул, и его nonce Счётчик для каждого аккаунта: для EOA это число отправленных транзакций; для контракта — число созданных им контрактов. Увеличивается с каждым развёртыванием, так что каждый раз он разный и зависит от порядка. . Nonce — вот в чём подвох: он растёт с каждым развёртыванием, так что один и тот же развёртывающий, создавая два контракта, получает два разных, зависящих от порядка адреса. Вычислить адрес заранее нельзя, если только вы точно не знаете, сколько контрактов развёртывающий создаст до этого, — а как только контракт занял адрес, его nonce уже ушёл вперёд, так что поместить туда что-то ещё никогда нельзя.

CREATE: address = keccak(sender, nonce)[12:] деплоер nonce = 5 → 6 → 7 keccak 0x4b2…0x9f1…0xc07… nonce растёт с каждым деплоем → адрес всё время меняется адрес контракта неизвестен до деплоя а использовав его раз, на тот же адрес уже не задеплоить
CREATE выводит адрес из развёртывающего и его nonce, а nonce увеличивается с каждым развёртыванием — так что итоговый адрес постоянно меняется и не может быть известен заранее. Это также значит, что использованный однажды адрес нельзя переиспользовать.

→ Шаг 2: заменяем nonce на входные данные, которые вы контролируете.

2 шаг Выводим из своих входных данных

CREATE2: адрес из отправителя, соли и кода

CREATE2 Опкод Constantinople (0xf5), который развёртывает контракт по адресу, выведенному из развёртывающего, выбранной вызывающим соли и init-кода — детерминированно, без какой-либо зависимости от nonce. полностью отбрасывает nonce и выводит адрес из трёх вещей, которые можно решить заранее: развёртывающего, выбранной вами salt 32-байтное значение, которое развёртывающий выбирает свободно и подмешивает в вывод адреса CREATE2. Изменение соли даёт другой адрес для того же кода; фиксация соли делает адрес воспроизводимым. (соли) и init-кода (точного развёртываемого байткода). Поскольку ни одно из них не является движущимся счётчиком, одни и те же входные данные всегда дают один и тот же адрес — и, что важно, вы можете вычислить его, ничего не развёртывая.

CREATE2: без nonce — входы под вашим контролем sender 0xYou salt your choice init code the bytecode keccak 0x71c… без nonce → те же входы всегда дают тот же адрес — вычислимо заранее
CREATE2 хеширует развёртывающего, выбранную соль и init-код — nonce нигде нет. Зафиксируйте эти три параметра, и адрес тоже окажется зафиксирован, так что кто угодно может вычислить, где именно будет жить контракт, ещё до его развёртывания.
Формула
address = keccak256( 0xff 1 sender ‖ salt 2 keccak256(init_code) 3 )[12:]
  1. 1 постоянный префикс, не дающий адресам CREATE2 когда-либо столкнуться с адресами CREATE
  2. 2 развёртывающий и выбранное вами значение — оба известны заранее
  3. 3 фиксирует точный байткод; измените код — изменится и адрес
Каждый вход — это то, что вы фиксируете заранее, — так что адрес является чистой функцией, которую можно вычислить до развёртывания.

→ Шаг 3: используем адрес до того, как контракт стал реальным.

3 шаг Используем адрес заранее

Выигрыш: контрфактическое развёртывание

Вот тот ход, который делает возможным CREATE2. Вы вычисляете адрес, а затем используете его до развёртывания — раздаёте, отправляете на него ETH, обращаетесь с ним как с настоящим, — хотя контракта там ещё нет. Это counterfactual deployment Заранее вычислить CREATE2-адрес контракта и взаимодействовать с ним (пополнять, ссылаться на него) до развёртывания — а развернуть только когда понадобится. Существование контракта «контрфактично» до этого момента. (контрфактическое развёртывание). Адрес можно пополнять и на него можно ссылаться, пока он пуст; позже тот, кому это нужно, запускает CREATE2 с той же солью и init-кодом, и контракт материализуется точно по этому адресу — уже с ожидающими его средствами.

использовать адрес до того, как у него появится код 0x71c… ① вычислить кода ещё нет ② пополнить отправить 5 ETH ③ задеплоить код появляется здесь CREATE2 размещает контракт по этому точному адресу — и он уже пополнен
Вычислите адрес, пополните и раздайте его, пока он ещё пуст, а затем разверните контракт позже с той же солью и кодом — он появится точно по этому адресу, уже держа ETH, который на него отправили. Развёртывание может даже оплатить первый, кто им воспользуется.
04 Глубже Куда двигаться дальше