State layout в Ethereum: как устроено состояние и хранилище контрактов

State layout в контексте Ethereum — это то, как физически и логически устроено состояние сети: какие уровни состояния существуют, как они связаны между собой и каким образом данные кодируются в деревьях и хранилищах.

Проще: это «план квартиры» для данных Ethereum — где лежат балансы, код контрактов и их переменные, и как узлы находят нужный кусок состояния, не загружая всё подряд.

State layout в Ethereum: как устроено состояние и хранилище контрактов

Уровни состояния в Ethereum

В Ethereum можно выделить несколько уровней state layout:

  • World state — глобальное состояние сети: отображение от адреса к аккаунту.
  • Состояние аккаунта — структура с полями:
    • nonce (счётчик транзакций),
    • balance (баланс ETH),
    • storageRoot (корень хранилища),
    • codeHash (хеш байткода).
  • Хранилище контракта (storage) — отдельное ключ-значение хранилище для каждой учётной записи-контракта.
  • История состояний — последовательность state root’ов в каждом блоке, позволяющая «перематывать» состояние назад.

На уровне протокола всё это упаковано в специализированные деревья, см. Merkle Patricia Trie (MPT) в Ethereum — как устроено текущее дерево состояния и Ethereum State.

World state и account-based модель

Ethereum использует account-based модель, в отличие от UTXO-подхода (как в Bitcoin):

  • у каждого адреса есть аккаунт,
  • транзакции прямо изменяют баланс и состояние аккаунтов,
  • итоговое состояние описывается одним корнем дерева — stateRoot в заголовке блока.

World state — это концептуально:

  • отображение address → account;
  • фактически — Merkle Patricia Trie, в котором:
    • ключом служит адрес (обработанный через Keccak-256);
    • значением — сериализованный объект аккаунта.

State layout на этом уровне определяет:

  • как быстро узел может найти состояние по адресу;
  • как компактно состояние кодируется на диске;
  • какие доказательства (proof’ы) можно строить для light-клиентов и мостов.

Merkle Patricia Trie, stateRoot и storageRoot

Чтобы можно было:

  • доказывать корректность состояния без скачивания всего объёма данных;
  • эффективно проверять отдельные ключи,

Ethereum использует Merkle Patricia Trie (MPT):

  • stateRoot — корень trie для всего world state;
  • storageRoot — корень отдельного trie для хранилища конкретного контракта.

Особенности state layout в MPT:

  • ключи разбиваются по нибблам (4-битные куски), что задаёт структуру дерева;
  • значения аккаунтов/слотов кодируются через RLP;
  • каждый узел дерева содержит хеши дочерних узлов, образуя Merkle-структуру.

Такой layout позволяет:

  • строить короткие доказательства «аккаунт X действительно имеет такое состояние»;
  • эффективно синхронизировать узлы (light-клиенты, мосты, rollup’ы).

Layout хранилища контрактов и связь с Solidity

Хранилище каждого контракта — это отдельный key-value store с собственным storage trie:

  • ключ — это 256-битный индекс слота;
  • внутри trie ключ обычно представлен как keccak256(slot_index) (для простых типов) или более сложные схемы для массивов/структур;
  • значение — 32-байтовое слово (storage word).

Важно отличать:

  • state layout на уровне протокола — как хранятся слова в trie;
  • storage layout на уровне языка — как компилятор (например, Solidity) раскладывает переменные по слотам.

Для разработчика смарт-контрактов:

  • детальный разбор схем размещения переменных и упаковки в слоты — на странице Storage Layout;
  • понимание того, как компилятор сопоставляет high-level переменную с конкретным storage-слотом, критично для:
    • апгрейдов прокси-контрактов;
    • работы с delegatecall;
    • низкоуровневого дебага и оптимизации газа.

State layout, газ и производительность

Выбор state layout напрямую влияет на стоимость операций:

  • SLOAD / SSTORE в EVM должны:
    • найти нужный слот в storage trie;
    • при необходимости изменить структуру дерева;
    • пересчитать хеши до корня storageRoot и stateRoot.

Из-за этого:

  • чтение/запись в storage — одни из самых дорогих по газу операций;
  • протокол стимулирует разработчиков уменьшать количество и изменчивость слотов:
    • кэшировать значения в memory/stack;
    • использовать события (event’ы) вместо частых записей;
    • аккуратно проектировать структуры данных.

State layout также влияет на:

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

Эволюция state layout: Verkle-деревья и stateless-клиенты

Текущий layout на базе Merkle Patricia Trie — не финальная точка. В дорожной карте Ethereum:

Основные цели:

  • сделать доказательства состояния компактнее;
  • сократить нагрузку на диск;
  • позволить узлам работать без полного world state, используя лишь «свидетельства» (witnesses) к нужным частям состояния.

Это по сути следующая итерация state layout:

  • структура дерева меняется (Verkle вместо MPT);
  • формат доказательств и их размеры улучшаются;
  • но логический уровень (world state, аккаунты, storage) остаётся знакомым.

См. также

Task Runner