Темпография. Создание контракта методом CREATE2
Вводные
- basescan.org/tx/0xd9800e0412e25f75339826615a1422704e88a6f65489e95e7f920081333e5b2f
- https://basescan.org/tx/0x075261f2afd788e62f49a04623d292da012d4b02032911cdc772b2d494b7fafe
- В первой транзакции (0xd980...5b2f) - отправка средств на адрес, который ещё не создан.
- Сам контракт на этот адрес создаётся только во второй транзакции (0x0752...7fafe).
Резонный вопрос: “Как это возможно?”. Ответ таков: Это нормально и называется "контракт по предсказуемому адресу", создаваемый через механизм CREATE2. Его и рассмотрим.
Что такое CREATE2?
Прежде всего - это способ заранее предсказать, на каком адресе будет контракт, ещё до его создания.Специальная команда в EVM (CREATE2) позволяет рассчитать адрес контракта по:
- адресу создателя (deployer),
- salt (произвольная соль),
- байт-коду контракта.
- Адрес контракта можно вычислить заранее, ещё до деплоя.
- А потом деньги или данные можно отправить на будущий адрес.
- После деплоя всё "срастается", и контракт получает доступ к этим средствам.
Как это происходит в транзакции?
Деплоер знает, что в будущем контракт будет на определённом адресе (с помощью CREATE2). На этот адрес отправляются средства или данные в транзакции 0xd980...5b2f (см. выше).
Потом через 0x0752...7fafe происходит разворачивание контракта именно на этом адресе. Контракт, появившись, сразу "видит" отправленные ранее средства.
Зачем так делают?
Для поддержки сложных архитектур: прежде всего - мультисиг-кошельков, но также для кошельков с отложенным созданием, а ещё для аукционов и прочего.
Кроме того, это повышает безопасность: пока контракт не развёрнут, атаковать его труднее.
Наконец, это в ряде случаев просто удобно: можно заранее посчитать адреса для пользователей или систем.
У всего этого дела есть даже формула:
address = keccak256( 0xff ++ deployer_address ++ salt ++ keccak256(init_code) )
- 0xff — фиксированный байт;
- deployer_address — адрес создателя;
- salt — произвольное значение;
- init_code— байт-код контракта;
- keccak256 — хэш-функция SHA-3.