Web3 и блокчейн Ончейн-управление: DAO, голоса, таймлоки и захват протокола
0%

Ончейн-управление: DAO, голоса, таймлоки и захват протокола

Ончейн-управление: DAO, голоса, таймлоки и захват протокола

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

Это тот случай, когда человек с бэкенд-опытом обычно недооценивает риск. В обычной системе «у кого есть доступ к проду» — вопрос эксплуатации: неприятно, но восстановимо. Здесь право обновления контракта — это право переписать логику, охраняющую чужие деньги, за одну транзакцию и без возможности откатить последствия. В статье о масштабировании мы уже видели крайнюю форму: идеальный ZK-роллап с безупречной математикой защищён ровно тремя подписями, если обновлять его контракты может мультисиг три из пяти.

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

1. Карта власти: кто вообще может что-то сделать

Начинать анализ надо не с токена управления, а с вопроса «какие действия способны навредить» и «кто их может совершить».

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

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

2. Как прочитать чужое управление за пятнадцать минут

Это не теория, а обязательная процедура перед интеграцией. Всё читается публично.

# 1. Прокси: адрес реализации и адрес админа лежат в фиксированных слотах EIP-1967
cast storage 0xПРОТОКОЛ 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc --rpc-url "$ETH_RPC_URL"
cast storage 0xПРОТОКОЛ 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103 --rpc-url "$ETH_RPC_URL"

# 2. Кто владелец и какие роли розданы
cast call 0xПРОТОКОЛ "owner()(address)" --rpc-url "$ETH_RPC_URL"
cast call 0xПРОТОКОЛ "hasRole(bytes32,address)(bool)" 0xDEFAULT_ADMIN_ROLE 0xКАНДИДАТ --rpc-url "$ETH_RPC_URL"

# 3. Если владелец — таймлок, узнаём реальную задержку и кто может предлагать
cast call 0xТАЙМЛОК "getMinDelay()(uint256)" --rpc-url "$ETH_RPC_URL"

# 4. Если предлагающий — Safe, смотрим порог и подписантов
cast call 0xSAFE "getThreshold()(uint256)" --rpc-url "$ETH_RPC_URL"
cast call 0xSAFE "getOwners()(address[])" --rpc-url "$ETH_RPC_URL"

# 5. Модули Safe обходят порог подписей — их наличие обязательно к проверке
cast call 0xSAFE "getModulesPaginated(address,uint256)(address[],address)" 0x0000000000000000000000000000000000000001 20 --rpc-url "$ETH_RPC_URL"

Дальше цепочка разматывается рекурсивно: владелец → таймлок → его PROPOSER_ROLE → мультисиг → подписанты. Останавливаться нужно на людях. Если в конце цепочки два адреса, у которых, судя по истории транзакций, одинаковый источник финансирования — «мультисиг два из трёх» стоит читать как «один человек».

Три вопроса, ответы на которые нужно получить обязательно: какова минимальная задержка на опасное действие, сколько независимых людей нужно скомпрометировать, есть ли путь в обход задержки (модуль Safe, роль гардиана, отдельный «экстренный» контракт).

3. Мультисиг: минимальная работающая форма

До всякого DAO почти всё управляется мультисигом, и чаще всего — Safe. Модель простая: контракт-кошелёк хранит список владельцев и порог m из n; чтобы исполнить транзакцию, нужно собрать m подписей по EIP-712 над структурой SafeTx (адрес, значение, calldata, операция, газовые параметры, nonce).

