Перейти к содержанию
Learning Platform
Продвинутый
30 минут
HTLC Commitment TX Revocation Preimage Timelock Penalty Мультихоп

Требуемые знания:

  • 09-lightning-network

Payment Channels и HTLC

Зачем это нужно в блокчейне

Как Alice платит Bob через Lightning, если у них нет прямого канала? Через посредника Carol — и HTLC (Hash Time-Locked Contract) гарантирует, что либо платёж пройдёт полностью, либо все средства вернутся. Атомарность без блокчейна.

В предыдущем уроке мы рассмотрели общий жизненный цикл платежного канала. Теперь разберём внутренние механизмы: как именно устроены commitment-транзакции, почему мошенничество наказывается потерей всех средств, и как HTLC обеспечивает атомарную маршрутизацию через цепочку каналов.

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

Структура Commitment TX

Пройдите пошагово структуру commitment-транзакции — от базовой схемы до наказания за мошенничество:

Структура Commitment TX и отзыв
0
1
2
3
Шаг 0: Структура Commitment TX
Каждая commitment TX имеет два выхода: to_local (свои средства, с таймлоком) и to_remote (средства партнёра, без задержки). Таймлок нужен, чтобы партнёр мог оспорить мошенничество.
Commitment TX (версия Alice)
to_local4 BTC
Таймлок 144 блока
to_remote6 BTC
Мгновенный доступ
to_local: ваши средства, но вы должны ждать (OP_CHECKSEQUENCEVERIFY). to_remote: средства партнёра, доступны сразу.

Два выхода: to_local и to_remote

Каждая commitment TX имеет минимум два выхода:

Commitment TX (версия Alice):
├── Output 0: to_local  (Alice, 4 BTC)  -- С ТАЙМЛОКОМ!
│   └── OP_IF
│       <revocation_pubkey> OP_CHECKSIG       # Bob может забрать, если TX отозвана
│   OP_ELSE
│       <to_self_delay> OP_CHECKSEQUENCEVERIFY OP_DROP
│       <alice_delayed_pubkey> OP_CHECKSIG     # Alice может забрать после задержки
│   OP_ENDIF

└── Output 1: to_remote (Bob, 6 BTC)    -- БЕЗ ЗАДЕРЖКИ
    └── <bob_pubkey> OP_CHECKSIG              # Bob может забрать сразу

Почему асимметрия необходима:

  • Если Alice публикует commitment TX, она получает свои средства ТОЛЬКО после таймлока (144 блока, ~1 день)
  • Bob получает свои средства СРАЗУ
  • За это время Bob может проверить: «Это последнее состояние или старое?»

Зеркальная структура

Alice и Bob имеют разные версии одной commitment TX:

Версия AliceВерсия Bob
to_localAlice (таймлок 144 блока)Bob (таймлок 144 блока)
to_remoteBob (сразу)Alice (сразу)

В версии Alice таймлок стоит на ЕЁ выходе. В версии Bob — на ЕГО выходе. Кто публикует TX — тот и ждёт.

Механизм отзыва

Когда состояние канала обновляется (новый платёж), старые commitment TX нужно «отозвать». Иначе любая сторона может опубликовать выгодное ей старое состояние.

Как работает отзыв

  1. Alice и Bob создают новую commitment TX #(N+1)
  2. Alice передаёт Bob ключ отзыва для своей старой commitment TX #N
  3. Bob передаёт Alice ключ отзыва для своей старой commitment TX #N
  4. Теперь публикация старой TX #N позволит партнёру забрать ВСЕ средства

Ключ отзыва — это приватный ключ, который позволяет потратить to_local выход старой commitment TX немедленно, без ожидания таймлока.

Сценарий отзыва (упрощённый скрипт):
OP_IF
    <revocation_pubkey>    # Партнёр может забрать НЕМЕДЛЕННО
    OP_CHECKSIG
OP_ELSE
    <delay>                # Владелец ждёт 144 блока
    OP_CHECKSEQUENCEVERIFY
    OP_DROP
    <owner_pubkey>
    OP_CHECKSIG
OP_ENDIF

Наказание за мошенничество

Это — центральный механизм безопасности платежных каналов.

Сценарий

  1. Канал открыт: Alice 5, Bob 5
  2. Alice платит Bob 3 BTC. Новое состояние: Alice 2, Bob 8
  3. Alice решает обмануть и публикует СТАРУЮ commitment TX: Alice 5, Bob 5

Что происходит

  1. Bob обнаруживает старую TX в блокчейне (или его watchtower обнаруживает)
  2. to_local выход Alice имеет таймлок 144 блока — Alice ждёт
  3. Bob использует ключ отзыва и забирает to_local выход Alice НЕМЕДЛЕННО
  4. Bob также получает to_remote (свои 5 BTC сразу)

Результат: Bob забирает ВСЕ 10 BTC. Alice теряет всё.

