Основная концепция Lightning Network проста. Для дальнейшего понимания представьте потоки транзакций сети Lightning как код javascript, ссылаясь на белую книгу.

Если я объясню все потоки транзакций в одном сообщении в блоге, его будет трудно читать. Итак, я делю на несколько сообщений в блоге. И это последний пост.

Цель этого сообщения в блоге - потратить средства на устранение нарушений HTLC, что соответствует рисункам 13 + 14 официального документа.

Код на Github: lightning-network-tx-flow

Pre Post: Упрощенный код Bitcoin Lightning Network, часть 3 - Проведите отзывную доставку выполнения HTLC

19 шагов, чтобы потратить HTLC Breach Remedy

Я пропускаю шаги до 11 из-за повторяющихся объяснений. Так что, пожалуйста, обратитесь к предыдущему сообщению в блоге, если хотите узнать.

  1. Финансирование с несколькими подписями
  2. Сборка C1a и C1b (без знака)
  3. Сборка RD1a и RD1b
  4. Обмен подписью C1a и C1b
  5. Сборка C2a и C2b (без признаков)
  6. Сборка RD2a и RD2b
  7. Сборка HTD1b
  8. Сборка HE1b
  9. Сборка HERD1b
  10. Обмен подписью C2a и C2b
  11. Сборка BR1a и BR1b
  12. Сборка C3a и C3b (без признаков)
  13. Сборка RD3a и RD3b
  14. Обмен подписью C3a и C3b
  15. Раскрыть закрытые ключи
  16. Потратьте C2b
  17. Создавайте и расходуйте D2b
  18. Создайте и потратите BR2b
  19. Создание и расходование HBR1b

12. Сборка C3a и C3b (без признаков)

Теперь Алиса и Боб хотят закрыть HTLC, чтобы они построили C3a и C3b для обновления состояния сети Lightning. Обратите внимание на остатки на выходе. Боб получает на 0,1 BTC больше, чем Алиса. На этот раз Алиса не требует, чтобы Боб отвечал на прообраз R.

let C3a = new Transaction(
  [
    new TxIn(
      fTxAH, 
      0, 
      { 
        type: 'MULTI',
        sig: [ 
          redeemScript.pubKeyHashs[0], 
          redeemScript.pubKeyHashs[1] 
        ],
        redeemScript
      }
    ),
    new TxIn(
      fTxBH,
      0, 
      { 
        type: 'MULTI',
        sig: [ 
          redeemScript.pubKeyHashs[0], 
          redeemScript.pubKeyHashs[1] 
        ],
        redeemScript
      }
    )
  ],
  [
    new TxOut(
      40000000, 
      { 
        type: 'RSMS',
        pubKeyHash: [ 
          getPubKeyHash(AliceKeys[7]), 
          getPubKeyHash(BobKeys[7]) 
        ]
      }
    ),
    new TxOut(
      60000000, // Bob receive 0.1 BTC more than Alice
      { 
        type: 'NORMAL',
        pubKeyHash: getPubKeyHash(BobKeys[7])
      }
    )
  ]
)

13. Сборка RD3a и RD3b

Пропустите повторяющееся объяснение. См. Предыдущий пост в разделе Сборка RD1a и RD1b.

14. Обмен подписью C3a и C3b

Алиса позволила Бобу подписать C3a. Теперь Алиса может транслировать эту транзакцию в любое время.

// Alice hand over C3a to Bob, and let him sign
C3a = signTx(C2a, BobKeys[1]);

Таким же образом Боб позволил Алисе подписать C3b.

15. Раскрыть закрытые ключи

Алиса и Боб раскрывают там закрытые ключи, соответственно, для отмены выходных данных C2a и C2b. Если Алиса неожиданно транслирует C2a, она теряет все BTC, так что Алиса может безопасно отозвать C2a.

Сначала Алиса раскрывает AliceKeys[4]. Используя этот ключ, Боб может самостоятельно построить и потратить BR2a и HBR1a, чтобы получить BTC Алисы.

Во-вторых, Алиса раскрывает AliceKey[5]. Используя этот ключ, Боб может самостоятельно построить HEBR1a.

Таким же образом Боб раскрывает BobKey[4] и BobKey[5] Алисе.

16. Потратьте C2b.

Боб неожиданно передал C2b. К сожалению, из-за нарушения он потерял все BTC.

// Sign by himself(Bob)
C2b = signTx(C2b, BobKeys[1]);
validateTx(C2b, Blocks);
// Mine block as adding transactions
Blocks = mineBlock(Blocks, createNewBlock([C2b], Blocks));

17. Стройте и тратьте D2b

Алиса тратит D2b, вывод которой изначально принадлежит Алисе.

const hashC2b = calculateTxHash(C2b);
let D2b = new Transaction(
  [
    new TxIn(
      hashC2b, 
      0, 
      { 
        type: 'SINGLE',
        sig: [ 
          getPubKeyHash(AliceKeys[4]) 
        ],
      }
    )
  ],
  [
    new TxOut(
      40000000, 
      { 
        type: 'NORMAL',
        pubKeyHash: getPubKeyHash(AliceKeys[8])
      }
    )
  ]
)
D2b = signTx(D2b, AliceKeys[4]);
validateTx(D2b, Blocks);
Blocks = mineBlock(Blocks, createNewBlock([D2b], Blocks));

18. Создайте и потратьте BR2b

Алиса может подписать BR2b, используя раскрытый закрытый ключ Боба. И она сразу же получает BTC Боба.

const c2bHash = calculateTxHash(C2b);
let BR2b = new Transaction(
  [
    new TxIn(
      c2bHash,
      1, 
      { 
        type: 'BR',
        sig: [ 
          getPubKeyHash(AliceKeys[4]), 
          getPubKeyHash(BobKeys[4]) 
        ],
      }
    )
  ],
  [
    new TxOut(
      40000000, 
      { 
        type: 'NORMAL',
        pubKeyHash: getPubKeyHash(AliceKeys[8]) // For Alice
      }
    )
  ]
)
// Alice can sign, because she know Bob's private key.
BR2b = signTx(BR2b, BobKeys[4]);
// Inherently, this BTC is for Bob, but now belong to Alice.
// Bob lose for his breach.
BR2b = signTx(BR2b, AliceKeys[4]);
validateTx(BR2b, Blocks);
Blocks.push( createNewBlock([BR2b], Blocks) );

19. Постройте и расходуйте HBR1b.

Таким же образом Алиса может подписать HBR1b, используя раскрытый закрытый ключ Боба. И она сразу же получает BTC Боба.

let HBR1b = new Transaction(
  [
    new TxIn(
      c2bHash,
      2, 
      { 
        type: 'BR',
        sig: [ 
          getPubKeyHash(AliceKeys[4]), 
          getPubKeyHash(BobKeys[4]) 
        ],
      }
    )
  ],
  [
    new TxOut(
      10000000, 
      { 
        type: 'NORMAL',
        pubKeyHash: getPubKeyHash(AliceKeys[8]) // For Alice
      }
    )
  ]
)
// Alice can sign, because she know Bob's private key.
HBR1b = signTx(HBR1b, BobKeys[4]);
// Inherently, this BTC is for Bob, but now belong to Alice.
// Bob lose for his breach.
HBR1b = signTx(HBR1b, AliceKeys[4]);
validateTx(HBR1b, Blocks);
Blocks.push( createNewBlock([HBR1b], Blocks) );