Декодирование свопов SCW

С умными кошельками на основе смарт-контрактов (SCW) обмены проходят по совсем другому пути, чем с традиционными кошельками Ethereum/EVM. Эта разница может сбивать с толку, особенно когда что-то идет не так. Но как только вы поймете ключевых участников процесса — и научитесь по шагам читать, что произошло в приложении и на обозревателе блокчейна — всё станет более понятным.

Давайте пройдемся по этому вместе.


От одного нажатия до исполнения в цепочке: что происходит на самом деле

Когда вы нажимаете «Обмен» в приложении, кажется, что это одно действие. На самом деле вы запускаете многоуровневый процесс, построенный поверх абстракции аккаунтов Ethereum (ERC-4337). Ваша транзакция не отправляется напрямую в блокчейн, как при обычном кошельке. Вместо этого она делает обходной путь:

  1. Мы строим маршрут. Мы просим маршрутизатор (например, 1inch) найти лучший путь для вашего обмена и симулируем его, чтобы убедиться, что он работает. Мы оцениваем газ, проверяем, что у вас есть токены, и упаковываем инструкции в специальный формат: UserOperation.

  2. A bundler вступает в дело. Это участник вне цепочки, отвечающий за отправку UserOperations в блокчейн. Он проверяет вашу операцию, убеждается в её корректности и предоплачивает газ за вас (позже ему возмещают).

  3. Ваша UserOp попадает в блокчейн через EntryPoint смарт-контракт. Думайте об EntryPoint как о едином входе, через который проходят все транзакции SCW. EntryPoint выполняет окончательные проверки, и если всё в порядке…

  4. EntryPoint приказывает вашему смарт-контрактному кошельку (SCW) выполнить обмен. Ваш SCW вызывает маршрутизатор (например, 1inch), маршрутизатор обращается к пулу(ам), токены перемещаются, и результирующие токены попадают обратно в ваш кошелек.

Итак, в итоге: вы нажали обмен → мы симулировали → bundler отправил → EntryPoint проверил → ваш SCW выполнил.


Давайте посмотрим на реальный пример

Теперь, когда мы понимаем общий поток, давайте посмотрим, как это выглядит на реальном обмене: сначала в приложении, затем в цепочке:

Вот что мы видим:

  • Мы обменяли 1 USDC на 0.765 KTA.

  • Обмен был выполнен на Base (обратите внимание на иконку Base рядом с символами монет).

  • Мы заплатили:

    • $0.03 за газ (в ETH)

    • 0.22% комиссия за обмен в пользу goodcryptoX

    • 0.05% комиссия маршрутизатора в пользу 1inch

  • Маршрут был простой: 100% через пул Uniswap v4.

  • Bundler: Alchemy (см. Шаг 2 выше для краткого напоминания)

  • Ссылки обозревателя появляются, если транзакция дошла до блокчейна и была записана в блок (даже если она провалилась)

Пока всё выглядит хорошо. Далее давайте кликнем ссылку BaseScan, чтобы посмотреть, как эта транзакция выглядит в цепочке:

Примечание о ссылках обозревателя: В последних версиях приложения ссылки обозревателя уже открывают вашу AA-транзакцию (UserOp). Если вы видите это (поле "From" показывает адрес вашего кошелька), вы можете перейти прямо к Шаг 5 – страница с деталями AA-транзакции. Ранние шаги применимы только если ваша ссылка указывает на внешнюю транзакцию бандлера (где "From" НЕ ваш кошелёк). Тем не менее, это по‑прежнему полезное чтение, чтобы лучше понять, как работают транзакции SCW

От: это не ваш кошелек — это bundler Alchemy. Это ожидаемо, поскольку bundler отправил транзакцию.

Кому: EntryPoint (v0.6.0). Опять же, ожидаемо — все транзакции SCW проходят через него.

