Kaspa Forge
Разбор

Подтверждения платежей Kaspa: от события BlockDAG к бизнес-вебхуку

22 августа 2026 Автор — ИИ-команда OfficeForge · проверено командой 14 мин чтения
Подтверждения платежей Kaspa: от событий BlockDAG к вебхукам

Мерчант, принимающий KAS, сталкивается с проблемой, которую Bitcoin решил много лет назад, — и с ещё более сложной, которой у Bitcoin никогда не было. Транзакции Kaspa не содержат поля для метаданных, нет OP_RETURN, нет способа встроить ссылку на заказ прямо в перевод. В то же время BlockDAG Kaspa производит блоки каждые 100 мс, а значит, «подтверждение» не соответствует линейной цепочке блоков Bitcoin. Платёжная система для Kaspa должна решить две задачи одновременно: атрибуция (к какому счёту относится этот платёж?) и финальность (когда безопасно отгружать товар?).

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

Проблема атрибуции: один адрес на счёт

В Bitcoin мерчанты иногда переиспользуют один адрес и различают платежи по данным OP_RETURN или сумме. В Kaspa такого поля нет. Элегантное решение — HD-деривация (иерархически детерминированная): генерация уникального адреса для каждого счёта на основе одного расширенного публичного ключа.

Процесс:

1. Мерчант владеет xpub (расширенным публичным ключом). Соответствующий приватный сид хранится офлайн или в отдельной защищённой среде — платёжный сервер никогда его не видит. 2. Для каждого нового заказа сервер вызывает функцию деривации со следующим последовательным индексом:

address_0 = derive(xpub, index=0)   → kaspa:qz...
address_1 = derive(xpub, index=1)   → kaspa:qp...
address_2 = derive(xpub, index=2)   → kaspa:qr...

3. Индекс сохраняется вместе с заказом. Поскольку каждый индекс порождает уникальный адрес, любой UTXO, появляющийся на этом адресе, однозначно является оплатой за конкретный заказ.

Это то же семейство деривации, что используется в HD-кошельках Bitcoin (BIP-32/44), адаптированное под формат адресов Kaspa. Ключевое свойство: сервер может генерировать адреса, но не может тратить полученные средства, потому что никогда не владеет приватным ключом. Это некастодиально по конструкции.

Определение

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

Наблюдение за BlockDAG: опрос vs. подписка

После выпуска адреса системе необходимо обнаруживать входящие платежи. Существует два подхода:

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

В продакшен-решении используется опрос. Наблюдатель ведёт список активных адресов («список наблюдения»), каждый из которых привязан к ID заказа, ожидаемой сумме и времени истечения. В каждом цикле он запрашивает у узла utxoindex — индекс всех непотраченных выходов транзакций, сгруппированных по адресам, который поддерживается узлом Kaspa. utxoindex должен быть включён на узле; во всех конфигурациях он включён по умолчанию не всегда.

# Псевдокод: цикл наблюдателя
for entry in watchlist:
    utxos = node.getUtxosByAddresses([entry.address])
    received = sum(utxo.amount for utxo in utxos)
    confirmations = current_blue_score - utxo.block_blue_score
    if received >= entry.expected and confirmations >= THRESHOLD:
        fire_callback(entry)

Компромисс здесь — задержка: опрос каждые N секунд означает, что обнаружение отстаёт от реального события BlockDAG максимум на N секунд. Для системы, обрабатывающей счета с 20-минутными окнами, это приемлемо. Для биржи в реальном времени больше подошёл бы гибридный подход (подписка плюс периодическая сверка).

Что означает «подтверждение» в BlockDAG

Здесь Kaspa принципиально отличается от Bitcoin.

В Bitcoin транзакция считается подтверждённой, когда она попадает в блок, и каждый последующий блок добавляет одно подтверждение. Цепочка линейна; глубина однозначна.

В протоколе GHOSTDAG Kaspa блоки образуют направленный ациклический граф (DAG), а не единую цепочку. Каждый блок имеет выбранный родительский блок (выбранный алгоритмом GHOSTDAG), и последовательность выбранных родителей формирует «выбранную цепочку». Но параллельно существуют множество других блоков — это блоки слияния, которые выбранная цепочка в конечном счёте поглощает.

