Kaspa работает на скорости 10 блоков в секунду и позволяет создавать блоки параллельно, поэтому в любой момент на вершине цепи нет единственного «последнего блока». Есть растущая куча блоков, ссылающихся друг на друга. И всё же кошелькам нужен один ответ на вопрос «какой у меня баланс», обозревателям — один ответ на «каково текущее состояние», а контрактам — один ответ на «какой путь расходования доступен прямо сейчас». Ответ в Kaspa — блок, который никогда не добывается: виртуальный блок. Это подробный технический разбор того, что такое виртуальный блок, как узел пересобирает его при каждом обновлении и как Kaspa Forge выводит из него состояние своих продуктов.
Зачем BlockDAG нужен «текущий блок»
В линейном блокчейне заголовок цепи очевиден: это блок с наибольшим объёмом работы, лежащий поверх предыдущего. Программное обеспечение привязывает к нему всё подряд — балансы, проверку мемпула, сложность, метки времени.
DAG лишает этого удобства. Майнеры публикуют блоки одновременно, и новый блок может ссылаться сразу на нескольких родителей. При 10 блоках в секунду постоянно существует несколько недавних блоков, которые ещё не ссылаются друг на друга. Если бы каждому приложению приходилось разбираться с этим графом напрямую, каждому кошельку, бирже и контракту понадобился бы собственный код консенсуса.
Ответ Kaspa — абстракция на уровне узла: воображаемый блок, ссылающийся на всё, что узел сейчас знает. Представьте делопроизводителя. DAG — это почтовая комната: тысячи писем в минуту, часть приходит не по порядку, часть ссылается на более ранние письма. Виртуальный блок — это единственная открытая страница реестра у делопроизводителя, непрерывно переписываемая на основе того, что сейчас лежит в почтовой комнате. Любой вопрос о «текущем состоянии мира» задаётся этой странице, а не почтовой комнате.
Виртуальный блок — это локально конструируемый воображаемый блок, указывающий на все текущие верхушки DAG узла. Его никогда не добывают, не подписывают и не рассылают по сети. Это скользящее лучшее предположение узла о настоящем состоянии реестра, пересчитываемое с приходом новых блоков.
Что из себя представляет виртуальный блок на самом деле
Три свойства имеют значение.
Он локальный. Каждый узел строит свой виртуальный блок из полученных блоков. Два узла с чуть разными наборами блоков получат чуть разные виртуальные блоки. Это не ошибка, а честное следствие распределённой системы с задержками. Узлы сходятся к одному результату, потому что рассылка быстро разносит блоки по TCP.
Он ведёт себя как блок. У виртуального блока есть выбранный родитель — так называемая выбранная верхушка, — который выбирает тот же алгоритм GHOSTDAG, что упорядочивает обычные блоки. Если идти от выбранной верхушки вниз по ссылкам «выбранный родитель», получится выбранная цепь. Именно выбранная цепь задаёт порядок событий в DAG. Поскольку точка зрения виртуального блока меняется с появлением новых верхушек, может меняться и выбранная цепь — это и есть реорганизация.
Всё, что измеряется «отсюда», измеряется от него. Синий счёт — это число синих блоков в прошлом узла с точки зрения виртуального блока. Окно корректировки сложности отсчитывается назад от виртуального блока. Порядок транзакций, который узел называет «текущим», — это порядок виртуального блока.
Пошагово: как узел пересобирает виртуальный блок
блоки приходят через рассылку между узлами (проверка PoW k-heavyhash)
│
▼
верхушки DAG: каждый блок без потомков
│
▼
┌──────────────────────────────────────────┐
│ виртуальный = воображаемый блок на всех │
│ верхушках │
│ выбранный родитель = выбранная верхушка │
│ (GHOSTDAG) │
└──────────────────────────────────────────┘
│
├── выбранная цепь → порядок событий
├── синий счёт → счётчик синих блоков
├── DAA-счёт → синие + слитые красные → эмиссия
└── окно DAA 2641 → сложность
1. Блоки приходят. Соседние узлы передают другим активным узлам хеши блоков и хеши транзакций мемпула; узел запрашивает недостающее и проверяет доказательство работы и структуру, прежде чем что-либо добавить в свой DAG. 2. GHOSTDAG задаёт порядок. Каждому блоку назначается выбранный родитель. Для любого блока цепи C его набор слияния — это множество блоков из прошлого C, которых нет в прошлом выбранного родителя C (набор слияния включает и самого выбранного родителя). Набор слияния сортируется по возрастанию синей работы, а при равенстве — лексикографически по хешу. 3. Виртуальный блок пересобирается. Теперь он указывает на все текущие верхушки. Его выбранным родителем становится новая выбранная верхушка, и из неё заново выводится выбранная цепь. 4. Счётчики движутся вместе с ним. Синий счёт, DAA-счёт, окно сложности и представление узла о текущем состоянии UTXO заново выводятся из нового виртуального блока. 5. И так непрерывно. Каждый принятый блок двигает виртуальный блок. При 10 блоках в секунду это происходит в среднем десять раз в секунду.
Именно в шаге 3 живут реорганизации. Если новый виртуальный блок выбирает другую выбранную верхушку, чем раньше, выбранная цепь немного смещается. В широком DAG мелкие реорганизации часты — но аргумент безопасности GHOSTDAG в том, что цепь *устойчива*: она стабилизируется очень быстро, оставляя нестабильным лишь короткий хвост. На практике: последние мгновения всегда предварительны, всё, что старше, скучно стабильно.
Синий счёт, DAA-счёт и окно за ними
Эти три счётчика легко перепутать, потому что все они выводятся с точки зрения виртуального блока.
- Синий счёт — число синих блоков в прошлом узла с точки зрения виртуального блока. «Синий» означает хорошо связанный: блок, который укрепляет безопасность, а не является отдельной веткой.
- DAA-счёт — синий счёт плюс красные блоки, которые к данному моменту были успешно слиты и вознаграждены. Именно этот счётчик управляет скоростью эмиссии через алгоритм корректировки сложности.
- Окно DAA — 2641 блок, отсчитываемый назад от виртуального блока, включая синие блоки и красные, попавшие в окно. Именно оно удерживает частоту блоков на целевом уровне. (В вики отмечено, что блоки вне этого окна — те, между майнингом и публикацией которых прошло примерно 45 минут, то есть сильно отставшие, плохо связанные блоки.)
Есть также окно медианного времени прошлого из 263 блоков. Поэтому метки времени блоков — плохие часы: окна на основе медианы устойчивы к манипуляциям, и именно поэтому ковенантам, которым нужно надёжное условие «не раньше», используют DAA-счёт как программируемые часы, а не системное время.
Награды тоже определяются с «виртуальной» точки зрения блока цепи: блок цепи C обходит свой набор слияния в порядке GHOSTDAG, добавляет по одному coinbase-выходу на каждый слитый синий блок (i-й выход платит майнеру i-го синего блока) и платит сам себе за слитые красные блоки, попавшие в его окно DAA. Блок, который так и не стал блоком цепи, порождает coinbase, отбрасываемый после стабилизации DAG. Для майнера или наблюдателя за платежами «мой блок найден» не то же самое, что «coinbase моего блока находится в зафиксированном порядке» — и именно виртуальный блок в конце концов сообщает, как обстоят дела.
Как Kaspa Forge читает состояние продуктов из виртуального блока
Каждая поверхность Kaspa Forge — это проекция DAG, увиденная из виртуального блока узла, и вокруг этого факта построен наш индексатор.
- Kaspa Safe — каждый депозит в хранилище становится собственным UTXO, запертым ковенантом. Живое состояние хранилища — сколько заперто, идёт ли задержка вывода, доступен ли путь аварийного ключа, — читается из набора UTXO, который в данный момент подразумевает виртуальный блок. Сама задержка выражена в DAA-счёте, поэтому она продвигается только тогда, когда реально продвигается DAG.
- Kaspa Escrow — сделки являются ончейн-конечными автоматами состояний. Интерфейс показывает, какой путь расходования сейчас открыт (возврат, получение, спор, тайм-аут), исходя из спроецированного состояния на виртуальном блоке; решает, что можно потратить, сам контракт эскроу, а не наш сервер.
- Депозит — залог ведёт себя так же: KAS блокируется ковенантом, а пути возврата / получения / спора — это пути контракта, триггеры которых читают те же часы на DAA-счёте.
- Маркетплейс — объявления никогда не держат деньги покупателя: чат приводит стороны к отдельной эскроу-сделке, а страница объявления лишь отображает проиндексированное состояние.
- Desk — считает балансы кошельков из набора UTXO виртуального блока. Ничто из этого не касается ключей: ключи остаются на устройстве, а виртуальный блок — модель чтения реестра, а не хранитель средств.
- Boards — публикации, ответы и чаевые являются ончейн-данными. Индекс, который их отображает, можно пересобрать: если виртуальный блок сдвигается и публикация выпадает из зафиксированного порядка, проекция пересчитывается, а не заплатывается.
- Arena — блэкджек — это публичная бета основной сети, где деньги лежат в UTXO комнат и игр, а игрок подписывает транзакции локально. Конечный автомат игры продвигается, когда виртуальный блок принимает подписанную транзакцию, а доказательство честности проверяется независимо от всего этого.
Ключевое инженерное следствие: раз виртуальный блок у заголовка предварителен, ничто, что из него выводится, нельзя считать постоянным. Проекции, учитывающие реорганизации, означают, что состояние можно пересобрать из DAG, а не заплатывать инкрементально, поэтому мелкая реорганизация стоит пересчёта, а не испорченной базы данных.
Если хотите увидеть эту модель чтения на чём-то конкретном: Kaspa Safe — ончейн-хранилище, где задержка вывода, аварийный ключ и сценарии наследования оцениваются по тому же движущемуся DAA-счёту, о котором рассказывается в этой статье. Контракты и инструменты открыты (github.com/Kaspaforge/kaspaforge), самотест прогоняет 25 проверок в виртуальной машине узла, а открытый CLI vaultctl работает с любым узлом Kaspa v2+ — так что мёртвый сайт не сможет дотянуться до денег, запертых в хранилище. Предыстория дизайна — в документации архитектуры Kaspa Forge.
Компромиссы и честные границы
«Подтверждено» — не значит «окончательно». Виртуальный блок движется, и мелкие реорганизации в широком DAG — норма. Любой продукт, показывающий состояние виртуального блока — балансы, статус сделки, раунды игры, — обязан переживать небольшой откат заголовка. Смягчение не в том, чтобы делать вид, будто этого не бывает, а в пересобираемых проекциях и разумных ожиданиях подтверждений.
Два узла — два виртуальных блока. Кратковременное расхождение узлов неизбежно. Для пользователей на практике это незаметно, но для интеграторов это означает, что вид вашего индексатора — это вид *вашего* узла. Запустить собственный узел — единственный способ владеть этим взглядом; Kaspa Forge держит собственную инфраструктуру именно по этой причине, и вы можете направить открытые инструменты на свой узел.
Мемпул — это не состояние. Транзакция, лежащая в мемпуле, не входит в набор UTXO виртуального блока. Она также не бессмертна: ретранслированные транзакции отбрасываются через 60 блоков без включения, а транзакции, отправленные по RPC, пересылаются неограниченно, пока узел не перезапустится. Если транзакция сделки или депозита ожидает подтверждения, интерфейс должен показывать *в ожидании*, а не *готово*.
Обрезка ограничивает историю. Эмиссию контролирует DAA-счёт, но старые данные DAG обрезаются. Исторические запросы («что случилось с этим UTXO три недели назад») требуют индексатора, который сохранил данные, — поэтому наши проекции хранят то, что нужно продуктам, вместо того чтобы полагаться на обрезанный узел.
PoW по-прежнему в основе. Всё вышеописанное имеет смысл лишь потому, что блоки несут настоящее доказательство работы k-heavyhash и распространяются между узлами. Виртуальный блок — это бухгалтерия; энергия, потраченная майнерами, — якорь, делающий откат этой бухгалтерии дорогим.
Статус продуктов, прямо и без прикрас: блэкджек Arena — публичная бета основной сети. Дайс — инженерная работа, его постоянная рабочая ветка выключена до независимого аудита. Дуэль, баккара и Permissionless Tokens — пункты дорожной карты, а не работающие сервисы: их нельзя попробовать, и в этой статье для них не описана ни одна работающая поверхность.
Протокольные определения, лежащие за всем этим — виртуальный блок, синий счёт, DAA-счёт, набор слияния и правила наград, — описаны в базе знаний разработчиков Kaspa wiki; это справочник, которым пользуемся мы.
Продолжить изучение
архитектура транзакций Kaspa Forge
Следующий шаг: перейти к документации протоколов
FAQ
Что такое виртуальный блок Kaspa?
Это локально конструируемый воображаемый блок, указывающий на все текущие верхушки DAG узла. Его никогда не добывают и не рассылают по сети. Это скользящее представление узла о текущем состоянии реестра.
Является ли виртуальный блок частью блокчейна?
Нет. Он существует только внутри представления конкретного узла. Поскольку каждый узел строит свой виртуальный блок из тех блоков, что у него есть, два узла могут кратковременно расходиться, пока их DAG не сойдутся.
В чём разница между синим счётом и DAA-счётом?
Синий счёт считает синие блоки в прошлом узла. DAA-счёт добавляет к ним красные блоки, которые были успешно слиты и вознаграждены. Именно DAA-счёт управляет графиком эмиссии Kaspa.
Почему выбранная цепь может меняться?
Выбранный родитель виртуального блока выбирается алгоритмом GHOSTDAG из текущих верхушек. По мере появления новых блоков этот выбор может сместиться — это и есть реорганизация цепи. GHOSTDAG держит такие реорганизации маленькими и кратковременными.
Становится ли платёж, подтверждённый виртуальным блоком, мгновенно окончательным?
Ни одно подтверждение не равно окончательности. DAG быстро стабилизируется вплоть до короткого хвоста, но программное обеспечение должно рассматривать свежее состояние виртуального блока как предварительное и явно обрабатывать реорганизации.
Хранит ли Kaspa Forge что-либо, читая состояние виртуального блока?
Нет. Ключи остаются на устройстве пользователя. Виртуальный блок — это лишь модель чтения реестра; хранилища, эскроу и депозиты живут в ончейн-контрактах, а не на нашем балансе.
Держите KAS там, где кражу можно отменить
Ковенант-сейф в мейннете Kaspa: ваши ключи, ваши правила, наш инструмент. Ончейн — бесплатно, навсегда.
Создать сейф