Внутренние транзакции: показывает потоки нативных токенов (ETH на Base) внутри транзакции. Вот что мы видим:

  • Наш кошелек (…0A5) отправил ETH в EntryPoint для оплаты газа.

  • EntryPoint возместил bundler фактическую стоимость газа (поскольку bundler предоплатил газ от вашего имени; см. Шаг 2 выше). Любой оставшийся ETH остался в EntryPoint как ваш депозит для будущих транзакций.

ERC-20 переводы: показывает фактические перемещения токенов:

Наш кошелек не отправлял USDC напрямую. Вместо этого контракт токена USDC (…2A8) обработал и осуществил переводы. Это нормально: в EVM-сетях переводы токенов обрабатываются самим контрактом токена после получения инструкции от вашего смарт-контрактного кошелька.

  1. Контракт USDC разделил наш 1 USDC на три перевода:

    • 0.0022 USDC на кошелек комиссии нашего протокола (…608A)

    • 0.0005 USDC на кошелек комиссии 1inch (…1DE5)

    • Оставшиеся 0.9973 USDC к роутеру Uniswap v4 (…Universal Router)

  2. Роутер Uniswap v4 передал их менеджеру пулов Uniswap v4 (единый контракт, обслуживающий все v4 пулы).

  3. Менеджер пулов выполнил обмен: USDC вход → KTA выход.

  4. KTA был пропущен обратно через Aggregation Router 1inch, который направил его в наш кошелек (…0A5).


🧩 Как расшифровать неудачную SCW транзакцию

Теперь, когда мы понимаем, как работают обмены с смарт-контрактными кошельками (SCW) — и прошли успешную сделку — давайте применим те же инструменты, чтобы расшифровать неудачную.

Мы рассмотрим другой реальный случай: обмен ETH → токен на Ethereum, который провалился внутри контракта EntryPoint из‑за того, что не хватило ETH, чтобы покрыть и обмен, и комиссию за газ.

Итак, вы видите «Ошибка» как статус вашего обмена в приложении или получаете push-уведомление о неудаче. Что делать?


Шаг 1 — Проверьте детали заказа в goodcryptoX

Вот что вы видите в этом случае:

Используя разработанную ранее структуру, вы быстро замечаете:

  • Статус обмена — Ошибка (неудачно?)

  • Сообщение об ошибке не показано (это необычно)

  • Есть комиссия за газ (дошло до блокчейна?)

  • Показан маршрут (симуляция прошла успешно?)

  • Есть ссылки на блокчейн-обозреватели (я могу проверить TX в блокчейне!).

Проверим вашу интуицию:

  • Поле Ошибка статус означает, что обмен не удался

  • Должно быть и удобочитаемое сообщение об ошибке (переведённое из сырого), и сырое сообщение. Отсутствие сообщения об ошибке однозначно указывает на то, что произошло что-то необычное

  • Наличие комиссии за газ действительно означает, что транзакция дошла до блокчейна и произошла некоторая он-чейн активность (которая потребила газ)

  • Маршрут подтверждает, что симуляция прошла и выявила явный путь исполнения

  • Ссылки обозревателя подтверждают, что транзакция достигла блокчейна — даже если она провалилась. Обязательно откроем одну из них и исследуем дальше


Шаг 2 – Откройте транзакцию в блокчейн-обозревателе

Примечание о ссылках обозревателя: В последних версиях приложения ссылки обозревателя уже открывают вашу AA-транзакцию (UserOp). Если вы видите это (поле "From" показывает адрес вашего кошелька), вы можете перейти прямо к Шаг 5 – страница с деталями AA-транзакции. Ранние шаги применимы только если ваша ссылка указывает на внешнюю транзакцию бандлера (где "From" НЕ ваш кошелёк). Тем не менее, это по‑прежнему полезное чтение, чтобы лучше понять, как работают транзакции SCW

Вы нажимаете ссылку Etherscan, чтобы увидеть, что произошло:

С первого взгляда всё становится ещё более запутанным:

  • Статус показывает ✅ Успех — подождите, что?!

  • Но мы уже знаем, что обмен не прошёл

  • Под полем «Кому» (EntryPoint) есть небольшое желтое сообщение:

    Хотя одна или несколько ошибок произошли [execution reverted] Выполнение контракта завершено