Вики Kaspa определяет две ключевые метрики:

  • Blue score: количество *синих* (хорошо связанных) блоков в прошлом данного блока. Блок считается «синим», если он хорошо интегрирован в DAG — он вносит вклад в безопасность консенсуса. Blue score — это аналог высоты блока в Bitcoin, но нативный для DAG.
  • DAA score: blue score плюс количество красных (плохо связанных) блоков, которые были успешно объединены и вознаграждены. Эта метрика управляет графиком эмиссии.

Для подтверждения платежей Kaspa актуальной метрикой является blue score. Когда UTXO транзакции появляется в блоке с blue score B, а текущий виртуальный (концевой) blue score равен V, количество подтверждений равно V - B. Система ждёт, пока эта разница не достигнет настраиваемого порога, и только тогда считает платёж финальным.

Почему blue score, а не общее количество блоков? Потому что синие блоки — это те, которые алгоритм GHOSTDAG считает хорошо связанными и надёжными. Красные блоки — те, которые опоздали или плохо разошлись по сети, — объединяются, но несут меньший вес консенсуса. Подсчёт только синих блоков для подтверждений даёт более точную меру того, на глубоко транзакция погружена в консенсусную структуру DAG.

При текущей скорости Kaspa в 10 блоков в секунду даже скромный порог в 10–30 подтверждений по blue-score проходит за 1–3 секунды. Это на порядки быстрее, чем блоки Bitcoin примерно раз в 10 минут, но порог всё равно должен быть ненулевым, чтобы защититься от небольших реорганизаций DAG, которые GHOSTDAG допускает.

Определение

Реорганизация DAG: В отличие от редких реорганизаций цепочки в Bitcoin, BlockDAG Kaspa испытывает частые небольшие реорганизации, когда выбранная концевая вершина меняется. GHOSTDAG гарантирует, что они неглубокие и быстро стабилизируются, поэтому небольшого порога подтверждений по blue-score достаточно для финальности платежа.

Вебхук: от обнаружения к бизнес-событию

Как только наблюдатель определяет, что подтверждение платежа Kaspa достигнуто, он должен уведомить бизнес-уровень. Это и есть вебхук KAS-платежа — HTTP-обратный вызов с деталями платежа.

Полезная нагрузка вебхука включает:

{
  "order_id": "ord_abc123",
  "address": "kaspa:qz...",
  "txid": "7342e267...",
  "received_sompi": 199000000000,
  "daa_score": 12345678
}

Три проектных решения обеспечивают надёжность:

1. HMAC-подпись. Вебхук содержит криптографическую подпись (HMAC-SHA256) над полезной нагрузкой, используя общий секрет, известный только наблюдателю и бизнес-серверу. Получатель проверяет подпись перед обработкой. Это предотвращает подделку обратных вызовов для ложного выполнения заказов.

2. Идемпотентность по ID заказа. Конечная точка обратного вызова спроектирована так, что повторное получение одного и того же order_id даёт тот же результат — второй вызов возвращает ответ dedup: true и не выпускает вторую лицензию и не отправляет второе письмо. Это важно, потому что при развёртывании в два экземпляра (см. ниже) оба наблюдателя могут независимо обнаружить один и тот же платёж.

3. Идентификация через User-Agent. Практический урок: некоторые обратные прокси и CDN блокируют запросы со стандартными строками User-Agent из библиотек. Отправитель вебхука устанавливает собственный заголовок User-Agent, чтобы избежать молчаливых отказов 403 на сетевом уровне.

Отказоустойчивость с двумя экземплярами

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

Решение — активно-активная пара экземпляров с разделёнными индексами деривации:

Экземпляр A: генерирует адреса с нечётными индексами (1, 3, 5, 7, ...)
Экземпляр B: генерирует адреса с чётными индексами (0, 2, 4, 6, ...)

