Чому взаємодія з контрактом зривається після успішної симуляції

2026-09-03

Чому взаємодія з контрактом зривається після успішної симуляції

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

Чому взаємодія з контрактом зривається після успішної симуляції: ключові моменти

Що насправді виконує симуляція

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

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

Стан, на якому ви симулювали, не є станом, у який ви потрапляєте

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

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

Мінімальний вихід і дедлайн: перевірки, які зриваються навмисно

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

Припустімо, попередній перегляд називає 10 000 USDC за токени, які ви продаєте, а ваш допуск виставлено на 0,5 %. Тоді виклик несе межу 9 950 USDC, і контракт отримує вказівку відмовитися від усієї взаємодії, замість того щоб видати менше. Коли ціна відходить далі за ваш допуск, поки транзакція в дорозі, запобіжник робить рівно те, про що ви його просили. Дедлайн поводиться так само: виклик, який висить непідтвердженим довше за власну позначку часу, відхиляється після прибуття, хоча той самий виклик пройшов би кількома хвилинами раніше.

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

Порядок: та сама транзакція на іншому місці

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

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

Газ: оцінка не є бронюванням

Оцінка газу отримується тим самим способом, що й попередній перегляд: виклик виконується один раз і вимірюється. Та сама документація попереджає, що оцінка може виявитися значно більшою за кількість газу, фактично використану транзакцією, а боляче б'є протилежний напрям: оцінка, знята на дешевій гілці, може не покрити ту гілку, якою транзакція піде врешті.

Саме на розгалуженнях виконання цей розрив і відкривається. Обмін, що під час перегляду проходив через один пул, під час виконання може пройти через два; перший запис у комірку сховища коштує дорожче за наступний запис у ту саму комірку; цикл, який торкнувся трьох позицій, може торкнутися дев'яти. Якщо підписаний вами ліміт вичерпується посеред виконання, зроблена робота відкочується, а газ усе одно витрачається, і це та сама арифметика, що застосовна до будь-якої невдалої транзакції. Запас понад оцінку не підвищує комісію, коли він лишається невикористаним, бо як формується ціна газу відокремлює обсяг роботи від ціни за одиницю роботи.

Коли симуляція симулювала не ту транзакцію, яку ви надіслали

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

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

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

Який вигляд має невдача потім

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

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

Що справді знижує частку невдач

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

Налаштовуйте запобіжники під конкретний актив, а не за звичкою. Межа, достатньо вузька, щоб відхиляти звичайний рух за хвилину на тонкому ринку, раз за разом зупинятиме ваші взаємодії, а межа, достатньо широка, щоб приймати будь-що, віддає той захист, заради якого ви її ставили. Те саме судження стосується дедлайну, який має бути достатньо довгим, щоб пережити період перевантаження.

Ставтеся до повторюваної невдачі як до інформації. Коли та сама взаємодія з тими самими аргументами зупиняється кілька разів, контракт повідомляє про умову, яку зараз виконати неможливо, а повторне надсилання того самого виклику витрачає газ заради тієї самої відповіді.

Підсумок

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

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

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

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

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

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

- FIFO і LIFO у собівартості криптоактивів

- Меметична премія: чому меми впливають на ціни

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

Джерела

[1] Документація для розробників Ethereum.org, JSON-RPC API (eth_call, eth_estimateGas) ethereum.org

[2] Ethereum Improvement Proposals, EIP-658: Embedding transaction status code in receipts eips.ethereum.org

[3] Документація для розробників Ethereum.org, «Транзакції» (Transactions) ethereum.org

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

Більше