Перейти к содержанию

Корень состояния

Корень состояния — компактное обязательство Ethereum о глобальном состоянии после блока. Статья объясняет расчёт, смысл доказательств аккаунта и хранилища и границы их гарантий.

Обновлено

Только в образовательных целях; не является инвестиционным советом или инвестиционной рекомендацией. Инвестиции могут привести к убыткам.

Краткий ответ

Корень состояния — 32-байтовое криптографическое обязательство в заголовке блока Ethereum о глобальном состоянии после обработки блока. Глобальное состояние сопоставляет адреса аккаунтам. Каждый аккаунт фиксирует nonce, баланс, корень хранилища и хеш кода; корень хранилища контракта, в свою очередь, фиксирует ячейки хранения этого аккаунта.

Корень — дайджест, а не загружаемый снимок. Узлы сравнивают с ним независимо рассчитанные результаты, а проверяющий сверяет доказательство аккаунта или хранилища с доверенным блоком. Сам корень не позволяет восстановить состояние, не доказывает доступность данных или финальность блока и не подтверждает экономическую безопасность контракта.

Термин «корень состояния» зависит от протокола. Сейчас Ethereum фиксирует состояние уровня исполнения с помощью модифицированного дерева Merkle-Patricia. Другие сети могут применять иные модели состояния, кодировки, хеш-функции или аутентифицированные структуры данных, поэтому одинаковое название не делает корни и доказательства взаимозаменяемыми.

Как это работает

Клиент исполнения начинает с состояния родительского блока, проверяет и исполняет новый блок по действующим правилам протокола, затем применяет изменения аккаунтов и хранилищ. Схематично:

S_n = Υ(S_(n-1), B_n)

Здесь S_(n-1) — родительское состояние, B_n — вся заданная протоколом обработка нового блока, а S_n — итоговое состояние. Клиент детерминированно кодирует его в дереве состояния и вычисляет корневой хеш. Заголовок действительного блока должен содержать тот же результат; несовпадение означает, что клиент отвергнет блок.

В дереве состояния Ethereum путь аккаунта выводится из адреса, а закодированный аккаунт содержит nonce, баланс, корень хранилища и хеш кода. Код контракта указывается своим хешем, и у каждого контракта есть отдельное дерево хранилища. Поэтому изменение одной ячейки может изменить корень хранилища контракта, затем закодированный аккаунт и наконец глобальный корень состояния.

Корень состояния отличается от корней транзакций и квитанций в том же заголовке. Корень транзакций фиксирует упорядоченные данные транзакций, а корень квитанций — квитанции исполнения. Они не заменяют друг друга.

EIP-1186 определяет eth_getProof, который возвращает доказательство аккаунта и запрошенные доказательства хранилища для указанного блока. Проверяющему всё равно нужны аутентифицированный хеш блока или корень состояния, точные правила дерева и кодирования, а также подходящая политика подтверждений или финальности.

Пример

Пусть транзакция переводит ETH от Alice к Bob. Корректное исполнение может изменить nonce и баланс Alice, баланс Bob и баланс получателя комиссии. При вызове контракта могут измениться ячейки и корень его хранилища. Эти обновления создают новый глобальный корень состояния, хотя большинство аккаунтов не затронуто.

Два честных клиента, начавшие с одного родительского состояния и обработавшие один действительный блок по одинаковым правилам, должны получить одинаковый корень. Если клиент зачислит неверную сумму или применит неверную кодировку дерева, его корень разойдётся с заголовком, и он должен отвергнуть блок, а не молча принять локальное состояние.

Чтобы проверить баланс Bob без загрузки всего глобального состояния, можно получить заголовок блока и доказательство аккаунта. Пересчёт пути доказательства показывает, соответствует ли закодированный аккаунт корню состояния заголовка. Это не доказывает каноничность или финальность выбранного заголовка; они устанавливаются проверками цепочки и финальности.

Риски

  • Недоверенный корень: Действительное доказательство относительно выбранного злоумышленником или устаревшего корня подтверждает неверную точку отсчёта. Связывайте корень с проверенными хешем блока, ID цепочки и номером блока.
  • Реорганизации и финальность: Доказательство может быть верным для блока, который позже покинет каноническую цепь. Глубина подтверждения или финальность должна соответствовать допустимому убытку приложения.
  • Ошибки кодирования: Хеширование адресов, RLP, пути nibble, встроенные узлы и ключи хранилища должны точно следовать протоколу. Обычной библиотеки бинарных доказательств Merkle недостаточно.
  • Отсутствующие данные: Корень фиксирует состояние, но не обеспечивает доступность узлов дерева, истории или сервиса построения доказательств. Узлы после обрезки могут не выдавать старые доказательства.
  • Завышенные гарантии: Совпадение корней выявляет несовместимое исполнение, но не проверяет логику контракта, данные оракула или RPC, не гарантирует стоимость актива и не мешает скомпрометированным ключам подписывать операции.

Распространённые заблуждения

  • Корень состояния хранит все балансы. Это обязательство фиксированного размера о закодированном дереве; исходные данные дерева получают отдельно.
  • Одинаковые корни доказывают идентичность баз данных. Они фиксируют одинаковое логическое глобальное состояние по правилам протокола, но клиенты могут по-разному хранить, индексировать, обрезать и кешировать его.
  • Разный корень указывает ошибочную транзакцию. Он показывает расхождение итогового состояния, но не место его возникновения; для диагностики нужно трассировать исполнение.
  • Действительное доказательство аккаунта подтверждает финальность и безопасность. Оно подтверждает лишь соответствие одному корню. Выбор цепи, финальность, свежесть данных, поведение контракта и экономический риск остаются отдельными вопросами.

Связанные темы

Источники

Навигация

Поиск по вики...