Основная концепция Lightning Network проста. Для дальнейшего понимания представьте потоки транзакций сети Lightning как код javascript, ссылаясь на белую книгу.
Если я объясню все потоки транзакций в одном сообщении в блоге, его будет трудно читать. Итак, я делю на несколько сообщений в блоге. Целью этого сообщения в блоге является использование отменяемой доставки выполнения HTLC, что соответствует рисунку 12 официального документа.
Код на Github: lightning-network-tx-flow
Pre Post: Упрощенный код Bitcoin Lightning Network, часть 2 - Средство защиты от утечек
Следующее сообщение: Упрощенный код сети Bitcoin Lightning, часть 4 - Устранение нарушения HTLC
14 шагов, чтобы провести отзывную доставку выполнения HTLC
Я пропускаю шаги до 4 из-за повторяющегося объяснения. Так что, пожалуйста, обратитесь к предыдущему сообщению в блоге, если хотите узнать.
- Финансирование с несколькими подписями
- Сборка C1a и C1b (без знака)
- Сборка RD1a и RD1b
- Обмен подписью C1a и C1b
- Сборка C2a и C2b (без признаков)
- Сборка RD2a и RD2b
- Сборка HTD1b
- Сборка HE1b
- Сборка HERD1b
- Обмен подписью C2a и C2b
- Сборка BR1a и BR1b
- Потратьте C2b
- Израсходовать HE1b
- Потратьте HERD1b
5. Постройте C2a и C2b (без признаков)
Сначала Алиса создает прообраз R, а также соответствующий хэш H. Алиса хочет заплатить 0,1 BTC Бобу только тогда, когда Боб знает прообраз R. Для Боба он должен ответить R, чтобы получить 0,1 BTC, когда Алиса предоставила H. В это время Алиса использует закрытый ключ как R и открытый ключ как H.
// Use private key as preimage R const preimageR = generatePrivateKey(); // Preimage H is public key const preimageH = getPubKey(preimageR); let C2a = new Transaction( [ new TxIn( // This is same as C1a fTxAH, 0, { type: 'MULTI', sig: [ redeemScript.pubKeyHashs[0], redeemScript.pubKeyHashs[1] ], redeemScript } ), new TxIn( // This is same as C1a fTxBH, 0, { type: 'MULTI', sig: [ redeemScript.pubKeyHashs[0], redeemScript.pubKeyHashs[1] ], redeemScript } ) ], [ new TxOut( 40000000, { type: 'RSMS', pubKeyHash: [ getPubKeyHash(AliceKeys[4]), getPubKeyHash(BobKeys[4]) ] } ), new TxOut( 50000000, { type: 'NORMAL', pubKeyHash: getPubKeyHash(BobKeys[4]) } ), new TxOut( 10000000, { type: 'HTLC', pubKeyHash: [ getPubKeyHash(AliceKeys[4]), getPubKeyHash(BobKeys[4]) ], preimageH // Alice provide H, Bob need to know R } ) ] )
Формат Json scriptPubKey выглядит следующим образом.
scriptPubKey = { type: 'HTLC', pubKeyHash: [ pubKeyHash1, pubKeyHash2 ], preimageH: preimageH }
Таким же образом Боб строит C2b.
6. Соберите RD2a и RD2b.
Пропустите повторяющееся объяснение. См. Предыдущий пост в разделе Сборка RD1a и RD1b.
7. Соберите HTD1b.
Только Алиса может транслировать эту транзакцию, чтобы вернуть 0,1 BTC после 3-х подтверждений временной блокировки, если Боб не может ответить R. Для Боба лучше ответить R до истечения этого времени блокировки.
let HTD1b = new Transaction( [ new TxIn( '', 2, { type: 'HTLCT', sig: [ getPubKeyHash(AliceKeys[4]), getPubKeyHash(BobKeys[4]) ], sequence: 3 } ) ], [ new TxOut( 10000000, { type: 'NORMAL', pubKeyHash: getPubKeyHash(AliceKeys[5]) } ) ] ) // Alice hand over HTD1b to Bob and let him sign HTD1b = signTx(HTD1b, BobKeys[4]);
Формат Json scriptSig выглядит следующим образом.
scriptSig = { type: 'HTLCT', sig: [ { signature: signature, pubKey: pubKey1 }, { signature: signature, pubKey: pubKey2 } ], sequence: 3 }
Обратите внимание, что HT1a немного отличается от HTD1b, поэтому обратитесь к Gitbub.
8. Соберите HE1b
Боб может транслировать эту транзакцию в любое время, если он знает R. К сожалению, он не получает 0,1 BTC от этой транзакции.
let HE1b = new Transaction( [ new TxIn( '', 2, { type: 'HTLCE', sig: [ getPubKeyHash(AliceKeys[4]), getPubKeyHash(BobKeys[4]) ], preimageR // Bob answer required R } ) ], [ new TxOut( 10000000, { type: 'RSMS', pubKeyHash: [ getPubKeyHash(AliceKeys[5]), getPubKeyHash(BobKeys[5]) ] } ) ] ) // Bob hand over HE1b to Alice and let her sign HE1b = signTx(HE1b, AliceKeys[4]);
Формат Json scriptSig выглядит следующим образом.
scriptSig = { type: 'HTLCE', sig: [ { signature: signature, pubKey: pubKey1 }, { signature: signature, pubKey: pubKey2 } ], preimageR: preimageR }
Обратите внимание, что HED1a немного отличается от HE1b, поэтому обратитесь к Gitbub.
9. Соберите HERD1b.
Боб может транслировать эту транзакцию только после 10 подтверждений блокировки по времени. Наконец, Боб получает от этой транзакции 0,1 BTC.
let HERD1b = new Transaction( [ new TxIn( '', 0, { type: 'RD', sig: [ getPubKeyHash(AliceKeys[5]), getPubKeyHash(BobKeys[5]) ], sequence: 10 // 10 block confirmation time lock } ) ], [ new TxOut( 10000000, { type: 'NORMAL', pubKeyHash: getPubKeyHash(BobKeys[6]) } ) ] ) // Bob hand over HERD1b to Alice and let her sign HERD1b = signTx(HERD1b, AliceKeys[5]);
Обратите внимание, что HTRD1a немного отличается от HERD1b, поэтому обратитесь к Gitbub.
10. Обмен подписью C2a и C2b
Алиса позволила Бобу подписать C2a. Теперь Алиса может транслировать эту транзакцию в любое время.
// Alice hand over C2a to Bob, and let him sign C2a = signTx(C2a, BobKeys[1]);
Таким же образом Боб позволил Алисе подписать C2b.
11. Соберите BR1a и BR1b.
Пропустите повторяющееся объяснение. См. Предыдущий пост в разделе Сборка BR1a и BR1b.
12. Потратьте C2b.
Боб проводит C2b. Даже если он знает R, он не может сразу получить 0,1 BTC Алисы из-за временной блокировки HERD1b.
Но, если Алиса потратит C2a, Боб может получить его немедленно, если он знает R.
// Sign by himself(Bob) C2b = signTx(C2b, BobKeys[1]); // Validate transaction validateTx(C2b, Blocks); // Mine block as adding transactions Blocks = mineBlock(Blocks, createNewBlock([C2b], Blocks));
13. Проведите HTD1b.
Боб потратит эту транзакцию, чтобы ответить R.
// Set C2b transaction hash HE1b.txIns[0].txPrev = calculateTxHash(C2b); HE1b = signTx(HE1b, BobKeys[4]); validateTx(HE1b, Blocks); Blocks.push( createNewBlock([HE1b], Blocks) );
14. Потратьте HERD1b
Боб потратит эту транзакцию, чтобы получить 0,1 BTC после 10 временной блокировки.
// Set HE1b transaction hash HERD1b.txIns[0].txPrev = calculateTxHash(HE1b); HERD1b = signTx(HERD1b, BobKeys[5]); // Wait 10 confirmations for time lock Blocks = mineBlock(Blocks, createNewBlock([], Blocks)); Blocks = mineBlock(Blocks, createNewBlock([], Blocks)); Blocks = mineBlock(Blocks, createNewBlock([], Blocks)); Blocks = mineBlock(Blocks, createNewBlock([], Blocks)); Blocks = mineBlock(Blocks, createNewBlock([], Blocks)); Blocks = mineBlock(Blocks, createNewBlock([], Blocks)); Blocks = mineBlock(Blocks, createNewBlock([], Blocks)); Blocks = mineBlock(Blocks, createNewBlock([], Blocks)); Blocks = mineBlock(Blocks, createNewBlock([], Blocks)); Blocks = mineBlock(Blocks, createNewBlock([], Blocks)); validateTx(HERD1b, Blocks); Blocks.push( createNewBlock([HERD1b], Blocks) );