Виртуальная машина Ethereum, или EVM (Ethereum Virtual Machine), — это среда исполнения смарт-контрактов Ethereum. Её работу удобно рассматривать как связь трёх элементов: контракт содержит скомпилированный байткод, EVM выполняет его инструкции, а состояние Ethereum изменяется по заданным правилам. Gas измеряет вычислительную работу и ограничивает объём ресурсов, доступный транзакции.
Такое объяснение помогает понять исполнение контракта, не превращая его в обещание нужного результата. Основные вопросы здесь просты: какой код выполняется, какие сохранённые данные он затрагивает и что произойдёт, если вычислительного бюджета не хватит? Для изучения этих принципов не требуется отправлять транзакцию или подписывать запрос кошелька.
Какой код исполняет EVM
Начать стоит с различия между программой и средой её исполнения. Смарт-контракт содержит код, а EVM задаёт правила его выполнения. В документации Ethereum об EVM описаны аккаунты контрактов, содержащие скомпилированный байткод. Когда другой аккаунт обращается к контракту посредством вызова сообщения, выполняется этот байткод.
Байткод — скомпилированная форма программы контракта. Его исполнение происходит через инструкции EVM, называемые опкодами. Байткод можно представить как закодированную программу, а опкоды — как отдельные инструкции, из которых складывается её работа. Для начального понимания эта связь полезнее, чем заучивание списка команд.
При чтении описания контракта полезно отделять назначение программы от её поведения. Фраза «контракт предназначен для записи значения» объясняет замысел. Чтобы описать поведение, нужно установить, какие инструкции выполняются и какое сохранённое значение получается в результате. Одно описание назначения ещё не подтверждает фактический результат.
EVM не является кошельком или алгоритмом консенсуса Ethereum. В рассматриваемой схеме её задача — исполнение кода контракта. Поэтому фразу «EVM обработала операцию» следует понимать в пределах этой задачи: сама по себе она не устанавливает все обстоятельства взаимодействия с приложением.
Переход состояния: исходные данные, правила и результат
Состояние Ethereum включает аккаунты, балансы и постоянное хранилище контрактов. EVM определяет правила изменения состояния. Документация выражает эту связь формулой Y(S, T) = S': исходное допустимое состояние вместе с допустимыми транзакциями даёт новое допустимое состояние согласно правилам перехода.
В этой записи важны все составляющие. Исходное состояние задаёт начальные данные. Транзакции содержат инструкции для обработки. Правила перехода определяют итоговое состояние. Если смотреть только на заявленное назначение контракта, исходный контекст останется за пределами объяснения.
Функция перехода описывается как детерминированная: при заданных входных данных и правилах результат определяется однозначно. Детерминированность не означает гарантированного достижения цели пользователя. Воспроизводимость вычисления и соответствие результата ожиданиям — разные вопросы. Определение не следует читать как обещание, что любой вызов обязательно завершится так, как задумано.
Здесь можно сделать ограниченный логический вывод из двух положений документации. Во-первых, переходы состояния подчиняются правилам протокола. Во-вторых, исполнение может исчерпать gas, после чего его изменения откатываются. Следовательно, допустимый переход состояния сам по себе не гарантирует, что вызов контракта достигнет намеченного результата. Это вывод из указанных предпосылок, а не отдельное обещание, содержащееся в формуле.
Постоянное хранилище и временные данные
Постоянное хранилище контракта связано с его аккаунтом и входит в глобальное состояние Ethereum. На понятийном уровне это место для данных, которые контракт сохраняет, а не только использует в промежуточных вычислениях.
Поэтому важно различать выполнение инструкций и подтверждённое изменение сохранённых данных. Если в описании упомянута операция записи, всё ещё нужно установить, вступило ли предполагаемое изменение в силу. Попытка обновления сама по себе недостаточна для вывода об итоговом значении.
При этом не все данные, используемые во время исполнения, становятся постоянными. Например, рабочая память EVM не сохраняется между транзакциями. Это отличие памяти исполнения от постоянного хранилища; оно не означает, что любые временные механизмы EVM устроены одинаково.
Для понимания основ не нужно разбирать внутреннее устройство деревьев хранения. Достаточно последовательно задать два вопроса: какая информация относится к постоянному состоянию контракта и какие сведения подтверждают её значение после обработки? Так легче избежать подмены результата описанием отдельного вычислительного шага.
Gas измеряет работу и задаёт её бюджет
Gas — единица измерения вычислительных усилий, необходимых для выполнения операций Ethereum. Лимит gas транзакции задаёт максимальный предоставленный ей бюджет в этих единицах. Gas служит мерой работы, а лимит ограничивает доступный объём.
В расчёте комиссии используется количество израсходованного gas, умноженное на стоимость единицы. Из сопоставления этого определения с определением лимита следует: количество gas и цена единицы — разные величины. Здесь нас интересует именно вычислительный бюджет, без разбора текущих цен и стоимости отдельных опкодов. Денежная сторона отдельно рассмотрена в статье о том, почему комиссия gas отличается от суммы перевода.
Недостаточный обязательный gas: отказ при проверке
Документация Ethereum о gas различает нехватку минимально необходимого gas для прохождения проверки и исчерпание gas после начала исполнения. В первом случае лимит ниже обязательной потребности транзакции, которую также называют intrinsic gas. Такая транзакция отклоняется на этапе проверки до включения в блок, и gas не расходуется.
Источник иллюстрирует это простым переводом ETH с лимитом ниже необходимого для проверки. Числовой порог из такого примера нельзя переносить на любую операцию контракта. Существенна граница этапов: отказ происходит при проверке, прежде чем начнётся исполнение.
Исчерпание gas во время исполнения
Во втором описанном источником случае транзакция начинает исполняться, но исчерпывает предоставленный gas. При таком исчерпании на уровне транзакции EVM откатывает изменения исполнения, а весь предоставленный gas расходуется на выполненную работу.
У этого утверждения есть чёткие пределы. Оно относится к описанному случаю исчерпания gas на уровне транзакции, а не к любой возможной ошибке. Из него не следует обещание восстановления активов, отмены расхода gas или определённого поведения при ошибках отдельных внутренних вызовов. Нельзя также заключать, что любая ошибка исполнения обязательно расходует весь лимит.
Гипотетический пример: счётчик в хранилище
Гипотетический пример: представим учебный контракт, в постоянном хранилище которого записан счётчик со значением 7. Предполагаемая операция должна увеличить его до 8. Контракт и числа вымышлены и нужны только для объяснения; выполнять реальную транзакцию не требуется.
- Определяем программу. Контракт содержит скомпилированный байткод, исполняемый через опкоды EVM при обращении к нему.
- Фиксируем исходные данные. До рассматриваемой операции в постоянном хранилище записано значение 7.
- Уточняем ожидаемый результат. Учебная задача предполагает, что итоговое сохранённое значение станет равно 8.
- Учитываем границу бюджета. Если транзакция исчерпает gas во время исполнения, изменения её исполнения откатятся, а весь предоставленный gas будет израсходован.
Пример показывает, почему описания намерения недостаточно. Исходное значение, выполняемая операция и итоговые сохранённые данные требуют отдельного рассмотрения. В варианте с исчерпанием gas само начало исполнения ещё не подтверждает предполагаемое обновление. Назвать ожидаемое значение и установить получившееся значение — разные шаги объяснения.
Граница между исполнением и согласованием в сети
Клиент исполнения Ethereum выполняет транзакции в EVM. Клиент консенсуса реализует согласование proof-of-stake, опираясь на данные, проверенные клиентом исполнения. Это разделение описано в документации об узлах и клиентах.
Для понимания EVM достаточно этой границы: исполнение относится к обработке инструкций и состоянию, консенсус — к сетевому согласованию на основе проверенных данных исполнения. Более широкий разбор этапов есть в статье о том, как проверяется транзакция Ethereum.
Используйте следующий список при разборе объяснения работы EVM:
- Установите, какой скомпилированный код рассматривается и каково его назначение.
- Уточните исходное состояние и относящиеся к нему данные постоянного хранилища.
- Отделите соблюдение правил перехода от подтверждения ожидаемого результата.
- Различайте бюджет gas транзакции и цену единицы gas.
- Отделите отказ из-за недостаточного обязательного gas от его исчерпания во время исполнения.
- Сохраняйте различие между исполнением и сетевым согласованием.
Эти вопросы помогают читать технические объяснения. Ссылки на первичную документацию сами по себе не устанавливают безопасность конкретного контракта.
Образовательный материал подготовлен с помощью ИИ. Пример вымышленный; статья не предлагает отправлять транзакции или подписывать запросы кошелька.