Три точки, где теряется UserOperation

  • Ошибка eth_sendUserOperation означает, что bundler не принял объект в свой mempool; AA-префикс помогает найти слой отказа, но точный текст зависит от версии EntryPoint.
  • Возвращённый userOpHash подтверждает принятие после simulation этим bundler, а не включение в блок и не успех целевого действия.
  • После включения проверяют отдельный UserOperation receipt и поле success; receipt внешнего handleOps может охватывать несколько операций.
Три идентификатора одной попытки
ИдентификаторГде появляетсяЧто доказывает
userOpHashОтвет bundler после принятия объектаКонкретные поля UserOperation, EntryPoint и chain domain; не inclusion
transactionHashПосле включения bundle-транзакции handleOpsВнешняя транзакция попала в блок; внутри могут быть другие UserOperations
UserOperation receiptПосле on-chain обработки конкретной operationsender, nonce, gas, success/reason и связанные logs для данного userOpHash
Три идентификатора одной попытки
Идентификатор
userOpHash
Где появляется
Ответ bundler после принятия объекта
Что доказывает
Конкретные поля UserOperation, EntryPoint и chain domain; не inclusion
Идентификатор
transactionHash
Где появляется
После включения bundle-транзакции handleOps
Что доказывает
Внешняя транзакция попала в блок; внутри могут быть другие UserOperations
Идентификатор
UserOperation receipt
Где появляется
После on-chain обработки конкретной operation
Что доказывает
sender, nonce, gas, success/reason и связанные logs для данного userOpHash

userOpHash означает acceptance, а не перевод

Draft ERC-7769 рекомендует возвращать из eth_sendUserOperation userOpHash только после simulation и принятия объекта в локальный UserOperation pool этого bundler. До этого проверяются структура, поддерживаемый EntryPoint, account validation, paymaster и срок действия. Это диагностический слой поверх архитектуры smart account: bundler ещё может повторно проверить объект перед bundle и удалить его, если состояние изменилось.

Ошибка RPC отвечает, почему объект не приняли

Карта отказов до включения
СигналСлойЧто перепроверить
-32602Форма RPCОбязательные поля, hex encoding и согласованные factory/paymaster fields
-32500 и AAxxEntryPoint simulationПолный message, sender, nonce, signature и prefund
-32501Paymaster validationАдрес, policy, data, deposit и срок sponsorship
-32502Bundler validation rulesЗапрещённые opcode/storage patterns и supported mempool
-32503Time rangevalidAfter, validUntil и время следующего блока
-32507Wallet signatureAccount implementation, signer set и подписанный userOpHash
Карта отказов до включения
Сигнал
-32602
Слой
Форма RPC
Что перепроверить
Обязательные поля, hex encoding и согласованные factory/paymaster fields
Сигнал
-32500 и AAxx
Слой
EntryPoint simulation
Что перепроверить
Полный message, sender, nonce, signature и prefund
Сигнал
-32501
Слой
Paymaster validation
Что перепроверить
Адрес, policy, data, deposit и срок sponsorship
Сигнал
-32502
Слой
Bundler validation rules
Что перепроверить
Запрещённые opcode/storage patterns и supported mempool
Сигнал
-32503
Слой
Time range
Что перепроверить
validAfter, validUntil и время следующего блока
Сигнал
-32507
Слой
Wallet signature
Что перепроверить
Account implementation, signer set и подписанный userOpHash

AA-префикс локализует класс: AA1 относится к созданию sender, AA2 — к account validation, AA3 — к paymaster validation. Но полный номер и текст нельзя переносить между версиями EntryPoint. Сначала сохраните raw RPC error, chain ID, EntryPoint address и весь объект без секретов; затем сопоставьте его с документацией именно поддерживаемой версии. Причину обычной Ethereum-транзакции reverted разбирают отдельно, потому что она уже прошла другой путь включения.

Null не различает pending, dropped и чужой bundler

eth_getUserOperationByHash может вернуть null для не включённого объекта; pending operation bundler также вправе не раскрывать. eth_getUserOperationReceipt возвращает данные после включения, иначе null. Поэтому один null не доказывает, что operation никогда не попадёт в bundle. Опросите исходный bundler, сохраните время acceptance и проверьте текущие nonce, paymaster state и EntryPoint. Если есть transactionHash, прочитайте события и логи Ethereum внутри его receipt.

