Блокчейн
Ethereum: аккаунты и state
В Bitcoin нет понятия «баланс кошелька» - есть только разбросанные по блокчейну выходы транзакций, которые нужно собирать как монеты из копилки. Виталик Бутерин решил, что это неудобно для смарт-контрактов, и придумал модель, где у каждого адреса есть нормальный аккаунт с балансом - как в банке, только без банка. Эта простая идея породила world state на 300 ГБ и несколько нетривиальных проблем масштабируемости.
- **MetaMask** показывает баланс вашего EOA, читая его прямо из world state trie — один lookup вместо перебора тысяч UTXO
- **Uniswap** — contract account, который управляет 5+ млрд ликвидности без приватного ключа, исключительно через код
- **Nonce** спасает пользователей от replay attacks ежедневно: без него любой мог бы повторно отправить вашу подписанную транзакцию и списать средства
Предварительные знания
Externally Owned Accounts (EOA)
В Bitcoin нет понятия «аккаунт» - есть только неизрасходованные выходы транзакций (UTXO). Ethereum пошёл другим путём: у каждого пользователя есть **аккаунт с балансом**, как в обычном банке.
**Externally Owned Account (EOA)** - аккаунт, управляемый человеком через приватный ключ. «Externally» означает, что управление происходит **извне блокчейна** - человек подписывает транзакцию своим ключом и отправляет в сеть.
Только EOA может **инициировать транзакцию**. Любое действие в Ethereum начинается с того, что владелец EOA подписывает и отправляет транзакцию. Без этой «первой искры» ничего не происходит.
**Почему 20 байт?** Это компромисс: 2^160 возможных адресов (~10^48) - достаточно, чтобы столкновение было практически невозможным, но адрес остаётся компактным. Для сравнения: атомов во Вселенной ~10^80.
EOA в реальной жизни
Как EOA работает при повседневном использовании
Когда ты создаёшь кошелёк в MetaMask: 1. MetaMask генерирует приватный ключ (и показывает seed phrase для его восстановления) 2. Из ключа вычисляется публичный ключ → адрес 3. Этот адрес - твой EOA Когда ты отправляешь 1 ETH другу: • MetaMask подписывает транзакцию приватным ключом • Сеть проверяет подпись → убеждается, что это действительно ты • Баланс твоего EOA уменьшается, баланс друга увеличивается
Что уникального в EOA по сравнению с другими типами аккаунтов в Ethereum?
Contract Accounts: автономные агенты
Второй тип аккаунтов в Ethereum - **contract accounts**. Это смарт-контракты: программы, живущие прямо в блокчейне. У них нет приватного ключа - вместо него есть **код** и **хранилище (storage)**.
Contract account нельзя «вручную» контролировать. Он выполняет только то, что записано в его коде. Поэтому их называют **автономными агентами**: однажды задеплоенный контракт работает по своим правилам, и даже его создатель не может изменить логику (если это не предусмотрено в самом коде).
Contract account может **реагировать** на входящие транзакции и вызовы, отправлять ETH, вызывать другие контракты - но не может сам начать цепочку действий. Всегда нужен EOA, который «нажмёт кнопку».
**CREATE2** - удобный инструмент. Uniswap использует его для деплоя пулов: адрес пула для пары ETH/USDC **детерминирован** и может быть вычислен заранее, без обращения к блокчейну.
Почему contract account не может инициировать транзакцию самостоятельно?
World State: состояние всей сети
Теперь ключевой вопрос: где Ethereum хранит информацию обо всех аккаунтах? Ответ - **world state** (мировое состояние). Это гигантская таблица, где **каждому адресу соответствует его состояние**.
Технически world state - это **Modified Merkle Patricia Trie** (MPT). Это дерево, где ключ - адрес аккаунта, а значение - его состояние. Корень этого дерева - **stateRoot** - записывается в заголовок каждого блока.
Это кардинально отличает Ethereum от Bitcoin. Bitcoin - **stateless**: чтобы узнать баланс адреса, нужно просканировать все UTXO. Ethereum - **stateful**: текущее состояние каждого аккаунта явно хранится в state trie и доступно за O(log n).
| Bitcoin (UTXO) | Ethereum (Account State) | |
|---|---|---|
| Модель | Набор неизрасходованных выходов | Таблица адрес → состояние |
| Баланс | Сумма всех UTXO адреса | Одно число в поле balance |
| State | Нет глобального state | World State Trie в каждом блоке |
| Проверка баланса | Перебор UTXO (O(n)) | Lookup в trie (O(log n)) |
| Смарт-контракты | Ограниченный Script | Полноценный EVM |
**Цена stateful модели:** размер state постоянно растёт. На март 2024 world state Ethereum занимает ~300 ГБ. Это называется **state bloat** - одна из главных проблем масштабируемости Ethereum.
Что записывается в поле stateRoot заголовка блока?
Nonce и Balance: защита от double-spend
Из четырёх полей аккаунта два заслуживают особого внимания: **nonce** и **balance**. Вместе они решают фундаментальную проблему цифровых денег - **double-spend**.
**Balance** хранится в **wei** - минимальной единице Ethereum. 1 ETH = 10^18 wei (квинтиллион). Почему такая точность? Потому что gas price и микро-транзакции требуют работы с очень маленькими суммами.
**Nonce** - счётчик транзакций, отправленных с данного EOA. Первая транзакция аккаунта имеет nonce = 0, вторая - 1, и так далее. Nonce решает сразу две проблемы:
Stuck transaction: проблема с nonce на практике
Реальная ситуация, знакомая каждому пользователю Ethereum
Ситуация: ты отправил транзакцию с низким gas price, и она зависла в mempool. Твой nonce аккаунта: 42 Зависшая транзакция: nonce=42, gas price=10 gwei Все последующие транзакции (nonce=43, 44, ...) тоже блокируются! Решение: отправить новую транзакцию с тем же nonce=42, но с более высоким gas price → старая заменяется новой. Это называется «speed up» или «cancel» транзакции в MetaMask.
**Nonce для contract accounts работает иначе:** он увеличивается не при транзакциях, а при **создании новых контрактов** через CREATE. Это важно, потому что адрес нового контракта зависит от nonce создателя.
Аккаунт в Ethereum - это как файл на диске, который создаётся при первом переводе
Аккаунт не «создаётся» в традиционном смысле. Любой валидный адрес потенциально существует в state trie. EOA «появляется» когда кто-то отправляет на него ETH или он отправляет первую транзакцию - тогда его состояние (nonce, balance) записывается в world state. До этого момента он имеет дефолтные значения (nonce=0, balance=0) и не занимает места в trie.
Это следствие архитектуры: state trie хранит только ненулевые значения. Пространство адресов (2^160) слишком велико, чтобы хранить все возможные аккаунты. Поэтому аккаунт существует «виртуально» и материализуется в state только при первом взаимодействии.
Алиса отправила транзакцию с nonce=10. Злоумышленник перехватил её и пытается отправить повторно. Что произойдёт?
Итоги
- **EOA** (Externally Owned Account) — управляется приватным ключом, только он может инициировать транзакции. Адрес = последние 20 байт keccak256(publicKey)
- **Contract Account** — автономный агент с кодом и storage, но без приватного ключа. Не может сам начать транзакцию, только реагирует на вызовы
- **World State** — Modified Merkle Patricia Trie, хранящий состояние каждого аккаунта (nonce, balance, storageRoot, codeHash). Корень записывается в каждый блок как stateRoot
- **Nonce** предотвращает replay attacks и гарантирует порядок транзакций, **balance** хранится в wei (1 ETH = 10^18 wei)
- В отличие от Bitcoin (stateless, UTXO), Ethereum — **stateful** система: полное состояние всей сети доступно в world state, как и обещал Виталик, когда проектировал альтернативу UTXO-модели
Связанные темы
Аккаунтная модель Ethereum связана с несколькими важными темами:
- Bitcoin UTXO — Альтернативная модель хранения балансов - без глобального state, через набор неизрасходованных выходов
- EVM — Виртуальная машина, которая выполняет код contract accounts и изменяет world state
- Hash-Based Structures — Merkle Patricia Trie - структура данных, на которой построен world state
Вопросы для размышления
- Почему Ethereum выбрал аккаунтную модель вместо UTXO? В каких сценариях UTXO может быть лучше?
- Если contract account не имеет приватного ключа, как тогда обновляется upgradeable proxy контракт — кто решает, что код можно изменить?
- State bloat (300+ ГБ) — одна из главных проблем Ethereum. Какие решения вы можете предложить для уменьшения размера world state?