Даже если Alice хотела получить 5 BTC вместо 2 BTC — она потеряла 2 BTC полностью. Мошенничество экономически иррационально: риск потерять всё ради попытки получить немного больше.

Экономическая безопасность: Lightning Network не полагается на «честность» участников. Она создаёт экономический стимул: мошенничество строго наказывается. Это game-theoretic security — безопасность через теорию игр.

HTLC: Hash Time-Locked Contract

HTLC — это условный платёж, который объединяет два механизма:

МеханизмНазначениеBitcoin Script
Hash LockПлатёж выполняется при раскрытии прообразаOP_HASH160 <H> OP_EQUAL
Time LockЕсли не раскрыт вовремя, средства возвращаются<timeout> OP_CHECKLOCKTIMEVERIFY

Зачем нужен HTLC?

В прямом канале (Alice ↔ Bob) commitment TX достаточно. Но для мультихоп-платежей (Alice -> Carol -> Bob) нужен механизм, который гарантирует:

  • Либо ВСЕ промежуточные платежи проходят
  • Либо НИ ОДИН не проходит
  • Никакой посредник не может украсть средства

HTLC обеспечивает эту атомарность через единый секрет — прообраз R.

Мультихоп-платёж через HTLC

Пройдите полный сценарий мультихоп-платежа Alice -> Carol -> Bob:

HTLC: атомарный мультихоп-платёж
0
1
2
3
4
5
T
Шаг 0: Подготовка
Bob генерирует случайный прообраз R и вычисляет хеш H = SHA-256(R). Bob отправляет H Alice (по защищённому каналу). R остаётся секретом Bob.
Хеш H = SHA-256(R)a4b9...7d21
Прообраз R?????? (секрет Bob)
Alice-->Carol
Нет HTLC
Сумма: -
Carol-->Bob
Нет HTLC
Сумма: -
H -- публичный хеш, R -- секретный прообраз. Только тот, кто знает R, может «разблокировать» HTLC.

Поток платежа

Прямое направление (создание HTLC):
Alice ---[HTLC, 48ч]---> Carol ---[HTLC, 24ч]---> Bob

Обратное направление (раскрытие прообраза R):
Alice <---[R]--- Carol <---[R]--- Bob

Обратите внимание: HTLC создаются в прямом направлении (от отправителя к получателю), а прообраз R раскрывается в обратном направлении (от получателя к отправителю).

Почему таймлоки уменьшаются?

Это критически важная деталь для безопасности:

КаналТаймлокПочему
Alice -> Carol48 часовAlice имеет больше времени — она дальше всех от Bob
Carol -> Bob24 часаCarol имеет меньше времени — она ближе к Bob

Сценарий безопасности:

  1. Carol узнаёт R от Bob (в течение 24 часов)
  2. У Carol остаётся ещё 24 часа (48 - 24 = 24) чтобы передать R Alice
  3. Если Carol задержится — HTLC Alice->Carol истечёт, и Alice не потеряет средства

Если таймлоки были бы одинаковыми (оба 48ч):

  • Carol узнаёт R от Bob в последний момент (на 47-м часу)
  • Carol передаёт R Alice, но HTLC Alice->Carol уже истёк
  • Alice потеряла бы средства!

Убывающие таймлоки гарантируют, что каждый промежуточный узел имеет достаточно времени для передачи прообраза.

Timeout-сценарий

Что если Bob отказывается раскрыть R?

  1. HTLC Carol->Bob истекает через 24 часа. Carol получает средства обратно.
  2. HTLC Alice->Carol истекает через 48 часов. Alice получает средства обратно.
  3. Никто ничего не теряет. Платёж просто не прошёл.

Это и есть атомарность HTLC: либо R раскрыт и ВСЕ HTLC исполнены, либо R не раскрыт и ВСЕ HTLC истекают.

Алгоритмический уровень

HTLC output script (упрощённый)

# Выход HTLC в commitment TX
OP_IF
    # Путь раскрытия прообраза (recipient path)
    OP_HASH160 <H> OP_EQUAL
    <recipient_pubkey> OP_CHECKSIG
OP_ELSE
    # Путь таймаута (sender path)
    <timeout> OP_CHECKLOCKTIMEVERIFY OP_DROP
    <sender_pubkey> OP_CHECKSIG
OP_ENDIF

Путь 1 (получатель): Если recipient знает R такой что SHA-256(R) == H, он подписывает и забирает средства.

Путь 2 (отправитель): Если timeout истёк и R не был раскрыт, sender подписывает и возвращает средства себе.

Псевдокод маршрутизации