Оба экземпляра используют один и тот же xpub, но с шагом и смещением, гарантирующим, что они никогда не создадут одинаковый адрес. Оба регистрируют свои адреса в списке наблюдения бизнес-уровня. Если один экземпляр выходит из строя, другой продолжает обрабатывать свои адреса без перебоев.

Конечная точка вебхука на бизнес-уровне идемпотентна по ID заказа, поэтому если оба экземпляра независимо обнаружат и сообщат об одном и том же граничном платеже, дубликат будет безвредно поглощён.

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

Частичные платежи и переплаты

Транзакции Kaspa не содержат поля «сумма счёта». Клиент видит адрес и ожидаемую сумму, но ничто не обязывает его отправить именно эту сумму. Система должна обрабатывать три случая:

  • Точный платёж: получено ≥ ожидаемого (с небольшим допуском на округление) → подтвердить и выполнить заказ.
  • Недоплата: получено < ожидаемого → сообщить о недостаче. Клиент может отправить вторую транзакцию на тот же адрес. Наблюдатель суммирует все UTXO на адресе, поэтому много-транзакционные платежи работают естественным образом.
  • Переплата: получено > ожидаемого → выполнить заказ. Излишек не возвращается автоматически (транзакции Kaspa необратимы; возвраты требуют ручного вмешательства).

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

Как Kaspa Forge использует эту схему

Инфраструктура подтверждения платежей, описанная выше, обеспечивает собственный конвейер продаж Kaspa Forge — приём KAS за продукты наряду с традиционными платёжными каналами. Архитектура следует той же философии самостоятельного хранения, которая пронизывает каждый продукт Kaspa Forge:

  • Kaspa Safe использует ковенант-контракты on-chain, где ключи пользователя никогда не покидают его устройство.
  • Kaspa Escrow блокирует средства в on-chain-контракте, а не у кастодиального посредника.
  • Deposit применяет ту же схему залога на основе ковенантов.
  • Desk хранит все ключи в зашифрованном профиле браузера; сервер никогда их не видит.

Платёжная система расширяет этот принцип на мерчант-уровень: сервер хранит только xpub, генерирует адреса, наблюдает за BlockDAG и отправляет вебхуки. Ни на каком этапе он не контролирует полученные средства. Если платёжный сервер исчезнет, средства остаются доступными тому, кто владеет сидом. Та же двухсервисная архитектура — тонкий бизнес-сервер и крипто-ориентированный шлюз — изолирует компилируемое Rust-колесо и весь криптографический материал от общего стека приложения.

Та же некастодиальная архитектура с собственным узлом, которая обеспечивает подтверждение платежей Kaspa, лежит в основе каждого продукта Kaspa Forge — от хранилищ на ковенантах Safe до P2P-сделок Escrow. Изучите полную архитектуру, чтобы увидеть, как on-chain-контракты заменяют кастодиальное доверие на каждом уровне.

Создать сейф

Компромиссы и честные ограничения

Ни одно решение не обходится без компромиссов. Вот реальные:

Задержка опроса. Наблюдатель опрашивает каждые несколько секунд, а не на каждый блок. Обнаружение отстаёт от BlockDAG на величину до интервала опроса. Для счетов с 20-минутными окнами это нормально. Для высокочастотной торговли или мгновенной розничной оплаты — нет.

Отсутствие push от узла. wRPC-интерфейс узла Kaspa поддерживает подписки, но продакшен-система их избегает, потому что обработка переподключений добавляет сложность и риск пропуска событий при обрыве сокета. Опрос проще и самовосстанавливается, ценой задержки.

Ручные возвраты. Транзакции Kaspa необратимы. Если клиент переплатил или оплатил просроченный счёт, система помечает это для ручного решения. Механизма возврата на уровне блокчейна нет.

Волатильность курса. Курс KAS/USD фиксируется при создании заказа с буфером в 2%. Если цена Kaspa изменится более чем на 2% в окне подтверждения, мерчант поглощает разницу. Это осознанный компромисс: больший буфер привёл бы к переплате клиентов; меньший — подверг бы мерчанта риску.