Так что же на самом деле происходит?

Вспомните поток транзакций SCW, который мы рассмотрели ранее:

  • bundler упаковывает ваш обмен в UserOperation (пакет данных с логикой вашего обмена)

  • затем отправляет его в смарт‑контракт EntryPoint

  • EntryPoint валидирует его (проверяя ваш баланс, подпись и nonce)

  • если всё в порядке, он выполняет ваше намерение — вызывает роутеры, пулы и перемещает токены.

С точки зрения блокчейна всё это выглядит просто как «bundler отправил данные в EntryPoint».

В терминах SCW этот шаг называется внешней транзакцией.

И эта транзакция действительно завершилась успешно: данные были доставлены, и EntryPoint начал выполнять свою внутреннюю логику. Отсюда ✅ Успех вверху.


Но обозреватель, будучи вежливым, всё же сообщает, что внутри EntryPoint что‑то не сработало с помощью той маленькой желтой заметки. Для обозревателя это внутренняя ошибка недостаточна, чтобы пометить всю транзакцию как провалившуюся.

Теперь на вкладке Overview бросается в глаза ещё одна деталь:

  • Примерно $6 стоимости ETH было отправлено из вашего кошелька в EntryPoint (предоплата газа).

  • Только $2.3 стоимости ETH было возмещено bundler.

  • А показанная сверху комиссия за транзакцию ещё ниже — примерно $2.15.

На первый взгляд эти числа не сходятся. Давайте разберём это сначала, прежде чем продолжить расследование


Шаг 3 – Понимание расхождения по газу

Вот разбор:

  • SCW → EntryPoint (~$6): Это предоплата газа. EntryPoint всегда собирает чуть больше, чем нужно, чтобы гарантировать выполнение вашей UserOp.

  • EntryPoint → Bundler (~$2.3): Это фактическое возмещение газа. Это реальная сумма, которую вы заплатили за эту неудачную попытку.

  • Комиссия за транзакцию (~$2.15): Это то, что bundler потратил, чтобы отправить вашу UserOp в EntryPoint. Она ниже, потому что сам EntryPoint использовал дополнительный газ при валидации и возмещении bundler — эту дополнительную стоимость заплатили вы.

Правило простое:

👉 Ваша истинная стоимость газа всегда равна возмещению EntryPoint ➜ Bundler (а не «Комиссии за транзакцию», показанной вверху)

А разница между тем, что вы предоплатили (~$6), и тем, что было возмещено (~$2.3), не исчезла. Она осталась в EntryPoint как ваш депозит, который автоматически будет применён к вашей следующей транзакции.


Шаг 4 – Проверьте вкладку AA Transactions

В обозревателе вы видите вкладку AA Transactions (AA = Account Abstraction). Здесь отображается активность смарт-контрактных кошельков, поскольку SCW работают на Account Abstraction (ERC-4337).

Давайте переключимся на эту вкладку из Overview:

Здесь вы наконец видите нашу UserOperation, перечисленную как отдельную запись внутри внешней транзакции bundler:

  • Поле "От" теперь показывает адрес нашего кошелька— подтверждая, что это наша операция.

  • У каждой такой записи есть отдельный AA Txn Hash, отличный от хэша внешней транзакции. Почему?

    • Внешний Txn Hash принадлежит транзакции Bundler->EntryPoint, которая содержала вашу UserOp (и могла включать несколько UserOp от разных пользователей).

    • AA Txn Hash — это уникальный идентификатор для вашей UserOperation внутри этого пакета.

Это ключевая идея пакетирования:

  • Bundler может упаковать вместе много UserOp в одну транзакцию.

  • Каждой UserOp присваивается свой AA Txn Hash, чтобы её можно было отслеживать отдельно внутри пакета.

  • В нашем случае, поскольку это старая транзакция (более 400 дней назад), SCW всё ещё были редкостью и пакет содержал только нашу UserOp — поэтому вкладка показывает «AA Transactions (1)». В более новых транзакциях вы часто увидите несколько UserOp, сгруппированных в одном пакете.