Decision tool перед новой попыткой
ФактКлассификацияБезопасное действие
send вернул error, hash не полученBundler не принял объектИсправить доказанную причину и заново оценить gas/state до новой подписи
Hash получен, lookup/receipt nullAcceptance есть, inclusion не доказанПроверить исходный bundler и account nonce; не создавать другой вызов вслепую
Receipt есть, success=falseOperation включена, целевое execution не удалосьРазобрать reason/logs и фактические state deltas; nonce уже мог измениться
Receipt есть, success=trueEntryPoint зафиксировал success operationСверить целевые события, balances и получателя; success не доказывает экономический смысл
Decision tool перед новой попыткой
Факт
send вернул error, hash не получен
Классификация
Bundler не принял объект
Безопасное действие
Исправить доказанную причину и заново оценить gas/state до новой подписи
Факт
Hash получен, lookup/receipt null
Классификация
Acceptance есть, inclusion не доказан
Безопасное действие
Проверить исходный bundler и account nonce; не создавать другой вызов вслепую
Факт
Receipt есть, success=false
Классификация
Operation включена, целевое execution не удалось
Безопасное действие
Разобрать reason/logs и фактические state deltas; nonce уже мог измениться
Факт
Receipt есть, success=true
Классификация
EntryPoint зафиксировал success operation
Безопасное действие
Сверить целевые события, balances и получателя; success не доказывает экономический смысл

Повтор начинается с текущего состояния account

Минимальный recovery packet

  1. 1
    Зафиксируйте домен

    Chain ID, sender, EntryPoint address/version, bundler endpoint и userOpHash должны относиться к одной попытке.

  2. 2
    Сохраните raw object

    Nonce, callData, gas fields, fees, factory/paymaster data и signature нужны для воспроизведения; seed и private key не нужны.

  3. 3
    Разделите стадии

    Запишите acceptance response, lookup, receipt и внешний transactionHash как отдельные наблюдения.

  4. 4
    Перечитайте state

    Получите актуальный nonce через EntryPoint/account и проверьте balance/deposit paymaster до перестроения.

  5. 5
    Подписывайте новый hash осознанно

    Изменение nonce, gas, paymaster, callData, EntryPoint или chain создаёт другой запрос и требует нового подтверждения.

Stop-сигналы

  • неизвестны chain или EntryPoint, но предлагают увеличить gas и подписать снова;
  • поддержка просит seed-фразу, private key или перевод на paymaster вручную;
  • вместо raw bundler error сохранился только скриншот слова Failed;
  • один внешний handleOps receipt принимают за успех всех вложенных operations;
  • userOpHash ищут через случайный RPC-узел без ERC-4337 методов и объявляют потерянным.

Проверка завершена, когда другой человек воспроизводит chain, EntryPoint, raw UserOperation, ответ bundler и — если включение состоялось — отдельный receipt с success и внешним transactionHash. RPC-узел общего назначения полезен для блока и receipt bundle, но поддержка ERC-4337 методов у него должна быть подтверждена отдельно. До этой связки безопаснее остановить повтор, чем создавать второй экономически равный вызов с новым hash.

Источники

Мы используем прямые ссылки и фиксируем дату проверки. Полный текст чужих материалов не перепечатывается.

  1. ERC-4337 — Account Abstraction Using Alt Mempool Ethereum Improvement Proposals · Проверено 22 августа 2026 г. в 10:35 GMT+5
  2. ERC-7769 — JSON-RPC API for ERC-4337 Ethereum Improvement Proposals · Проверено 22 августа 2026 г. в 10:35 GMT+5
  3. ERC-4337 Docs — ERC-7562 bundler validation rules ERC-4337 Documentation · Проверено 22 августа 2026 г. в 10:35 GMT+5
  4. eth-infinitism — IEntryPoint.sol eth-infinitism · Проверено 22 августа 2026 г. в 10:35 GMT+5
Материал носит информационный характер и не является индивидуальной рекомендацией. Криптоактивы связаны с риском волатильности, технических сбоев, хищения и полной потери средств.