def route_payment(sender, receiver, amount, route):
    """
    Маршрутизация платежа через HTLC.
    route = [sender, hop1, hop2, ..., receiver]
    """
    # 1. Receiver генерирует прообраз
    R = random_bytes(32)
    H = sha256(R)

    # 2. Создаём HTLC по маршруту (прямое направление)
    base_timeout = 48  # часов
    for i in range(len(route) - 1):
        timeout = base_timeout - i * 24  # убывающий таймлок
        create_htlc(
            channel=route[i] <-> route[i+1],
            amount=amount,
            hash_lock=H,
            timeout=timeout
        )

    # 3. Receiver раскрывает R (обратное направление)
    for i in range(len(route) - 1, 0, -1):
        reveal_preimage(
            channel=route[i-1] <-> route[i],
            preimage=R
        )

    # 4. Все HTLC исполнены атомарно
    return "Payment complete"

Математический уровень: атомарность HTLC

Почему мультихоп-HTLC атомарен (all-or-nothing)

Утверждение: Если существует маршрут Alice -> C1 -> C2 -> … -> Bob с HTLC, привязанными к одному хешу H, то либо все HTLC исполнены, либо ни один.

Доказательство (скетч):

Пусть R -- прообраз такой что SHA-256(R) = H.

Случай 1: R раскрыт (Bob знает R)
  - Bob раскрывает R в канале Cn-Bob. HTLC Cn->Bob исполнен.
  - Cn теперь знает R. Cn раскрывает R в канале Cn-1-Cn. HTLC Cn-1->Cn исполнен.
  - ... (индукция по цепочке) ...
  - C1 раскрывает R в канале Alice-C1. HTLC Alice->C1 исполнен.
  - Все HTLC исполнены. (all)

Случай 2: R не раскрыт
  - Ни один промежуточный узел не знает R.
  - Для каждого HTLC: timeout истекает, средства возвращаются отправителю.
  - Ни один HTLC не исполнен. (nothing)

Случай 3 (невозможен): Частичное раскрытие
  - Допустим, Ci узнал R но НЕ передал Ci-1.
  - Тогда HTLC Ci-1->Ci истечёт по таймауту: Ci-1 вернёт средства.
  - Но Ci уже заплатил Ci+1 (раскрыл R дальше).
  - Ci потерял средства? НЕТ: таймлок Ci-1->Ci > таймлок Ci->Ci+1.
  - Ci успевает раскрыть R для Ci-1 ДО истечения таймлока.
  - Противоречие с допущением. Частичное раскрытие невыгодно. QED.

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

Дальнейшее чтение

  • Watchtowers — сторонние сервисы мониторинга. Если ваш узел офлайн и партнёр публикует старое состояние, watchtower применит наказание от вашего имени. Реализации: Eye of Satoshi (CLN), watchtower (LND).
  • AMP (Atomic Multi-Path Payments) — разделение платежа на части, идущие разными маршрутами. Позволяет отправить 1 BTC, даже если ни один канал не имеет такой ликвидности.
  • BOLT 12 (Offers) — замена BOLT 11 инвойсов. Статические платёжные реквизиты (не нужен новый инвойс для каждого платежа), встроенная поддержка подписок, улучшенная конфиденциальность.

Завершение модуля: Bitcoin

Вы прошли весь модуль 2 — от базовой архитектуры Bitcoin до Lightning Network:

УрокТемаКлючевая идея
BTC-01Архитектура BitcoinДецентрализованная P2P-сеть с консенсусом
BTC-02Модель UTXOТранзакции как графы: входы потребляют, выходы создают
BTC-03Структура блока80-байтный заголовок + Merkle root транзакций
BTC-04Bitcoin ScriptСтековый язык для условий траты
BTC-05Типы транзакцийP2PKH -> P2SH -> SegWit -> Taproot (эволюция)
BTC-06Майнинг и PoWSHA-256d, nonce, target, энергия как гарантия безопасности
BTC-07Корректировка сложности2016 блоков, 10-минутный таргет, cap 4x
BTC-08Сетевой протоколP2P, gossip, IBD, headers-first
BTC-09Lightning NetworkОфчейн-каналы, мультисиг, commitment TX
BTC-10Payment Channels и HTLCОтзыв, наказание, атомарные мультихоп-платежи

Что дальше: Модуль 3 — Ethereum. Принципиально другой подход: вместо UTXO — модель аккаунтов. Вместо Bitcoin Script — Turing-complete Solidity. Вместо Lightning Network — rollups и sharding. Но фундамент тот же: криптография, консенсус, экономические стимулы.

Итоги

КонцепцияФормула / МеханизмЗначение
Commitment TXto_local (таймлок) + to_remote (сразу)Асимметрия для защиты от мошенничества
Отзывrevocation_key раскрывает to_localПубликация старого состояния = потеря всего
HTLCHash Lock + Time LockУсловный платёж: знание R или таймаут
АтомарностьЕдиный прообраз R для всей цепочкиВсе HTLC исполнены или ни один
Убывающие таймлокиT(i) > T(i+1)Каждый узел успевает передать R дальше

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс