Статус транзакції успішний, а переказ токенів не відбувся

2026-09-03

Статус транзакції успішний, а переказ токенів не відбувся

Гаманець пише, що підтверджено. На сторінці оглядача стоїть зелена галочка. А токенів на рахунку немає. Ніщо не застрягло і нічого не треба надсилати повторно: поле статусу відповіло на вужче запитання, ніж те, яке ви ставите. Нижче розібрано, що саме засвідчує це поле, що воно лишає поза дужками і де записана відповідь, яка вам насправді потрібна.

Статус транзакції успішний, а переказ токенів не відбувся: що засвідчує статус квитанції і де насправді записане переміщення токенів

Що насправді засвідчує успішний статус

EIP-658 помістив у квитанцію транзакції код статусу і визначив два його значення одним рядком: 0 означає невдачу, спричинену будь-якою операцією, здатною відкотити транзакцію або виклик верхнього рівня, а 1 означає успіх. Оглядач блоків перетворює цю одиницю на галочку.

Важлива саме сфера дії цього визначення. Код описує виклик верхнього рівня. Він повідомляє, що найзовнішня частина виконання завершилася без відкату, і не повідомляє нічого понад це: ні що змінився баланс конкретного токена, ні що перемістилася сума, яку ви мали на увазі, ні що викликаний контракт зробив те, про що ви його просили. Квитанція зі статусом 0 — це те, що оглядач позначає як reverted. Квитанція зі статусом 1 виключає цей випадок і на цьому спиняється.

Кожен випадок нижче живе саме в цьому проміжку. Ланцюг записав те, що сталося, повністю. А підсумок з одного слова вгорі сторінки відповідав на інше запитання.

Запитання, яке ви ставите Де записана відповідь
Чи потрапила вона в блок Номер блоку у квитанції
Чи обійшовся найзовнішній виклик без відкату Код статусу у квитанції
Чи змінився баланс цього токена Події переказу в журналах
Чи виконала моя операція користувача свою роботу Прапорець успіху в її власній події

Чому переказ токенів може не відбутися без відкату

Стандарт токена ERC-20 оголошує transfer функцією, що повертає булеве значення, і про наслідок говорить жорстко: той, хто викликає, зобов'язаний обробляти false з returns bool success, і той, хто викликає, не повинен вважати, що false ніколи не повертається. Невдачі дозволено приходити як значення, що повертається, а не як відкат.

Коли токен повідомляє про невдачу саме так, результат залежить від контракту, який його викликав. Той, хто викликає і перевіряє булеве значення, може відкотитися на false, і квитанція повертається зі статусом 0. Той, хто викликає і відкидає це значення, іде далі, найзовнішній виклик завершується, квитанція каже про успіх, а баланс так і не зрушив.

Значення, що повертаються, різняться ще у другий спосіб. Бібліотека SafeERC20 від OpenZeppelin описує себе як обгортки навколо операцій ERC-20, які кидають виняток при невдачі, коли контракт токена повертає false, і додає, що токени, які не повертають значення взагалі, теж підтримуються, а виклики без відкату вважаються успішними. Бібліотека, написана заради зведення цих значень до одного вигляду, сама є прямим свідченням того, що вони неоднорідні.

Невдачі, які контракт ковтає навмисно

Контракт може викликати інший контракт і заздалегідь вирішити не падати разом із ним. Конструкція try і catch у Solidity, а також низькорівневий виклик, який віддає прапорець успіху замість того, щоб пропускати відкат нагору, існують саме для того, щоб виконання тривало після внутрішньої невдачі. Роутери, батчери та релеєри користуються цим навмисно: одна нога пакета не проходить, решта ніг розраховуються, а транзакція в цілому успішна.

З боку квитанції це не відрізнити від попереднього випадку. Внутрішній виклик не пройшов, зовнішній виклик поглинув цю невдачу, а поле статусу записало зовнішній результат. Внутрішня невдача досі в ланцюгу, але вона лежить у трасі виконання і в тому, чого в журналах немає, а не в полі статусу.

Замалий ліміт витрачання — один зі шляхів до цієї форми. Контракт, який забирає ваші токени через transferFrom, витрачає в межах ліміту, заданого вами через схвалення токенів. Коли ліміт менший за суму, яку витягують, внутрішній виклик не проходить, а чи падає разом із ним уся транзакція, вирішує той, хто викликає, а не токен.

Коли приходить менше, ніж було надіслано

У третьому випадку невдачі немає взагалі, а арифметика все одно не сходиться. Контракт токена може утримувати частину всередині власної функції transfer, зараховуючи одержувачу менше, ніж передав відправник. Надішліть 5 000 одиниць токена, який бере 3% з кожного переказу, і прийде 4 850. Квитанція каже про успіх, подія переказу на місці, а число всередині неї — не те число, яке набрали.

Токени з ребейзом дають споріднену розбіжність з протилежного боку. Їхні баланси переписує контракт, а не переміщує переказ, тож баланс може змінитися без жодної події переказу за ним. Звіряти показання гаманця із сумами в історії транзакцій для такого токена не вийде, і при цьому жодне з двох показань не є хибним.