Что здесь регулярно ломается на практике:

  • Слепая подпись. Подписант видит в интерфейсе «перевод 10 ETH», а подписывает хеш структуры, содержимое которой не проверил. Именно так был устроен взлом Bybit в феврале 2025 года (≈1.5 млрд USD): подменённый интерфейс показывал одно, а подписывалась операция, менявшая логику кошелька через delegatecall. Защита — независимая сверка хеша и calldata на аппаратном устройстве и вторым инструментом; см. кошельки и ключи.
  • Ненезависимые подписанты. Пять ключей в одном офисе, в одном облаке или у одной команды — это один ключ с лишними шагами. Ronin в марте 2022 года потерял 624 млн USD, когда атакующий получил пять из девяти ключей валидаторов, четыре из которых контролировались одной организацией.
  • Модули. Модуль Safe исполняет транзакции в обход порога подписей. Это легитимный механизм (например, для рекуррентных платежей), но любой модуль — самостоятельный путь к деньгам, который нужно аудировать как основной.
  • Отсутствие ротации. Ушедший сотрудник в списке владельцев — типовая находка. Список подписантов должен пересматриваться так же регулярно, как доступы в прод.

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

4. Таймлок: задержка как право выхода

Таймлок не защищает от плохого решения — он даёт время его заметить. Операция сначала ставится в очередь, публикуется целиком (адрес, calldata, значение), и только по истечении задержки может быть исполнена.

Временная шкала предложения DAO: снимок голосов, голосование, таймлок и окно исполнения

TimelockController из OpenZeppelin — фактический стандарт. Устройство:

  • роли PROPOSER_ROLE (ставит в очередь), EXECUTOR_ROLE (исполняет; часто выдаётся всем), CANCELLER_ROLE (отменяет);
  • minDelay — минимальная задержка; операция идентифицируется хешем от параметров вместе с predecessor (зависимость от другой операции) и salt (различение одинаковых вызовов);
  • батчи: scheduleBatch/executeBatch — набор вызовов исполняется атомарно, иначе обновление из трёх шагов может застрять на середине.
// Постановка обновления в очередь: содержимое становится публичным немедленно.
bytes memory payload = abi.encodeCall(IProxyAdmin.upgradeAndCall, (proxy, newImpl, ""));
bytes32 salt = keccak256("upgrade-v3-risk-params");

timelock.schedule(
    address(proxyAdmin),  // цель
    0,                    // value
    payload,              // calldata — читаемо в эксплорере с этой секунды
    bytes32(0),           // predecessor: зависимости нет
    salt,
    timelock.getMinDelay() // задержка не меньше минимальной
);

// ...спустя minDelay секунд, если операцию не отменили
timelock.execute(address(proxyAdmin), 0, payload, bytes32(0), salt);

Антипаттерны, которые превращают таймлок в декорацию:

  1. Задержка меньше времени реакции. Час ночью в выходные — это ноль. Осмысленный минимум для действий с деньгами — двое суток; для L2 и мостов индустриальная норма выше.
  2. Роль PROPOSER у EOA. Тогда весь процесс защищён одним приватным ключом.
  3. Право менять minDelay без задержки. Классическая рекурсивная дыра: сначала снижаем задержку, потом делаем что угодно. minDelay обязан меняться через сам таймлок.
  4. Никто не смотрит очередь. Задержка полезна, только если существует мониторинг, который присылает уведомление о каждой поставленной операции с расшифрованным calldata (см. наблюдаемость dApp).
  5. Гардиан без границ. Право отмены обычно нормально; право исполнить в обход задержки — нет.

5. Токен голосования: почему вес берут из прошлого

Наивная реализация «вес голоса равен текущему балансу» ломается за одну транзакцию: занять токены флеш-займом, проголосовать, вернуть. Поэтому голосование обязано опираться на снимок в прошлом.

ERC20Votes из OpenZeppelin решает это чекпоинтами: при каждом изменении баланса или делегирования в массив записывается пара «момент времени → вес». Запрос getPastVotes(account, timepoint) бинарным поиском находит вес на нужный момент — O(log n) по числу чекпоинтов аккаунта.

