April 29

Темпография. Создание контракта методом CREATE2

Темпография

Вводные

См. транзакции:

Что из них можно извлечь?

  • В первой транзакции (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.

Вот такие пироги из будущего.

До!