Как проверяется транзакция в криптовалютной сети? На примере Ethereum ответ состоит из нескольких частей: какой аккаунт разрешил операцию, что получилось при исполнении, вошла ли транзакция в проверенный блок и как сеть достигла согласия. Слово «проверена» без уточнения может скрывать любой из этих этапов.
Различие особенно важно при обращении к смарт-контракту. Транзакция может попасть в блок, но завершиться ошибкой исполнения. Успешный статус, в свою очередь, сам по себе не доказывает достижения всех целей пользователя. Ниже рассматриваются обычные подписанные транзакции Ethereum. Это объяснение принципов, а не полный алгоритм проверки или универсальная схема для всех криптовалют.
1. Подпись подтверждает авторизацию аккаунта
Обычная транзакция Ethereum содержит подпись, созданную с помощью приватного ключа отправителя. Она подтверждает авторизацию операции соответствующим ключом. Поле from обозначает адрес отправителя. Здесь проверяется связь операции с аккаунтом, а не личность человека и не то, насколько хорошо он понял последствия действия.
Это ограничение полезно помнить при чтении утверждений о безопасности. Подтверждение авторизации ключом нельзя автоматически расширять до вывода, что контракт надёжен или операция отвечает намерениям пользователя. Подпись отвечает на определённый технический вопрос; оценка ожидаемого результата требует отдельного рассмотрения.
Ещё одно поле — nonce, последовательно увеличивающийся счётчик, который обозначает номер транзакции аккаунта. Для понимания общей схемы достаточно отличать его от подписи: подпись связана с авторизацией, а nonce задаёт номер операции в контексте аккаунта. Одно определение поля не описывает всех правил проверки nonce и замены ожидающих транзакций.
Эти поля разобраны в документации Ethereum о транзакциях. Её объяснение подписи следует читать в указанном узком смысле. Ни наличие подписи, ни ссылка на первичный источник не дают самостоятельной гарантии безопасности конкретного действия.
2. Распространение и исполнение решают разные задачи
В упрощённом описании жизненного цикла транзакцию передают в сеть, после чего она оказывается в пуле ожидающих операций. Это ещё не включение в блок. Такое описание также не обещает, что транзакцию получит каждый узел или что она обязательно будет включена позднее.
Клиент исполнения Ethereum выполняет переданные транзакции в виртуальной машине EVM. Исполнение определяет результат инструкций по правилам Ethereum. Включение отвечает на другой вопрос: стала ли транзакция частью проверенного блока. Для появления в блокчейне такое включение необходимо, но само требование не гарантирует, что оно произойдёт.
Проверка через повторное исполнение хорошо видна на примере полной синхронизации, или full sync. В этом режиме узел последовательно выполняет каждый блок начиная с исходного блока сети и восстанавливает состояние блокчейна. То есть результат реконструируется вычислениями, а не просто принимается как готовое утверждение.
Уточнение режима здесь существенно. Другие способы синхронизации могут начинать проверку с доверенной контрольной точки или иначе обрабатывать историю. Поэтому нельзя заключать, что каждый узел всегда заново исполняет всю историю Ethereum. Роли клиентов и различия режимов описаны в документации об узлах и клиентах. Это объяснение не заменяет полную спецификацию проверок протокола.
3. Консенсус выходит за пределы проверки одного узла
Клиент консенсуса Ethereum реализует механизм согласования proof-of-stake, используя данные, проверенные клиентом исполнения. Таким образом, проверка исполнения и достижение сетевого согласия связаны, но выполняют разные роли. Корректность вычислений и положение блока в согласованной цепочке нельзя описывать как один и тот же результат.
Документированный жизненный цикл также различает включение транзакции в блок и последующие этапы: обоснование блока, обозначаемое как justified, и финализацию — finalized. Первое появление транзакции в блоке не следует называть финальностью. Это описание стадий, а не обещание конкретного времени или безусловного перехода между ними.
Из разделения этих ролей следует вывод: локальная проверка исполнения одним узлом сама по себе не устанавливает финальность для сети. Основания вывода — отдельная роль сетевого согласования и отдельный этап финализации. Здесь не задаются пороги голосования и не утверждается абсолютная невозможность изменения истории.
Поэтому при чтении сообщения о проверке полезно уточнять его предмет. Сообщение может относиться к вычисленному результату, включению в блок или более позднему этапу консенсуса. Если назван только первый этап, сведения о последующих ещё нужно устанавливать отдельно.
4. Статус исполнения нужно отделять от включения
Квитанция транзакции Ethereum позволяет различить несколько фактов. Поле blockNumber указывает номер блока, содержащего транзакцию. В квитанциях с полем status значение 1 означает успешное исполнение, а 0 — ошибку исполнения. Номер блока сам по себе не устанавливает финальность.
У определения статуса есть историческая граница: документация отдельно описывает квитанции до обновления Byzantium, где вместо этого поля указывался корень состояния. Поэтому формулировка о значениях 1 и 0 относится именно к квитанциям, содержащим status.
Из устройства квитанции следует вывод: включение в проверенный блок не равнозначно успешному исполнению. Квитанция одновременно указывает содержащий транзакцию блок и допускает статус ошибки. Следовательно, сеть может принять и включить транзакцию, исполнение которой завершилось неудачей. Это не противоречие между двумя показателями: они описывают разные стороны операции.
Определения приведены в документации Ethereum JSON-RPC. Из определения бинарного статуса следует ещё одно ограничение: значение 1 сообщает об успехе исполнения, но не сравнивает результат со всеми ожиданиями пользователя. Чтобы установить конкретный результат работы контракта, нужны сведения именно об этом результате. Сам статус такой проверки не выполняет.
Если нужно отдельно разобраться в отображении этих данных, пригодится материал о том, как читать транзакцию Ethereum в обозревателе блоков. Здесь же главное — понимать смысл разных подтверждаемых фактов.
5. REVERT откатывает изменения в пределах затронутого исполнения
Инструкция REVERT прерывает затронутое исполнение EVM, обозначает его как неудачное и откатывает изменения состояния в его пределах. Область отката принципиальна: из этого правила нельзя делать вывод о восстановлении всех расходов gas, комиссий, эффектов nonce или любых изменений во внешнем контексте исполнения.
При обычном выполнении REVERT не расходует весь оставшийся gas. Это не означает бесплатного исполнения или восстановления gas, уже потраченного на вычисления. Есть и исключение: если gas недостаточно для самой инструкции REVERT либо происходит нехватка элементов стека, поведение соответствует исключению out-of-gas с расходованием всего gas в затронутом контексте исполнения.
Спецификация REVERT в EIP-140 также описывает передачу признака ошибки вызывающему коду, когда REVERT произошёл в вызванном контракте. Это позволяет сделать ограниченный вывод: откат вызванного исполнения сам по себе не доказывает откат всех эффектов вызывающего кода. Основания — границы отката и отдельное сообщение об ошибке вызывающей стороне.
Последующее поведение вызывающего кода и итог всей транзакции требуют собственных подтверждений. Нельзя по одному упоминанию внутреннего REVERT автоматически определить статус всей операции или объявить, что абсолютно всё вернулось в исходное состояние.
6. Условный пример и список для проверки объяснения
Гипотетический пример: Майя авторизовала обычную транзакцию Ethereum для обращения к контракту. Она ожидала выполнения определённой задачи. Транзакцию передали в сеть и позднее включили в проверенный блок. В квитанции указан этот блок, но поле status равно 0. Включение и ошибка исполнения совместимы: подпись и наличие блока не превращают неудачное исполнение в успешное.
Предположим, затронутое исполнение завершилось через REVERT. Изменения состояния в его пределах откатываются с учётом описанных ограничений по gas. Это не основание заявлять о восстановлении любых внешних эффектов. Если в другом варианте примера статус равен 1, он подтверждает успех исполнения, но отдельно взятого поля всё ещё недостаточно для доказательства всей задуманной Майей задачи. Оба варианта вымышлены и служат только для объяснения.
Чтобы оценить объяснение проверки транзакции, пройдите по списку:
- Уточните сеть: выводы об Ethereum не следует автоматически переносить на другие протоколы.
- Отделите авторизацию подписью и значение nonce от результата исполнения.
- Различайте распространение, включение в блок и последующие стадии консенсуса.
- Сопоставляйте статус исполнения с данными о блоке, не приравнивая их друг к другу.
- Ограничивайте вывод об откате областью затронутого исполнения и учитывайте исключения REVERT.
- Уточняйте, какие сведения подтверждают конкретный ожидаемый результат работы контракта.
Образовательный материал подготовлен с помощью ИИ. Условные примеры поясняют механизм; сопоставление утверждений с источниками требует независимой редакционной проверки.