Две важные детали. Первая: вес имеет только делегированный голос. Пока держатель не вызвал delegate (хотя бы на себя), его токены не голосуют вообще — это защищает от учёта монет на биржах, но обеспечивает вечно низкую явку. Вторая: единица времени задаётся ERC-6372 (clock() и CLOCK_MODE) — номер блока или timestamp. На L2 с плавающим временем блока это не формальность: голосование, отмеренное в блоках, там растягивается или сжимается непредсказуемо.

// Токен: балансы + чекпоинты весов + делегирование
contract ProtocolToken is ERC20, ERC20Permit, ERC20Votes {
    constructor() ERC20("Protocol", "PRT") ERC20Permit("Protocol") {}

    // ERC-6372: считаем время в секундах, а не в блоках — переносимо между сетями
    function clock() public view override returns (uint48) { return uint48(block.timestamp); }
    function CLOCK_MODE() public pure override returns (string memory) { return "mode=timestamp"; }
}

// Governor: параметры процесса и связь с таймлоком
contract ProtocolGovernor is
    Governor, GovernorSettings, GovernorCountingSimple,
    GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockControl
{
    constructor(IVotes token_, TimelockController timelock_)
        Governor("ProtocolGovernor")
        GovernorSettings(
            1 days,      // votingDelay: пауза до старта — за неё фиксируется снимок
            5 days,      // votingPeriod: сколько идёт голосование
            100_000e18   // proposalThreshold: минимальный вес, чтобы вообще предложить
        )
        GovernorVotes(token_)
        GovernorVotesQuorumFraction(4)          // кворум 4 % от всего предложения токена
        GovernorTimelockControl(timelock_)
    {}
}

Здесь каждый параметр — компромисс, который стоит проговорить вслух:

Параметр Слишком мало Слишком много
votingDelay нет времени изучить предложение и делегировать голос процесс тормозит на неделю
votingPeriod решают часовые пояса, а не участники реакция на проблему запаздывает
proposalThreshold спам предложениями, размывание внимания предлагать может только крупный держатель
кворум решение принимает горстка адресов ничего не проходит, протокол парализован
minDelay таймлока нет времени выйти нельзя быстро починить параметры

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

6. Жизненный цикл предложения

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

Голосование вне цепи. Полностью ончейн-процесс дорог: каждый голос — транзакция. Отсюда популярность Snapshot (docs.snapshot.box): подпись EIP-712 вместо транзакции, вес читается из снимка состояния на заданном блоке, газ нулевой. Честная оценка: Snapshot сам по себе ничего не исполняет. Результат приводит в действие мультисиг — значит, реальная модель безопасности определяется этим мультисигом, а не голосованием. Промежуточный вариант — оптимистичное исполнение (oSnap и подобные схемы на UMA): предложенный результат исполняется автоматически, если за окно оспаривания никто не поставил залог против; та же логика доказательств мошенничества, что у оптимистичных роллапов из статьи о масштабировании.

7. Атаки на управление

7.1. Захват флеш-займом

Канонический случай — Beanstalk, апрель 2022 года, около 182 млн USD. Схема была уязвима сочетанием двух свойств: вес голоса считался в момент голосования, а «экстренное» исполнение не требовало ожидания.

Что именно ломает эту атаку — и должно быть в любой схеме:

  1. Снимок весов в прошлом (getPastVotes на блоке до подачи предложения): токены, купленные сейчас, не голосуют.
  2. Таймлок без исключений: «экстренный» путь исполнения без задержки — это отсутствие таймлока.
  3. Порог предложения и период голосования, измеряемые днями, а не блоками.

7.2. Вредоносное предложение, которое выглядит нормальным

Голосующие читают заголовок, изредка — описание, и почти никогда — calldata. Отсюда класс атак «безобидное предложение». В мае 2023 года управление Tornado Cash было захвачено предложением, чей код на момент голосования выглядел безвредным: атакующий использовал selfdestruct и повторный деплой по тому же адресу через CREATE2, подменив логику после одобрения. Урок универсален: проверять нужно не исходник, приложенный к описанию, а фактический байткод по адресу, который будет вызван, и все его зависимости — включая возможность их подмены.

