Декодирование свопов SCW
С умными кошельками на основе смарт-контрактов (SCW) обмены проходят по совсем другому пути, чем с традиционными кошельками Ethereum/EVM. Эта разница может сбивать с толку, особенно когда что-то идет не так. Но как только вы поймете ключевых участников процесса — и научитесь по шагам читать, что произошло в приложении и на обозревателе блокчейна — всё станет более понятным.
Давайте пройдемся по этому вместе.
От одного нажатия до исполнения в цепочке: что происходит на самом деле
Когда вы нажимаете «Обмен» в приложении, кажется, что это одно действие. На самом деле вы запускаете многоуровневый процесс, построенный поверх абстракции аккаунтов Ethereum (ERC-4337). Ваша транзакция не отправляется напрямую в блокчейн, как при обычном кошельке. Вместо этого она делает обходной путь:
Мы строим маршрут. Мы просим маршрутизатор (например, 1inch) найти лучший путь для вашего обмена и симулируем его, чтобы убедиться, что он работает. Мы оцениваем газ, проверяем, что у вас есть токены, и упаковываем инструкции в специальный формат:
UserOperation.A
bundlerвступает в дело. Это участник вне цепочки, отвечающий за отправку UserOperations в блокчейн. Он проверяет вашу операцию, убеждается в её корректности и предоплачивает газ за вас (позже ему возмещают).Ваша UserOp попадает в блокчейн через
EntryPointсмарт-контракт. Думайте об EntryPoint как о едином входе, через который проходят все транзакции SCW. EntryPoint выполняет окончательные проверки, и если всё в порядке…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, чтобы посмотреть, как эта транзакция выглядит в цепочке:

От: это не ваш кошелек — это 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-сетях переводы токенов обрабатываются самим контрактом токена после получения инструкции от вашего смарт-контрактного кошелька.
Контракт USDC разделил наш 1 USDC на три перевода:
0.0022 USDC на кошелек комиссии нашего протокола (…608A)
0.0005 USDC на кошелек комиссии 1inch (…1DE5)
Оставшиеся 0.9973 USDC к роутеру Uniswap v4 (…Universal Router)
Роутер Uniswap v4 передал их менеджеру пулов Uniswap v4 (единый контракт, обслуживающий все v4 пулы).
Менеджер пулов выполнил обмен: USDC вход → KTA выход.
KTA был пропущен обратно через Aggregation Router 1inch, который направил его в наш кошелек (…0A5).
🧩 Как расшифровать неудачную SCW транзакцию
Теперь, когда мы понимаем, как работают обмены с смарт-контрактными кошельками (SCW) — и прошли успешную сделку — давайте применим те же инструменты, чтобы расшифровать неудачную.
Мы рассмотрим другой реальный случай: обмен ETH → токен на Ethereum, который провалился внутри контракта EntryPoint из‑за того, что не хватило ETH, чтобы покрыть и обмен, и комиссию за газ.
Итак, вы видите «Ошибка» как статус вашего обмена в приложении или получаете push-уведомление о неудаче. Что делать?
Шаг 1 — Проверьте детали заказа в goodcryptoX
Вот что вы видите в этом случае:

Используя разработанную ранее структуру, вы быстро замечаете:
Статус обмена —
Ошибка(неудачно?)Сообщение об ошибке не показано (это необычно)
Есть комиссия за газ (дошло до блокчейна?)
Показан маршрут (симуляция прошла успешно?)
Есть ссылки на блокчейн-обозреватели (я могу проверить TX в блокчейне!).
Проверим вашу интуицию:
Поле
Ошибкастатус означает, что обмен не удалсяДолжно быть и удобочитаемое сообщение об ошибке (переведённое из сырого), и сырое сообщение. Отсутствие сообщения об ошибке однозначно указывает на то, что произошло что-то необычное
Наличие комиссии за газ действительно означает, что транзакция дошла до блокчейна и произошла некоторая он-чейн активность (которая потребила газ)
Маршрут подтверждает, что симуляция прошла и выявила явный путь исполнения
Ссылки обозревателя подтверждают, что транзакция достигла блокчейна — даже если она провалилась. Обязательно откроем одну из них и исследуем дальше
Шаг 2 – Откройте транзакцию в блокчейн-обозревателе
Вы нажимаете ссылку 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 пытался выполнить от вашего имени:
✅ Перевод от вашего SCW → EntryPoint (~0.00145 ETH, ~$6.36) = предоплата газа. Это успешно.
❌ Выполнение от вашего 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 как ваш депозит, который будет автоматически использован при следующей вашей транзакции.
Последнее обновление