ГоловнаСтаттіМшина Стічок: Як Виконуються Контракти Розумності

Мшина Стічок: Як Виконуються Контракти Розумності

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

mysimulator teamОновлено — червень 2026≈ 8 хв читання▶ Відкрити симуляцію

Чому платформи розумних контрактів використовують стековий віртуальний машинний пристрій

Стекова віртуальна машина зберігає дані на простому стеку «першим прийшов – першим вийшов» замість іменних регістрів. Це робить інструкційну схему мінімальною та однорідною: майже кожен операторний код витягує свої операнди зі вершини стека та повертає результат на нього. Ця простота ідеально підходить для децентралізованої мережі. Тисячі незалежних вузлів повинні виконувати один і той самий байт-код і досягти ідентичного кінцевого стану, по одному байту, без двозначності щодо того, який регістр містив які дані. Машина зі стеком не має прихованого файлу регістрів для суперечок, немає правил виклику, специфічних для компілятора, і немає невизначеної поведінки — вміст стека на кожному інструкційному циклі повністю визначається послідовністю операторних кодів, які були виконані до цього. Ця детермінованість дозволяє кожному вузлу незалежно повторно запустити транзакцію та перевірити результат замість того, щоб довіряти вихідній інформації однієї сторони.

Як оператори штовхають і витягують значення крок за кроком

Виконання відбувається по одній операції за раз, починаючи з лічильника програм (програмного покажчика), який збільшується після виконання кожного інструкту. Оператори PUSH поміщають літеральне числове значення на вершину стеку. Арифметичні оператори, такі як ADD або MUL, витягують точно два значення з верху стеку, обчислюють результат і штовхають цей єдиний результат назад — таким чином ефект: стек зменшується на один елемент. Розглянемо PUSH 3, PUSH 5, ADD: після двох штовхів стек містить [3, 5] з 5 зверху; ADD витягує обидва значення, обчислює 3 + 5 і штовхає 8, залишаючи стек як [8]. Оператори DUP та SWAP переставляють існуючі елементи стеку без будь-якого впливу на пам'ять. Оскільки ефект кожної операції щодо стеку є фіксованим і не залежить від контексту, вузол може перевірити правильність лише шляхом моделювання тієї ж послідовності — немає передбачення розгалужень або специulative виконання, які потрібно узгоджувати між машинами.

Зберігання проти стеку: постійний стан

Стек є тимчасовим — він існує лише протягом одного виконання та викидається в момент завершення виклику. Збереження контракту є протилежним: це постійна карта ключ-значення, яка зберігається між транзакціями та є частиною постійної бази даних блокчейну, ідентично відтворюючись на кожному вузлі. Читання збереження (SLOAD) переносить значення за заданим ключем на стек; запис у збереження (SSTORE) виймає ключ і значення зі стеку та записує їх у постійне місце. Наприклад, передача токена обчислює новий баланс відправника на стеку, потім SSTORE його в слот зберігання цього облікового запису та робить те саме для отримувача — два невеликі обчислення стеку, за якими слідують два постійні записи. Оскільки записи збереження є детермінованими функціями вхідної транзакції, кожен вузол досягає ідентичного оновленого стану.

Чому обмеження газу та кроків обмежують кожне виконання

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

Часті запитання

Що таке «збірна» (stack-based) для віртуальної машини?

Це означає, що основна робоча пам’ять віртуальної машини – це стек типу «першим прийшов – першим вийшов», а не набір іменних регістрів. Більшість інструкцій отримують операнди безпосередньо з верху стеку та повертають результат назад на нього, замість того, щоб явно вказувати джерело та призначення регістрів. Це робить кодування інструкцій компактним і спрощує інтерпретатор: віртуальна машина повинна відстежувати лише один покажчик верху стеку, а також лічильник команд. Машини на основі стека легше правильно реалізувати та перевірити незалежно від багатьох різних реалізацій, що важливо, коли мережа вузлів має виконувати однакові байт-код і узгоджувати результати без будь-якого координаційного обміну за межами спільного послідовності інструкцій.

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

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

Як сховище контракту відрізняється від виконання стеку?

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

Спробуйте наживо

Усе, що вище, працює прямо у вашому браузері — відкрийте Stack Machine: How Smart Contracts Execute і змінюйте параметри під час роботи. Нічого не встановлюється, нічого не завантажується на сервер, уся модель живе в одній вкладці.

▶ Відкрити симуляцію Stack Machine: How Smart Contracts Execute

Що ви знайшли?

Додати кроки відтворення (опційно)