Що означає повідомлення про невдалу транзакцію з paymaster

За абстракції акаунтів те, що ви подаєте, не є транзакцією. ERC-4337 визначає об'єкт UserOperation із власним мемпулом і бандлера, який пакує такі об'єкти в одну звичайну транзакцію до контракту EntryPoint. Paymaster — це контракт, який погоджується заплатити за транзакцію замість відправника. Повідомлення про помилку, що називає paymaster, покриває дві ситуації, у яких немає нічого спільного, крім слова невдача.

Перша — відхилення під час валідації. ERC-4337 вимагає: якщо будь-який виклик validateUserOp зазнає невдачі, handleOps має пропустити виконання щонайменше цієї операції користувача, і вимагає від бандлерів відхиляти недійсні операції зі свого мемпулу, а не розміщувати їх у ланцюгу. Paymaster, який відмовляється спонсорувати виклик, у якого залишилося замало депозиту або який не проходить власну валідацію, спрямовує операцію в цю гілку. Нічого не було включено, нічого не було списано, і немає хеша, який можна переглянути, бо невдача сталася до того, як ланцюг побачив операцію.

Друга відбувається після включення, і саме вона дає галочку. Щойно валідація пройдена, специфікація стверджує, що виконання відбудеться і відбудеться лише один раз, а також гарантує сплату комісії. Далі EntryPoint випускає для кожної операції користувача подію з прапорцем успіху, задокументованим як true, якщо транзакція відправника вдалася, і false, якщо вона відкотилася, поряд із фактично сплаченою акаунтом або paymaster сумою. Пакетна транзакція успішна, з paymaster списано, а прапорець вашої операції дорівнює false. Усі три твердження справджуються одночасно.

Де сталася невдача Потрапило в блок Хто заплатив Що можна переглянути
Валідація, до включення Ні Ніхто Помилка від бандлера або гаманця і жодного запису в ланцюгу
Виконання, після включення Так Акаунт або paymaster Успішна транзакція, у події операції користувача якої прапорець успіху дорівнює false

Куди дивитися замість поля статусу

Переміщення токенів записуються як події в журналах. Вигляд із переказами токенів в оглядачі — це подання цих подій, тож якщо вашої адреси немає в жодній із них, токен не рухався, хоч би що казав статус. Перевіряти треба журнали; статус — це підсумок.

Три запитання роблять усю роботу. Чи існує взагалі подія переказу з вашою адресою, чи цей розділ сторінки порожній? Якщо існує, чи дорівнює її сума надісланій сумі? І чи той контракт її випускає, який ви мали на увазі, і чи в тій мережі.

Четверта можливість переживає всі три перевірки: переказ стався рівно так, як було велено, а шукають його не там. Друга адреса, виведена з тієї самої сид-фрази, та сама адреса в іншій мережі і токен, якого гаманець не покаже, доки його контракт не додадуть вручну, — кожен із них дає порожній екран поряд із цілком справною квитанцією.

Підсумок

Статус квитанції — це твердження про найзовнішній виклик і ні про що більше. Успіх означає, що транзакція не відкотилася. Він ніколи не означав, що токен перемістився, що перемістилася правильна сума або що контракт зробив із нею те, чого від нього хотіли. Ці факти живуть у журналах подій, а за ERC-4337 — у прапорці успіху, який тримають окремо від статусу транзакції, що його несе.

Коли переказ зникає за зеленою галочкою, ідіть шарами по порядку: подія переказу, далі її сума, далі контракт токена і мережа. Щоб і далі вивчати основи, стежте за матеріалами Bitbase Academy.

Схожі матеріали

Інші матеріали Bitbase на цю тему:

- Як безпечно змінити RPC-ендпоінт

- Максимальну комісію за транзакцію перевищено: що означає це попередження гаманця

- Перевищено ліміт запитів RPC і що з цим робити

- Що таке криптовалютний QR-код?

- Глобальна ліквідність, M2 і Bitcoin: посібник із вимірювання

Застереження: Ця стаття є освітнім матеріалом Bitbase Academy і надається лише для інформації. Вона не є інвестиційною, торговою, податковою чи фінансовою порадою. Криптоактиви волатильні — оцінюйте ризики самостійно. Написано станом на вересень 2026 року; орієнтуйтеся на найновішу офіційну інформацію.

Джерела

[1] Ethereum Improvement Proposals, EIP-20: Token Standard (функція transfer і її булеве значення, що повертається) eips.ethereum.org

[2] Ethereum Improvement Proposals, EIP-658: Embedding transaction status code in receipts (поле статусу у квитанції транзакції) eips.ethereum.org

[3] Ethereum Improvement Proposals, ERC-4337: Account Abstraction Using Alt Mempool (валідація, бандлери та paymaster) eips.ethereum.org

[4] eth-infinitism, account-abstraction, contracts/interfaces/IEntryPoint.sol, тег v0.7.0 (оголошення UserOperationEvent) raw.githubusercontent.com

[5] OpenZeppelin, openzeppelin-contracts, contracts/token/ERC20/utils/SafeERC20.sol, тег v5.1.0 (документаційний коментар бібліотеки) raw.githubusercontent.com

Пов'язані статті

Більше