javascript

Блокчейн глазами разработчика: append‑only база данных, за запись в которую платят

  • пятница, 7 августа 2026 г. в 00:00:03
https://habr.com/ru/articles/1067392/

Слово «блокчейн» испорчено маркетингом. За десять лет вокруг него наросло столько «революций», «иксов» и «цифрового золота», что нормальный разработчик при его звуке закрывает вкладку — и я его понимаю.

Проблема в том, что за хайпом прячется инженерно интересная конструкция. Если убрать из блокчейна всё маркетинговое и посмотреть на него глазами человека, который каждый день работает с Postgres, Kafka и git, останется знакомая до боли вещь: реплицированный append‑only лог, в котором состояние — это проекция, а запись — платная.

В этой статье я разберу блокчейн именно так: без «крипты», через аналогии с инструментами, которыми вы пользуетесь каждый день. А в конце мы подключимся к реальной сети из десяти строк TypeScript и пощупаем этот лог руками.

Блокчейн — это лог

Начнём с главного тезиса: блокчейн — это не «распределённая магия», а журнал транзакций, в который можно только дописывать.

Вы уже работали минимум с тремя такими журналами:

WAL в Postgres. Прежде чем изменить страницу данных, Postgres записывает изменение в write‑ahead log — строго в конец, без правок задним числом. Упал сервер — состояние восстанавливается проигрыванием WAL. Истина живёт в логе, таблицы — производное.

Топик в Kafka. Продюсеры дописывают сообщения в конец партиции. Оффсеты только растут, прошлое неизменяемо (пока не сработала retention‑политика). Консьюмеры строят своё состояние, проигрывая топик с нужного места.

Git. Каждый коммит содержит хеш родителя. Попробуйте подменить коммит трёхлетней давности — хеш изменится, и вся цепочка после него «рассыплется»: каждый следующий коммит ссылается уже на несуществующий хеш. Именно поэтому git log — надёжная история: переписать её незаметно нельзя, любая правка прошлого видна всем.

Блокчейн устроен так же, только единица записи — не коммит и не сообщение, а блок: пачка транзакций плюс служебные данные. В Ethereum новый блок появляется примерно раз в 12 секунд, и каждый блок несёт в себе хеш предыдущего — ровно как коммит в git несёт хеш родителя. Отсюда и название: цепочка блоков.

На этом месте «революционная технология» превращается в конструкцию из трёх знакомых деталей: Kafka‑подобный лог + git‑подобная цепочка хешей + репликация на тысячи узлов.

Балансы никто не хранит

Второй тезис ломает интуицию сильнее первого: «баланс кошелька» — это не ячейка, в которой лежит число.

Когда вы видите «на адресе 1.5 ETH», нигде не лежит запись balance = 1.5, которую кто‑то обновляет. Есть только лог всех транзакций с начала времён. Баланс — это результат его проигрывания: пришло +2, ушло −0.5, итого 1.5. Состояние вычисляется из истории, а не хранится вместо неё.

Если вы работали с event sourcing — это он и есть, в самом чистом виде из существующих в продакшене. Истина — история событий; текущее состояние — свёртка (fold) по этой истории; снести состояние и пересчитать заново можно в любой момент.

Ноды, конечно, кешируют вычисленное состояние — пересчитывать миллиарды транзакций на каждый запрос никто не станет. Но это именно кеш, materialized view поверх журнала. Любой узел сети может удалить его и восстановить с нуля, и получит байт в байт то же самое. Сравните с обычной базой: удалите таблицу без бэкапа — и данных больше нет, потому что таблица и была истиной.

Вне блокчейна вы сталкиваетесь с этим паттерном каждый день, просто не называете его: банковская выписка (события) и остаток на счёте (проекция), бухгалтерская книга и сальдо, аудит‑лог и текущие права доступа.

Три отличия от вашего Postgres

Если блокчейн — просто лог с проекцией, зачем городить огород? Postgres прекрасен, WAL у него уже есть. Разница — в трёх пунктах, и каждый из них дорого стоит.

1. Писать может кто угодно

В ваш Postgres пишут те, кому вы выдали доступ. За целостность отвечает один процесс на одной машине (ну, плюс реплики, которым primary доверяет по определению).

В публичный блокчейн пишет любой человек на планете. Анонимно. Без регистрации. Без DBA, который в случае чего всех рассудит. И при этом десятки тысяч независимых узлов — которые друг другу не доверяют и не обязаны — должны прийти к одинаковому ответу на вопрос «какой блок следующий?».

Механизм, которым они договариваются, называется консенсусом. В современном Ethereum это proof‑of‑stake: узлы‑валидаторы вносят залог (32 ETH - 2048 ETH), голосуют за блоки, а за попытку смошенничать — например, подписать два конфликтующих блока — протокол автоматически сжигает часть залога. Честность здесь не предполагается по умолчанию, как в кластере Postgres, — она делается экономически выгодной стратегией. Это отдельная большая тема; для сегодняшней картины достаточно того, что задача «тысячи незнакомцев согласованно пишут в один лог» решена и работает в проде больше десяти лет.

2. Запись платная

Каждая транзакция стоит денег — это тот самый «газ», о который спотыкаются все новички.

Интуиция подсказывает, что это жадность. Инженерный взгляд — что это честный ценник. Подумайте, что вы покупаете: ваша транзакция навсегда ложится в лог, который хранят и будут хранить десятки тысяч узлов по всему миру. Вы платите не за INSERT — вы покупаете кусочек вечного, отреплицированного на всю планету хранилища. Вечный INSERT с бесконечной репликацией обязан стоить денег: бесплатный он ровно до тех пор, пока кто‑то другой оплачивает ваши диски.

