Перейти к основному содержимому

EIP-7702 после Pectra: Практическое руководство для разработчиков приложений Ethereum

· 10 мин. чтения
Dora Noda
Software Engineer

7 мая 2025 года обновление Ethereum Pectra (Prague + Electra) было запущено в основной сети. Среди наиболее заметных для разработчиков изменений — EIP-7702, который позволяет внешнему аккаунту (EOA) «подключать» логику смарт-контракта без переноса средств или изменения адресов. Если вы создаете кошельки, децентрализованные приложения или ретрансляторы, это открывает более простой путь к улучшенному UX смарт-аккаунтов.

Ниже представлено краткое руководство, ориентированное на реализацию: что было фактически выпущено, как работает 7702, когда его выбрать вместо чистого ERC-4337, а также готовый шаблон, который вы можете адаптировать уже сегодня.


Что было фактически выпущено

  • EIP-7702 включен в окончательный объем Pectra. Мета-EIP для хардфорка Pectra официально включает 7702 в список изменений.
  • Детали активации: Pectra был активирован в основной сети на эпохе 364032 7 мая 2025 года после успешных активаций во всех основных тестовых сетях.
  • Примечание по инструментарию: Solidity v0.8.30 обновил свою целевую EVM по умолчанию до prague для совместимости с Pectra. Вам потребуется обновить свои компиляторы и CI-конвейеры, особенно если вы используете конкретные версии.

EIP-7702 — Как это работает (основы)

EIP-7702 вводит новый тип транзакций и механизм для EOA, позволяющий делегировать свою логику выполнения смарт-контракту.

  • Новый тип транзакций (0x04): Транзакция типа 4 включает новое поле под названием authorization_list. Этот список содержит одну или несколько кортежей авторизации — (chain_id, address, nonce, y_parity, r, s) — каждый из которых подписан приватным ключом EOA. При обработке этой транзакции протокол записывает индикатор делегирования в поле кода EOA: 0xef0100 || address. С этого момента любые вызовы EOA проксируются на указанный address ( реализация), но выполняются в контексте хранения и баланса EOA. Это делегирование остается активным до тех пор, пока оно не будет явно изменено.
  • Область действия цепочки: Авторизация может быть специфичной для цепочки путем предоставления chain_id, или она может применяться ко всем цепочкам, если chain_id установлен в 0. Это позволяет развертывать один и тот же контракт реализации в нескольких сетях, не требуя от пользователей подписывать новую авторизацию для каждой из них.
  • Отзыв: Чтобы вернуть EOA к его исходному, непрограммируемому поведению, вы просто отправляете еще одну транзакцию 7702, где address реализации устанавливается в нулевой адрес. Это очищает индикатор делегирования.
  • Самостоятельное спонсирование против ретрансляции: EOA может отправить транзакцию типа 4 самостоятельно, или сторонний ретранслятор может отправить ее от имени EOA. Последнее часто используется для создания пользовательского опыта без газа. Обработка nonce немного отличается в зависимости от метода, поэтому важно использовать библиотеки, которые правильно управляют этим различием.

Изменение модели безопасности: Поскольку оригинальный приватный ключ EOA все еще существует, он всегда может отменить любые правила смарт-контракта (например, социальное восстановление или лимиты расходов), отправив новую транзакцию 7702 для изменения делегирования. Это фундаментальное изменение. Контракты, которые полагаются на tx.origin для проверки того, что вызов исходит от EOA, должны быть повторно проверены, так как 7702 может нарушить эти предположения. Соответственно, проверьте свои рабочие процессы.


7702 или ERC-4337? (И когда их комбинировать)

И EIP-7702, и ERC-4337 обеспечивают абстракцию аккаунтов, но они служат разным целям.

  • Выбирайте EIP-7702, когда…
    • Вы хотите предоставить мгновенный UX смарт-аккаунта для существующих EOA, не заставляя пользователей переносить средства или менять адреса.
    • Вам нужны последовательные адреса в разных цепочках, которые могут быть постепенно обновлены новыми функциями.
    • Вы хотите поэтапно перейти к абстракции аккаунтов, начиная с простых функций и постепенно добавляя сложность.
  • Выбирайте чистый ERC-4337, когда…
    • Ваш продукт требует полной программируемости и сложных механизмов политик (например, мультиподпись, расширенное восстановление) с первого дня.
    • Вы создаете для новых пользователей, у которых нет существующих EOA, что делает новые адреса смарт-аккаунтов и связанную с ними настройку приемлемыми.
  • Комбинируйте их: Самый мощный паттерн — использовать оба. EOA может использовать транзакцию 7702 для назначения реализации кошелька ERC-4337 в качестве своей логики. Это заставляет EOA вести себя как аккаунт 4337, позволяя ему быть объединенным, спонсируемым пеймастерами и обрабатываемым существующей инфраструктурой 4337 — и все это без необходимости для пользователя в новом адресе. Это перспективный путь, явно поощряемый авторами EIP.

Минимальный шаблон 7702, который вы можете адаптировать

Вот практический пример контракта реализации и клиентского кода для его активации.

1. Маленький, поддающийся аудиту контракт реализации

Этот код контракта будет выполняться в контексте EOA после назначения. Держите его небольшим, поддающимся аудиту и рассмотрите возможность добавления механизма обновления.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/// @notice Executes calls from the EOA context when designated via EIP-7702.
contract DelegatedAccount {
// Unique storage slot to avoid collisions with other contracts.
bytes32 private constant INIT_SLOT =
0x3fb93b3d3dcd1d1f4b4a1a8db6f4c5d55a1b7f9ac01dfe8e53b1b0f35f0c1a01;

event Initialized(address indexed account);
event Executed(address indexed to, uint256 value, bytes data, bytes result);

modifier onlyEOA() {
// Optional: add checks to restrict who can call certain functions.
_;
}

function initialize() external payable onlyEOA {
// Set a simple one-time init flag in the EOA's storage.
bytes32 slot = INIT_SLOT;
assembly {
if iszero(iszero(sload(slot))) { revert(0, 0) } // Revert if already initialized
sstore(slot, 1)
}
emit Initialized(address(this));
}

function execute(address to, uint256 value, bytes calldata data)
external
payable
onlyEOA
returns (bytes memory result)
{
(bool ok, bytes memory ret) = to.call{value: value}(data);
require(ok, "CALL_FAILED");
emit Executed(to, value, data, ret);
return ret;
}

function executeBatch(address[] calldata to, uint256[] calldata value, bytes[] calldata data)
external
payable
onlyEOA
{
uint256 n = to.length;
require(n == value.length && n == data.length, "LENGTH_MISMATCH");
for (uint256 i = 0; i < n; i++) {
(bool ok, ) = to[i].call{value: value[i]}(data[i]);
require(ok, "CALL_FAILED");
}
}
}

2. Назначение контракта на EOA (транзакция типа 4) с помощью viem

Современные клиенты, такие как viem, имеют встроенные вспомогательные функции для подписания авторизаций и отправки транзакций типа 4. В этом примере аккаунт relayer оплачивает газ для обновления eoa.

import { createWalletClient, http, encodeFunctionData } from "viem";
import { sepolia } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
import { abi, implementationAddress } from "./DelegatedAccountABI";

// 1. Define the relayer (sponsors gas) and the EOA to be upgraded
const relayer = privateKeyToAccount(process.env.RELAYER_PK as `0x${string}`);
const eoa = privateKeyToAccount(process.env.EOA_PK as `0x${string}`);

const client = createWalletClient({
account: relayer,
chain: sepolia,
transport: http(),
});

// 2. The EOA signs the authorization pointing to the implementation contract
const authorization = await client.signAuthorization({
account: eoa,
contractAddress: implementationAddress,
// If the EOA itself were sending this, you would add: executor: 'self'
});

// 3. The relayer sends a Type-4 transaction to set the EOA's code and call initialize()
const hash = await client.sendTransaction({
to: eoa.address, // The destination is the EOA itself
authorizationList: [authorization], // The new EIP-7702 field
data: encodeFunctionData({ abi, functionName: "initialize" }),
});

// 4. Now, the EOA can be controlled via its new logic without further authorizations
// For example, to execute a transaction:
// await client.sendTransaction({
// to: eoa.address,
// data: encodeFunctionData({ abi, functionName: 'execute', args: [...] })
// });

3. Отзыв делегирования (возврат к обычному EOA)

Чтобы отменить обновление, попросите EOA подписать авторизацию, которая назначает нулевой адрес в качестве реализации, и отправить еще одну транзакцию типа 4. После этого вызов eth_getCode(eoa.address) должен вернуть пустые байты.


Паттерны интеграции, работающие в продакшене

  • Обновление на месте для существующих пользователей: В вашем децентрализованном приложении определите, находится ли пользователь в сети, совместимой с Pectra. Если да, отобразите необязательную кнопку «Обновить аккаунт», которая запускает одноразовую подпись авторизации. Поддерживайте резервные пути (например, классические approve + swap) для пользователей со старыми кошельками.
  • Бесплатное подключение (Gasless Onboarding): Используйте ретранслятор (либо ваш бэкенд, либо сервис) для спонсирования начальной транзакции типа 4. Для текущих безгазовых транзакций направляйте пользовательские операции через бандлер ERC-4337, чтобы использовать существующие пеймастеры и публичные мемпулы.
  • Развертывание между цепочками: Используйте авторизацию chain_id = 0 для назначения одного и того же контракта реализации во всех цепочках. Затем вы можете включать или отключать функции для каждой цепочки в рамках вашей прикладной логики.
  • Наблюдаемость: Ваш бэкенд должен индексировать транзакции типа 4 и анализировать authorization_list, чтобы отслеживать, какие EOA были обновлены. После транзакции проверьте изменение, вызвав eth_getCode и подтвердив, что код EOA теперь соответствует индикатору делегирования (0xef0100 || implementationAddress).

Модель угроз и подводные камни (не пропускайте это)

  • Делегирование является постоянным: Относитесь к изменениям в контракте реализации EOA с той же серьезностью, что и к стандартному обновлению смарт-контракта. Это требует аудитов, четкого информирования пользователей и, в идеале, процесса согласия. Никогда не внедряйте новую логику для пользователей без их ведома.
  • «Мины» tx.origin: Любая логика, которая использовала msg.sender == tx.origin для обеспечения того, что вызов исходил непосредственно от EOA, теперь потенциально уязвима. Этот паттерн должен быть заменен более надежными проверками, такими как подписи EIP-712 или явные списки разрешенных адресов.
  • Математика Nonce: Когда EOA спонсирует свою собственную транзакцию 7702 (executor: 'self'), его nonce авторизации и nonce транзакции взаимодействуют особым образом. Всегда используйте библиотеку, которая правильно обрабатывает это, чтобы избежать проблем с повторными воспроизведениями.
  • Ответственность UX кошелька: Спецификация EIP-7702 предупреждает, что децентрализованные приложения не должны просить пользователей подписывать произвольные назначения. Ответственность кошелька — проверять предлагаемые реализации и убеждаться в их безопасности. Разрабатывайте свой UX в соответствии с этим принципом безопасности, опосредованной кошельком.

Когда 7702 — очевидная победа

  • Потоки DEX: Многошаговые approve и swap могут быть объединены в один клик с использованием функции executeBatch.
  • Игры и сессии: Предоставляйте привилегии, подобные сессионным ключам, на ограниченное время или область действия, не требуя от пользователя создания и пополнения нового кошелька.
  • Предприятия и финтех: Включите спонсируемые транзакции и применяйте пользовательские политики расходов, сохраняя при этом один и тот же корпоративный адрес в каждой цепочке для учета и идентификации.
  • Мосты L2 и намерения: Создавайте более плавные потоки мета-транзакций с согласованной идентификацией EOA в разных сетях.

Эти варианты использования представляют те же основные преимущества, обещанные ERC-4337, но теперь они доступны каждому существующему EOA всего с одной авторизацией.


Контрольный список для запуска

Протокол

  • Убедитесь, что узлы, SDK и поставщики инфраструктуры поддерживают транзакции типа 4 и EVM "prague" от Pectra.
  • Обновите индексаторы и аналитические инструменты для анализа поля authorization_list в новых транзакциях.

Контракты

  • Разработайте минимальный, проверенный контракт реализации с основными функциями (например, пакетная обработка, отзыв).
  • Тщательно протестируйте потоки отзыва и повторного назначения в тестовых сетях перед развертыванием в основной сети.

Клиенты

  • Обновите клиентские библиотеки (viem, ethers и т. д.) и протестируйте функции signAuthorization и sendTransaction.
  • Убедитесь, что пути как для самостоятельно спонсируемых, так и для ретранслируемых транзакций правильно обрабатывают nonce и повторные воспроизведения.

Безопасность

  • Удалите все предположения, основанные на tx.origin, из ваших контрактов и замените их более безопасными альтернативами.
  • Внедрите мониторинг после развертывания для обнаружения неожиданных изменений кода по адресам пользователей и оповещения о подозрительной активности.

Итог: EIP-7702 обеспечивает легкий путь к UX смарт-аккаунтов для миллионов уже используемых EOA. Начните с небольшой, проверенной реализации, используйте ретранслируемый путь для настройки без газа, сделайте отзыв четким и простым, и вы сможете получить 90% преимуществ полной абстракции аккаунтов — без проблем с изменением адресов и миграцией активов.