Карантин адресов после истечения. Адрес просроченного счёта помещается в карантин и никогда не используется повторно. Это предотвращает путаницу, если опоздавший платёж поступит на адрес, который был переназначен новому заказу. Опоздавшие платежи по-прежнему обнаруживаются и помечаются для ручной обработки.

Зависимость от utxoindex. Весь наблюдатель зависит от того, что utxoindex на узле включён и полностью синхронизирован. Во время начальной загрузки блоков (IBD) индекс недоступен, поэтому платёжная система не может запуститься, пока узел полностью не догонит сеть.

Итог: полный жизненный цикл

Клиент нажимает «Оплатить KAS»
  → Сервер генерирует уникальный адрес из xpub (следующий индекс)
  → Фиксирует курс KAS/USD, устанавливает 20-минутное окно
  → Возвращает адрес + сумму + QR-код (kaspa: URI)
  → Клиент отправляет KAS из своего кошелька

Наблюдатель опрашивает getUtxosByAddresses каждые N секунд
  → Обнаруживает UTXO на адресе счёта
  → Суммирует полученные средства по всем UTXO
  → Проверяет порог подтверждений по blue-score
  → Если получено ≥ ожидаемого И подтверждений ≥ порога:
      → Отправляет HMAC-подписанный POST-вебхук на бизнес-сервер
      → Бизнес-сервер проверяет подпись
      → Выпускает лицензию / выполняет заказ (идемпотентно по order_id)

Весь процесс — от HD-деривации адресов через наблюдение за BlockDAG до идемпотентного вебхука — представляет собой универсальную схему приёма платежей Kaspa без кастодиальных рисков. Высокая скорость блоков BlockDAG делает подтверждения быстрыми; метрика blue-score в GHOSTDAG делает их осмысленными; а паттерн HD-деривации решает атрибуцию без каких-либо метаданных в самой транзакции. Для мерчант-платежей Kaspa это продакшен-основа: никаких сторонних процессоров, никаких кастодиальных рисков, никаких хаков на уровне протокола — только узел, наблюдатель и подписанный обратный вызов.

Маршрут по теме

Продолжить изучение

собственная инфраструктура транзакций Kaspa

Связанные материалы

Следующий шаг: проверить границы реализации в документации

FAQ

Сколько подтверждений нужно для платежа в Kaspa?

Порог настраивается для каждого развёртывания. При скорости Kaspa в 10 блоков в секунду даже 10–30 подтверждений по blue-score проходят за 1–3 секунды. Точное число зависит от вашей толерантности к риску.

Что такое blue score и почему он важен для платежей?

Blue score — это количество синих (хорошо связанных) блоков в прошлом данного блока в структуре GHOSTDAG. Он заменяет линейную высоту блока из Bitcoin в качестве метрики подтверждения в BlockDAG Kaspa.

Что произойдёт, если клиент отправит сумму меньше, чем указано в счёте?

Система обнаружит частичный платеж, сообщит о недостаче и дождётся доплаты на тот же адрес. Наблюдатель суммирует все UTXO на адресе, поэтому много-транзакционные платежи работают естественным образом.

Поддерживает ли Kaspa метаданные платежей или OP_RETURN?

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

Могу ли я создать аналогичный вебхук подтверждений для своего проекта?

Да. Описанная схема — деривация из xpub, опрос UTXO через utxoindex, порог blue-score, HMAC-подписанный обратный вызов — является универсальным решением. Вам понадобится узел Kaspa с включённым utxoindex и небольшой сервис-наблюдатель.

Является ли платёжная система кастодиальной?

Нет. Сервер хранит только расширенный публичный ключ (xpub). Приватный сид ни покидает защищённую среду оператора. Сервер генерирует адреса, но не может потратить полученные средства.

⚒

Эту статью собрала, написала и оформила ИИ-команда OfficeForge — те же ИИ-сотрудники, что построили и ведут Kaspa Forge. Направляет основатель, проверено командой.

Некастодиально · открытый код

Держите KAS там, где кражу можно отменить

Ковенант-сейф в мейннете Kaspa: ваши ключи, ваши правила, наш инструмент. Ончейн — бесплатно, навсегда.

Создать сейф