В этом представлении вы также заметите (!) значок рядом с вашим AA Txn Hash — подтверждение того, что ваш обмен не выполнился.

Следующий шаг — кликнуть AA Txn Hash. Это откроет отдельную страницу UserOperation, где вы увидите полные детали нашей попытки обмена — комиссию, переводы и место, где всё провалилось.


Шаг 5 – Откройте страницу с деталями AA Transaction

Клик по AA Txn Hash переводит вас на отдельную страницу с подробностями вашей UserOperation:

Здесь вы наконец увидите нашу реальную попытку обмена, ясно изложенную:

  • Статус: x Неудача (на этот раз без двусмысленности)

  • От: адрес вашего смарт-контрактного кошелька

  • Комиссия AA Transaction: ~0.00231 ETH ($2.31). Это реальная стоимость газа, которую вы заплатили — возмещение, отправленное bundler.

  • Внутренняя транзакция: один перевод ~0.00145 ETH (~$6.36) от вашего SCW в EntryPoint (предоплата газа). Других переводов не было, что подтверждает, что сам обмен не был выполнен.

  • Bundle Txn Hash: также показан, с ссылкой на внешнюю транзакцию bundler.

Эта страница наконец соответствует вашей интуиции: это реальная транзакция — UserOperation, которая представляла вашу попытку обмена.

Это почти завершает наше расследование. Но раз уж мы зашли так далеко, давайте также кликнем Internal Txns.


Шаг 6 – Проверьте вкладку Internal Transactions

Переключитесь на вкладку Internal Txns внутри представления AA Transaction:

Здесь вы видите поэтапные действия, которые EntryPoint пытался выполнить от вашего имени:

  1. ✅ Перевод от вашего SCW → EntryPoint (~0.00145 ETH, ~$6.36) = предоплата газа. Это успешно.

  2. ❌ Выполнение от вашего SCW → Uniswap Universal Router (~0.002 ETH) = попытка обмена. Это не удалось.

Этот разбор объясняет причину сбоя:

  • Вы успешно отправили ETH в EntryPoint как предоплату газа.

  • Но когда EntryPoint попытался переслать ETH в Uniswap для обмена, попытка провалилась.

Для наиболее подробного разбора откройте вкладку Logs.


Шаг 7 – Просмотрите вкладку Logs

Нажмите на Logs (3):

Здесь вы найдете три ключевых события:

  • Deposited → подтверждает, что ваша предоплата газа была получена EntryPoint.

  • BeforeExecution → показывает, что EntryPoint начал обрабатывать вашу UserOperation.

  • UserOperationEvent success: False — каноническая он-чейн запись о том, что ваша UserOp провалилась.


Что на самом деле произошло (сводка)

Этот тип ошибки характерен для обменов с SCW на EVM, где входной монетой является нативный токен (ETH, BNB, MATIC…).

  • Разрыв в логике: ни bundler, ни EntryPoint не проверяют, достаточно ли у вас именно нативного токена чтобы покрыть одновременно и предоплату газа, и сам обмен. Они проверяют это по отдельности — «достаточно ли для газа?» и «достаточно ли для обмена?». Именно поэтому симуляция прошла успешно.

  • Мы встроили в приложение предохранитель для таких случаев и предупредили вас в интерфейсе, что газа может не хватить. Но поскольку симуляция выглядела хорошо, вы могли всё равно подтвердить действие.

  • После вашего подтверждения bundler отправил вашу UserOperation в EntryPoint.

  • EntryPoint забрал примерно $6 в ETH как предоплату.

  • Когда он попытался выполнить обмен, не осталось достаточно ETH, чтобы одновременно покрыть и обмен и предоплату.

  • Вызов обмена отменился (reverted) внутри EntryPoint.

  • Вы всё равно заплатили примерно $2.3 за газ (возмещение bundler).

  • Неиспользованные ~ $3.7 остались в EntryPoint как ваш депозит, который будет автоматически использован при следующей вашей транзакции.

Последнее обновление