Практические защиты: запрет delegatecall в исполняемых операциях; проверка, что все вызываемые адреса имеют неизменяемый код; публикация расшифрованного calldata и дифа реализации перед голосованием; независимая симуляция предложения на форке мейннета до исполнения (Tenderly, forge script --fork-url).

7.3. Покупка голосов и рынки взяток

Если голос — это передаваемый токен, у него есть цена. Существуют легальные и открытые рынки: держатель делегирует голос и получает вознаграждение (Curve и Convex вокруг распределения эмиссии — самая известная экосистема такого рода). Технически это не атака, экономически — механизм, при котором решение принимает не тот, кто несёт последствия. Заимствование голосов вообще может стоить дешевле, чем владение: аренда токенов на срок голосования иногда дешевле их покупки, что делает атаку рациональной.

Смягчения: vote-escrow (вес растёт с длиной блокировки — Curve с veCRV; блокировка привязывает интерес голосующего к будущему), кворум и супербольшинство для критичных действий, отдельный «совет безопасности» с правом вето на явно враждебные решения, ограничение классов решений, доступных голосованию (см. раздел 10).

7.4. Прочее, что стоит держать в модели угроз

Вектор Суть Защита
Социальная инженерия подписантов фишинг, подменённый интерфейс, слепая подпись сверка calldata на устройстве, независимая проверка, разнесённые подписанты
Забытая роль у EOA деплойера остался DEFAULT_ADMIN_ROLE инвентаризация ролей и её проверка в CI
Кросс-чейн исполнение решение с L1 исполняется на L2 через мост доверие к мосту наследуется целиком (https://courses.digitable.life/post/web3/10-scaling/)
Апатия и низкий кворум решение принимает 1–2 % предложения токена кворум от делегированного веса, программы делегирования
Слитый ключ гардиана «экстренная» пауза как оружие ограничить гардиана только паузой, ротация ключей
Управление зависимостью вы зависите от параметров чужого протокола мониторинг их очереди таймлока, лимиты со своей стороны

8. Патологии: почему «управление сообществом» редко работает

Инженеру полезно смотреть на управление как на систему с обратными связями, а не как на политику.

  • Апатия. Голосование стоит времени и газа, а вес одного держателя ничего не решает — классическая рациональная неучастие. Явка в 3–7 % от предложения токена в крупных DAO — нормальное состояние.
  • Плутократия. «Один токен — один голос» означает, что решение принимает капитал. Это не всегда плохо (у капитала есть шкура на кону), но это точно не «децентрализация».
  • Делегаты. Профессиональные делегаты решают проблему явки и создают новую: концентрацию влияния у нескольких публичных лиц, чьи стимулы не совпадают со стимулами держателей.
  • Гудхарт. Как только «участие в голосованиях» становится метрикой, появляются участники, оптимизирующие метрику: голоса без чтения, предложения ради активности (см. метрики и закон Гудхарта).
  • Театр управления. Формально голосование есть, фактически исполнение — за мультисигом фонда. Спор вокруг AIP-1 в Arbitrum в марте 2023 года показателен: сообщество обнаружило, что средства были распределены до завершения голосования.

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

9. Сивилы и идентичность: почему нет «один человек — один голос»

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

Подход Как работает Чем платит
Токен-вес вес равен капиталу плутократия, но сивилы бессмысленны
Аттестации (EAS) доверенные стороны подписывают утверждения об адресе доверие к аттестующим, приватность
Веб доверия (BrightID и подобные) граф социальных связей атаки на граф, сложность входа
Биометрия (Worldcoin) доказательство уникальности человека приватность, оператор устройств, доступность
Репутация и SBT непередаваемые токены достижений «непередаваемое» ломается через контрактные кошельки
Квадратичное голосование n голосов стоят — меньшинству легче быть услышанным без сивил-устойчивости ломается тривиально

Квадратичное голосование заслуживает точной формулировки, потому что его часто рекламируют как решение: оно усиливает проблему сивил, а не решает её. Разделив капитал на сто адресов, участник получает не корень из суммы, а сто корней — то есть в десять раз больше влияния. Работоспособность квадратичных схем целиком зависит от качества фильтра личностей (так работает квадратичное финансирование Gitcoin с его Passport и постоянной борьбой с фермами адресов).

Второй сюжет — приватность голоса. Публичность голосования делает возможным подкуп: платящий видит, как вы проголосовали. Криптографический ответ известен — тайное голосование с доказательствами (MACI и схемы на ZK): голоса шифруются, корректность подсчёта доказывается, а доказать третьей стороне, как именно вы голосовали, невозможно. Обзорный текст Виталика Бутерина по этой теме — vitalik.eth.limo/general/2021/08/16/voting3.html; там же честный разбор пределов монетного голосования.

И отдельно: ENS — это имя, а не идентичность. Читаемое name.eth не подтверждает ничего, кроме факта регистрации; оно решает задачу UX (вместо сорока hex-символов) и упрощает фишинг похожими именами. Не стоит строить на нём модели доверия.

10. Казна, операции и внешний мир

  • Где лежит казна. Ответ «в контракте, которым владеет таймлок» — хороший. Ответ «на мультисиге фонда» — честный, но это не DAO. Ответ «часть на бирже» — открытая уязвимость.
  • Состав. Казна, состоящая из собственного токена, стоит ноль в тот момент, когда нужна: продажа обваливает цену того же токена. Диверсификация в стейблкоины — не роскошь, а требование к непрерывности разработки.
  • Выплаты. Разовые крупные переводы заменяют потоковыми выплатами и грантовыми комитетами с лимитом; для каждого лимита должен быть отдельный, более быстрый и менее опасный путь одобрения.
  • Отчётность. Все движения публичны, но не осмысленны без разметки: индексируйте казначейские адреса и события так же, как продуктовые (см. архитектуру dApp).
  • Юридическая обёртка. DAO без юридической формы в ряде юрисдикций трактуется как обычное товарищество с солидарной ответственностью участников — это не абстракция: дело CFTC против Ooki DAO (2022–2023) закончилось решением, в котором ответственность возлагалась на голосующих держателей токена. Обычная практика — фонд или LLC, представляющие DAO вовне. Это вопрос к юристам, но инженер обязан знать, что он существует.

Минимизация управления. Лучший ответ на вопрос «как защитить право обновления» — не иметь его там, где можно обойтись. Идея сформулирована в тексте Фреда Эрсама и Дэна Робинсона Governance Minimization и на практике выглядит так: ядро протокола иммутабельно, изменяемы только периферийные параметры, у каждого параметра есть жёсткие границы прямо в коде (порог ликвидации не может быть установлен ниже 50 % никаким голосованием), а новые версии выкатываются как отдельные развёртывания, в которые пользователь мигрирует сам. Это сильно менее удобно и радикально сокращает поверхность атаки.

11. Чек-лист проверки управления перед интеграцией

  1. Кто владелец каждого контракта, с которым вы взаимодействуете (проверено чтением слотов и owner(), а не документацией).
  2. Есть ли таймлок, какова минимальная задержка, кто может ставить в очередь и кто исполнять.
  3. Существует ли путь в обход таймлока: модули Safe, «экстренные» контракты, гардиан с расширенными правами.
  4. Сколько независимых людей нужно скомпрометировать, чтобы получить контроль; насколько независимы подписанты на самом деле.
  5. Берётся ли вес голоса из прошлого блока (getPastVotes) и какова длина голосования.
  6. Каков кворум в абсолютных числах и сколько адресов реально его составляют — распределение токена по топ-10 держателей важнее процентов в документации.
  7. Может ли голосование менять параметры без ограничений, или в коде есть жёсткие границы.
  8. Есть ли кросс-чейн исполнение и через какой мост.
  9. Мониторится ли очередь таймлока — и настроен ли у вас алерт на постановку операции в очередь у чужого протокола, от которого вы зависите.
  10. Что произойдёт с вашими средствами и вашим приложением, если управление будет захвачено сегодня: какие лимиты, паузы и пути выхода есть с вашей стороны.

12. Частые заблуждения

  • «Есть токен управления — значит, децентрализовано». Токен управления совместим с полной централизацией исполнения. Смотрите на владельцев контрактов, а не на голосования.
  • «Мультисиг безопаснее одного ключа». Только если подписанты независимы, а транзакции проверяются. Пять слепых подписей хуже одного внимательного ключа.
  • «Таймлок задерживает злоумышленника». Таймлок ничего не задерживает без наблюдателя. Он покупает вам время, только если кто-то смотрит.
  • «Голосование в цепи защищено криптографией». Криптографией защищён подсчёт. Что именно исполняется — вопрос внимательности читающих calldata.
  • «Снапшот-голосование — это ончейн-управление». Это опрос, исполняемый людьми.
  • «Иммутабельность — всегда лучше». Иммутабельный протокол не чинится. Это осознанный размен, а не универсальная добродетель.
  • «Плохое управление — не техническая проблема». Это самая техническая из проблем: она выражается в адресах, ролях и задержках, и все они читаются публично.

Мини-итог

  1. Реальную модель доверия протокола определяет не байткод, а список тех, кто может его изменить, и время, за которое они это сделают.
  2. Карта власти строится от опасных возможностей (обновление, параметры, оракул, казна, эмиссия, пауза), а не от токена управления.
  3. Мультисиг — рабочая честная форма; его слабые места операционные: слепая подпись, зависимые подписанты, модули в обход порога, отсутствие ротации.
  4. Таймлок не запрещает вредное решение, а даёт пользователю время выйти. Без мониторинга очереди он бесполезен, а без запрета на обходные пути — фиктивен.
  5. Вес голоса обязан браться из прошлого: снимок весов плюс задержка — это то, что делает захват флеш-займом невозможным.
  6. Атака на управление обычно не ломает криптографию: она эксплуатирует невнимательность к calldata, низкий кворум, покупку голосов или человека с ключом.
  7. Равный вес на человека требует внешней устойчивости к сивилам; квадратичные схемы без такого фильтра ухудшают ситуацию, а не улучшают.
  8. Лучшее управление — то, которого мало: иммутабельное ядро, жёсткие границы параметров в коде, миграция вместо обновления.

Источники

Что дальше

Трек закончен. Мы прошли путь от хеш-цепочки и подписи до работающего приложения и того, кто им управляет: как устроен блок, криптография, консенсус, EVM, контракты и их безопасность, ключи, токены, хранилища, масштабирование, архитектура dApp, финансовые примитивы и управление ими.

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

  • Распределённые системы — согласованность, консенсус, отказы и время. Половина сложности этого трека родом отсюда.
  • Базы данных — индексы, планы запросов, транзакции: без этого свой индексатор не построить.
  • Архитектурные паттерны — CQRS, event sourcing, устойчивость: индексатор и проекции ровно об этом.
  • Фронтенд — состояние, загрузка данных, обработка ошибок; интерфейс dApp остаётся обычным фронтендом с необычной моделью задержек.
  • Дата-инженерия — пайплайны, идемпотентность, качество данных: индексация цепи по сути ETL.
  • Теория игр и системное мышление — стимулы, равновесия и обратные связи: язык, на котором вообще имеет смысл обсуждать консенсус, ликвидации и управление.
  • Моделирование угроз, DevOps и тестирование — эксплуатация узлов, секреты, мониторинг и способы проверять систему, в которой нельзя нажать «отменить».

Общая карта портала и порядок изучения — в дорожной карте.

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

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

Доска запросов