Газ считается за операции: простой перевод — фиксированные 21 000 единиц газа, развёртывание контракта или сложная логика — сотни тысяч. Итоговая цена = количество газа × текущая ставка, а ставка плавает по загрузке сети — это аукцион за место в блоке. Плюс побочный эффект, который легко недооценить: платная запись — это ещё и встроенная защита от спама. Заспамить ваш API ботам почти бесплатно; заспамить блокчейн — разорительно.

3. UPDATE и DELETE не существуют

В этом логе есть только append. Никакого «поправить задним числом», никакого «удалить по GDPR‑запросу», никакого UPDATE users SET balance = ... от админа.

Единственный способ «отменить» транзакцию — отправить новую, в обратную сторону. Ровно как git revert: старый коммит навсегда остаётся в истории, поверх добавляется отменяющий. Ошиблись адресом при переводе — история этой ошибки останется в логе навсегда, даже если получатель вернёт деньги.

Из этого свойства растут и суперсилы блокчейна (никто — включая владельцев инфраструктуры — не может переписать историю), и его самые неприятные грабли (ошибка необратима; «право на забвение» физически нереализуемо). Проектировать под такой лог — отдельный навык: цена бага измеряется не даунтаймом, а деньгами, которые нельзя вернуть UPDATE‑ом.

Postgres vs блокчейн: шпаргалка

Postgres

Ethereum

Модель данных

таблицы = истина

лог = истина, состояние = проекция

Кто пишет

кому выдали GRANT

кто угодно, анонимно

Целостность

доверенный процесс + WAL

консенсус тысяч недоверяющих узлов

Стоимость записи

амортизированная (ваши диски)

явная, за каждую транзакцию (газ)

UPDATE / DELETE

есть

не существуют, только append

Скорость записи

до сотен тысяч TPS

потолок ~240 TPS на простых переводах; в реальной смешанной нагрузке — десятки TPS

Подтверждение записи

миллисекунды

~12 с до включения в блок; финальность ~13 минут

Чтение

по правам доступа

публичное, для всех

Откат ошибки

UPDATE, restore из бэкапа

только компенсирующая транзакция

Таблица честно показывает и цену: блокчейн — это чудовищно медленная и дорогая база данных. Платить эту цену имеет смысл только тогда, когда нужны его уникальные свойства — открытая запись без доверенного центра и непереписываемая история. Если участники друг другу доверяют, Postgres решит задачу в тысячу раз дешевле; блокчейн в корпоративном контуре между «своими» — почти всегда архитектурная ошибка.

Пощупаем лог из кода

Теория хороша, но лог, который нельзя почитать из кода, — это просто презентация. Прелесть публичного блокчейна в том, что для чтения не нужно ничего: ни регистрации, ни API‑ключа, ни кошелька. Это самая открытая база данных в мире.

Нам понадобится Node.js 20+ и одна библиотека — viem, современный TypeScript‑клиент для Ethereum (если вы встречали ethers.js или web3.js — это их наследник: строгие типы, минимум магии).

mkdir blockchain-peek && cd blockchain-peek
npm init -y && npm pkg set type=module
npm i viem typescript tsx
// peek.ts
import { createPublicClient, http, formatEther } from 'viem';
import { mainnet } from 'viem/chains';

// Подключаемся к публичной ноде Ethereum. Без регистрации и ключей:
// читать этот "лог" может кто угодно.
const client = createPublicClient({
  chain: mainnet,
  transport: http(), // публичный RPC-эндпоинт по умолчанию
});

// 1. Высота лога: номер последнего блока
const blockNumber = await client.getBlockNumber();
console.log('Последний блок:', blockNumber);

// 2. Читаем сам блок — "пачку записей" лога
const block = await client.getBlock({ blockNumber });
console.log('Транзакций в блоке:', block.transactions.length);
console.log('Хеш блока:        ', block.hash);
console.log('Хеш родителя:     ', block.parentHash); // та самая git-цепочка

// 3. Состояние-проекция: баланс произвольного адреса
const balance = await client.getBalance({
  address: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', // vitalik.eth
});
console.log('Баланс:', formatEther(balance), 'ETH');
npx tsx peek.ts

Запустите дважды с интервалом в полминуты — увидите, что номер блока вырос на 2–3: лог дописывается у вас на глазах, примерно каждые 12 секунд. parentHash каждого нового блока равен hash предыдущего — можете проверить и убедиться, что «цепочка как в git» — это не метафора, а буквальное устройство.

Обратите внимание на третий вызов: getBalance возвращает ту самую проекцию. Нода за миллисекунды отдаёт результат, который логически является свёрткой всей истории адреса с 2015 года — потому что держит materialized view и обновляет его с каждым блоком.

Что мы собрали

Соберём конструкцию целиком. Блокчейн — это:

  1. реплицированный append‑only лог (WAL/Kafka/git — выбирайте любимую аналогию)

  2. в котором состояние — проекция (event sourcing + materialized view)

  3. писать может кто угодно (поэтому консенсус вместо GRANT)

  4. запись платная (газ — цена вечного хранения и защита от спама)

  5. а UPDATE и DELETE не завезли (только компенсирующие транзакции)

Всё остальное в web3 — смарт‑контракты, токены, DeFi, NFT — это надстройки над этой пятёркой. Смарт‑контракт, забегая вперёд, — просто код, который живёт в том же логе и меняет состояние по тем же правилам: детерминированно, платно и без права на UPDATE.

Если после этой статьи блокчейн перестал быть «магией криптобратьев» и стал «интересно спроектированной базой со странными трейдоффами» — она свою задачу выполнила. Дальше в планах — разобрать кошельки и ключи (спойлер: «кошелёк» тоже ничего не хранит), JSON‑RPC‑ноды и первую транзакцию из кода.

UPD: поправил цифры TPS - спасибо @0xInnominatus