본문 바로가기
학교공부/[블록체인]

[블록체인] - Lightning Network_HTLC(Hash_Time_Locked_Control)

by 윈디개 2025. 12. 12.

지난 글에서는 Lightning Network가 등장하게 된 배경, 과정, 동작 원리 등에 대해서 정리해 보았다. 이번 글에서는 Lightning Network에서 특별한 경우를 정리해 보려고 한다.


1. Lightning Network_Invoice

 만약 다음과 같은 상황을 가정해보자.

그림에 대해서 설명하면, 다음과 같다.

  • Alice가 Dina에게 10,000 satoshi만 지불하려고 한다.
  • Alice와 Dina 사이에는 직접적인 payment channel이 존재하지 않는다.
  • Alice는 Bob과, Bob은 Chan과 Chan은 Dina와 각각 payment channel이 존재하는 상황이다.
  • 각 channel의 capacity는 100,000 satoshi, 5,000,000 satoshi, 250,000 satoshi이다.

 위 상황에서, Alice가 Dina에게 오직 10,000 satoshi를 주기 위해서 채널을 새로 파는 비효율적인 일을 할 필요가 없다. 이미 만들어 둔 channel 경로를 따라 지불을 라우팅하면 된다. 

 

 이런 방법을 실행하기 위해서 몇 가지 조건이 존재한다. 그중 하나는 Channel을 Lightning Network에 announcing하는 것이다. 즉, Lightning Network 전체에 channel을 broadcast해야 한다. 이는 곧, 이 채널은 다른 노드가 라우팅 경로로 사용할 수 있는 public channel로 취급된다. 이때 네트워크에 알려야 하는 정보는 다음과 같다.

  1. 채널 존재 여부
  2. 채널 capacity
  3. 채널의 fee 정책
  4. timelock 파라미터 등 라우팅에 필요한 정보

이러한 broadcast는 gossip protocol을 통해 이루어지며, LN 노드들은 이를 기반으로 전체 네트워크의 라우팅 path를 유지하게 된다.

 

그런데 만약, 채널에 참여하는 두 노드의 동의가 없다면, 이 채널은 unannounced channel(=private channel)로 남게 되며, 다른 Lightning network 참여자들은 channel의 존재 여부를 알 수 없게 되며, 이 채널은 라우팅 경로로 사용될 수 없다.

 

 즉, 새로운 노드가 Lightning Network에 참여하게 된다면, 새로운 노드는 그들의 peer로부터 gossip protocol을 통해 전파된 channel announcement를 수집할 수 있으며, 이를 통해 internal map이라는 것을 생성할 수 있다. 이 internal map에는 Lightning Netowork의 통로들이 나타나 있다.

 

- Invoice

 이제, 지불하는 통로는 파악할 수 있게 되었으니, 실제 payment 과정을 살펴볼 차례이다. Lightning Network에서 결제를 시작하기 위해서는 결제받는 쪽, 즉 위 그림의 Dina가 먼저 Invoice(청구서 또는 견적)를 발행해야 한다.

 

  Invoice는 다음과 같은 정보들을 포함하는 payment instruction이다.

  • payment_hash(지불 식별자)
  • 결제 금액
  • 설명(description)
  • 만료 시간(expiry)
  • routing hints(필요한 경우)

 여기서 주의해야 할 점은, invoice 자체가 hash한 값으로 이루어진 것이 아니라 invoice 안에 payment_hash가 포함되어 있는 구조이다.

 

그럼, Invoice는 어떻게 생성할까? Invoice를 만들기 위해 Recipient는 무작위 숫자 r을 선택하고 이를 SHA-256으로 해시하여 H(r)을 만든다. 이때, Invoice에는 H(r)만 sender에게 전달하며, 실제 r값은 payment가 완료된 후에만 Dina가 공개한다. 여기에 Hash값을 사용하는 이유는 다음과 같다.

  • Sender는 H(r)에 지불을 시도한다.
  • 중간 노드가 r을 유추 가능해 H(r)을 풀게된다면 payment를 가로챌 수 있다.
  • 그렇지만, SHA-256 해시함수의 preimage resistance 때문에 중간 노드가 결제를 탈취하는 것이 불가능하다.

 

 방금, H(r)에 대한 payment를 한다고 했는데, 기존의 address에 지불하는 Bitcoin과는 조금 다르다. 그럼 비트코인과 Lgihtning network의 지불 방식에는 어떤 차이점이 있을지 정리해 보려고 한다. 

  • Bitcoin
    • Recipient는 Sender에게 address(주소)를 전달한다.
    • sender는 address로 돈을 보내는 트랜잭션을 생성한다.
    • 즉, address 기반으로 이루어진다.
  • Lightning Network
    • recipient는 Sender에게 invoice를 전달한다.
    • sender는 invoice를 읽고 LN 라우팅 기반으로 payment가 이루어진다.
    • invoice라는 개념을 기반으로 이루어진다.
    • 위의 행동으로 payment가 진행된다.

만약, 위 그림에 대해서 Invoice개념을 적용하면, 다음과 같이 진행된다.

  1. Dina가 Invoice를 QR코드나 URL 형태로 미리 생성한다.
  2. Alice는 지불 의사가 있을 시, 해당 Invoice를 스캔하여 Invoice 내용을 받는다.
  3. Alice는 invoice 안의 payment_hash를 기반으로 route를 탐색하고,
  4. Alice > Bob > Chan > Dina 순으로 HTLC가 생성되며 전달된다.
  5. 마지막으로 Dina가 preimage r을 다시 전달하면, 모든 경로는 같은 r로 정산되어 결제가 원자적으로 완료된다.

+) Invoice에 추가로 포함된 정보를 한 번 살펴보자.

  • 또 다른 유용한 metadat를 포함시킬 수 있다.
    • short text description: 간단한 상품 설명
  •  routing hints: unannounced channel. 
    • 위의 예시에서 만약, Bob과 Chan의 channel이 unanncounced인데, Dina가 이를 알고 있다면 routing hints를 invoice 안에 담아 Alice에게 전달해준다.
  • expiry date: invoice는 유통기한이 있으면, 만료기한이 지나면 더 이상 결제를 할 수 없다. 또한 한 번 결제가 성공하면 해당 invoice의 r값은 다시 사용할 수 없다.

expiray date는 바로 Bitcoin과의 큰 차별점인데, 간단히 말해서, 비트코인은 같은 address로 여러 번 지불할 수 있지만, Lgihtning Network에서는 유통기한이 지나거나 한 번 payment가 성공한다면 재사용이 불가능하다.

 

++) Gossip Protocol이라고 불리는 이유

앞서 channel의 announcement가 gossip protcol로 인해 이루어진다고 정리했다. 'gossip'이라는 것은 보통 뒷이야기, 소문을 의미하는 것으로, 좋은 의미로 쓰이지는 않는다. 그런데, Lightning Network에서 gossip은 peer-to-peer 네트워크의 특성과 결합해 특정 그룹만 아는 소문이 아니라 네트워크 전체로 퍼지는 정보라는 의미로 사용된다.

 

즉, Lightning Network에 참여한 노드들은 gossip protocol의 특징으로 인해 announced된 payment channel 정보룰 공유받을 수 있다. 이 정보를 통해 각 노드는 자신의 라우팅 그래프(internal map)를 구성하게 된다.

>> 모든 참여자들은 announced된 payment channel들을 실제 존재하는지 funding transaction이 블록체인에 포함되었는지를 확인하여 유효성을 검증할 수 있다.

>> channel 정보를 broadcast할 때는 채널 참여자의 balance를 알리진 않는다.

 

+++) 용어 정리

Pathfinding: 목적지까지 갈 수 있는 라우팅 경로를 찾는 과정

Routing: 찾은 경로를 이용해 실제 payment를 전송하는 행위

Source-based: payment의 sender가 목적지까지 갈 수 있는 경로를 찾는다는 의미이다.

Onion-routed: 경로의 각 홉 정보는 양파처럼 층층이 암호화되어 있다. 즉, 각 노드는 그 중 자신에게 해당하는 layer만 복호화할 수 있으며, 그 이후 다음 노드에게 전달할 정보만 알 수 있다.

>> Lightning Network는 현재 pathfinding은 source-based 프로토콜을 사용하고 routing은 onion-routed 프로토콜을 사용한다.


2. Lightning Network_HTLC

이제 payment 과정에 대해서 더 자세히 정리해 보려고 한다. 다음 그림을 예시로 사용할 예정이다.

위 그림에서 Alice가 Dina에게 지불할 수 있는 방법은 다음과 같이 2가지가 존재한다.

  1. Alice와 Dina가 channel partner라면 바로 payment를 진행할 수 있다.
  2. Alice가 Bob-Chan의 Channel을 경유하여 Dina에게 payment를 진행할 수 있다.

지불의 전체적인 과정을 정리하기 전에 Ligthtning Network의 특성 중 하나인 Fairness Protocol을 알아야 한다. Fairness Protocol은 다음과 같은 특징을 지닌다.

  • Trustless operation
    • routed payment 과정에 참여하는 노드들은 서로를 믿을 필요가 없다. 누구도 상대방이 중간에서 돈을 가로채지 않을 것이라고 믿을 필요가 없다. 오직 프로토콜만을 신뢰하면 된다.
  • Atomicity
    • payment는 전체 홉에서 모두 성공하거나, 모두 실패한다. 중간 노드가 payment를 받고 다음 홉으로 넘겨주지 않는 상황은 발생하지 않는다. 따라서 cheat나 steal이 일어날 수 없다.
  • Multihop
    • payment가 여러 홉을 지나더라도 sender와 receiver 사이의 보안과 atomicity는 그대로 유지된다.

 

 만약, 위 그림에서, Alice가 Dina에게 payment를 진행한다고 했을 때, Bob과 Chan은 무료로 자신의 payment channel을 쓰게 해줄까? 그렇지 않을 것이다. 따라서 중간 노드도 routing fee를 얻어야 하고, 동시에 Alice 입장에서도 trustless하게 안전한 장치가 필요하다

 

 이 모든 요구를 만족시키기 위해 등장한 것이 바로 HTLC이다. 그럼 이 HTLC는 무엇이고 어떻게 적용되는지 한 번 알아보자.

 

 HTLC는 Hast Time-locked Contract의 약자로, Lightning Network의 핵심 Smart contract 구조이다. 이름에서 알 수 있듯이, Hash함수를 적용하며, time-lock도 존재한다. HTLC 기능에 대해서 위 그림을 통해 정리하면 다음과 같다.

  • Cryptographci Hash 적용
    • Dina는 랜덤한 숫자 R(=preimage)를 만들고, 그 해시값 H = hash(R)을 생서성한다.
    • Alice는 H, 즉, 해시값만 알고, R은 오직 Dina만이 안 채로 보존된다.
    • 해시 함수는 R을 모르면 해시값만으로 R을 추측 못하는 Preimage Resistance 특징이 있다.
  • Hash Preimage = Payment의 증명(like 영수증) 
    • Alice는 Dina에게 Invoice를 받는다. 이 Invoice 안에는 payment hash(R)가 들어있다. 
    • Payment에 성공하면 Dina는 R(=preimage)을 공개하고, R이 payment가 완료되었다는 영수증이 된다.

위 그림으로 예시를 들면, 다음과 같다.

  • Dina는 random number R을 선택하여 h(R)을 생성한다.
  • Alice는 h(R)을 이용해 50,000 satoshi 만큼의 payment를 진행하려고 한다.
  • Alice는 Bob에게 payment script를 제시할 때, 50,200satoshi을 포함시켜 진행한다.
  • Bob은 Chan에게 50,100 satoshi를 전달한다.
  • Chan은 Dina에게 50,000 satoshi를 전달한다.
  • Dina가 받은 HTLC는 R로 redeem(해금)할 수 있다.
  • Payment가 잘 도착한 것을 확인한 Dina는 R을 공개하고, Chan > Bob > Alice 순서로 모두 자신의 HTLC를 안전하게 reedem할 수 있다.

 그럼 이때, 생기는 궁금증은 이것이다. Bob이 만약 200 satoshi를 자신의 routing fee로 받고 Chan에게는 50,000satohi를 건네며 나는 100만 챙긴거야라고 거짓말을 친다면?

 

 위 같은 경우는, Chan이 검증을 진행한다. 즉, 자신이 챙길 routing fee가 없으면 Bob이 전달한 HTLC를 거부할 수 있으며, 결국 Alice가 발생시킨 HTLC는 모든 네트워크에서 무효화가 되어 Bob도 routing fee를 챙길 수 없다. 따라서 모든 노드는 정직하게 행동해야 된다.

 

 이제 실제 HTLC을 포함한 payment 모습을 한 번 살펴보자. 전체 과정을 그림으로 담아내면 다음과 같다.

그림에 대해서 설명하면 다음과 같다.

  • Alice는 Bob과의 payment channel을 통해 본인의 balance 70,000 sat에서 50,200 sat의 HTLC를 생성한 뒤 Bob에게 전달한다.
  • Bob은 100 sat만큼의 routing fee를 챙기고 Chan과의 payment channel을 통해 본인의 balance 1,000,000 sat에서 50,100 sat를 HTLC를 생성하여 Chan에게 전달한다.
  • Chan은 100 sat만큼의 routing fee를 챙기고 Dina와의 payment channel을 통해 본인의 balance 200,000 sat에서 50,000 sat를 HTLC를 생성하여 Dina에게 최종 전달한다.

이때, Alice가 제공한 50,200 satoshi HTLC의 output script를 살펴보자. 스크립트는 다음과 같다.

  • OP_SHA256 0575.....f6b3 OP_EQUAL

 Bob은 위 스크립트를 전달받은 즉시 사용하지 못한다. 그 이유는 위 스크립트를 unlock할 수 있는 값은 바로 Dina가 random으로 설정한 R이기 때문이다. 따라서, Dina가 R을 공개하지 않는다면 Bob은 100 sat 만큼의 routing fee를 사용할 수 없다. Chan도 마찬가지로 Dina가 R을 제시하기 전까지는 100 sat를 사용할 수 없다.

 

 그럼, 위 과정이 완벽하게 이루어졌고, Dina가 50,000 sat를 받았으면, Dina는 payment 성공을 증명하기 위해 R값 공개해야 한다. Dina는 R값을 Chan과의 payment channel을 통해 Chan에게 전달하고, Chan은 다시 Bob에게, Bob은 다시 Alice에게 전달한다.

 

 이 과정을 그림으로 표현하면 다음과 같다.

이렇게 되면,

  • Alice는 R값을 확인한 뒤, Dina에게 payment가 성공적으로 이루어졌다는 것을 확신할 수 있다.
  • Bob과 Chan은 각각 100 sat를 R을 통해 unlock해서 사용할 수 있다.

- HTLC with Signature

 위의 상황에서는 문제점이 존재한다. 위 구조만 보면 HTLC가 모두 똑같은 script 형태로 만들어져 있다. 이렇게 payment가 진행되면 다음과 같은 문제가 발생할 수 있다.

  • Chan이 Alice의 HTLC, Bob의 HTLC를 모두 알고 있는 상황에서,
  • Chan은 R을 전달받자마자 Alice의 HTLC, Bob의 HTLC를 unlock하여 사용할 수 있다.

 즉, 정리하면, 위에서 총 3개의 HTLC 스크립트가 존재하는데, 이 스크립트들이 모두 동일한 OP_SHA256 <h(R)> OP EQUAL 구조만으로 되어 있다면 Chan은 R을 통해 모든 HTLC를 redeem할 수 있으므로 문제가 생긴다.

 

 이러한 문제를 해결하기 위해 Lightning Network에서는 HTLC 스크립트에 서명 조건을 추가한다. 따라서 수정된 script를 확인하면 다음과 같다.

  • OP_SHA256 <h(R)> OP_EQUALVERIFY <PubKey> OP_CHECKSIG

 이를 unlock하기 위해서는 R(해시의 preimage)뿐 아니라 스크립트에 포함된 PubKey에 대응되는 유효한 서명도 제시해야 한다.

 

 예를 들어, Alice가 Bob에게 보낸 HTLC 스크립트는 OP_SHA256 <h(R)> OP_EQUALVERIFY <Bob's PubKey> OP_CHECKSIG일 것이고, Bob은 R값을 전달받으면 <Bob의 서명> <R>을 제시해 해당 HTLC 주인임을 증명할 수 있고, 100 sat를 사용할 수 있게 된다.

 

이렇게 서명을 포함시키면, Chan이 아무리 HTLC를 수집한다고 해도, 해당 HTLC 주인이 아니면 절대 unlock할 수 없게 된다.

 

- HTLC with Timeout

 위와 같이 서명을 추가한다 해도 문제 상황이 아직 남아있다. 만약, 누군가가 offline이거나, payment과정에서 협력하기를 거부한다면 어떻게 될까?

 

 다음 두 상황을 가정해보자.

  • Chan이 Bob으로부터 HTLC를 전달받았는데, Chan이 하루 이상 offline인 상황
  • Dina가 Payment를 받았는데 R 값을 공개하지 않는 상황

 위 두 상황 모두, Sender 측(Alice나 Bob 입장)에서는 정상적으로 HTLC를 전달했지만, 상대가 협력하지 않기 때문에 R을 받기 전까지 무한정 기다려야 하는 문제가 발생한다.

 

 이러한 상황을 해결하기 위해서, HTLC에는 Timelock 조건(CLTV)을 추가한다. 업데이트 된 script를 확인하면 다음과 같다.

  • OP_DROP <cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP ...(뒤는 위와 동일하므로 생략)

여기서 처음에 들어가 있는 OP_DROP은 기술적인 이유로 존재하지만, 수업시간에 다루지는 않았으므로 생략한다. 

  • <cltv_expiry>: output이 유효하게 spend될 수 있는 최소 블록 높이(또는 시간)
  • OP_CHECKLOCKTIMEVERIFY: 트랜잭션의 locktime field와 cltv_expiry를 비교하는 연산

만약, spend 하려는 트랜잭션의 locktime이 <cltv_expiry>보다 작으면 스크립트는 실패하고, 크거나 같을 때 스크립트가 통과되며, refund transaction을 진행할 수 있다.

 

 따라서, 위의 문제 상황에 대해서 적용하면, Chan이 offline이 되더라도, Dina가 R을 공개하지 않더라도 <cltv_exipry>로 설정된 시간이 지나면 sender(Alice 또는 Bob)가 HTLC를 온체인으로 전파해 refund transaction을 발생시킬 수 있게 된다. 그로 인해 Alice가 Dina에게 50,000 sat를 지불하려 했던 시도는 완전히 무효 처리된다.

 

 이를 통해 payment는 모두 성공하거나 모두 실패하는 Lightning Network의 Atomicity도 유지시킬 수 있다.

 

+) Timelock을 설정할 때는, 목적지에서 가까울수록 더 작게, 출발지에서 가까울수록 더 크게 설정해야 한다. 즉, HTLC는 경로를 따라가면서 점점 더 짧은 timelock이 적용되어야 한다.

 

 위의 상황에서

  • Alice가 Bob에게 HTLC를 보낼 때, current + 500으로 설정했다면,
  • Bob은 Chan에게 보낼 때 current + 450으로,
  • Chan은 Dina에게 보낼 때 current + 400으로

설정해야 한다.

 

 그 이유는 Chan보다 Bob의 <cltv_expriy>가 짧아 Bob이 먼저 refund transaction을 발동시키는 상황이 발생하기 때문이다. 이 경우 다음과 같은 문제가 생긴다.

  • Chan은 아직 자신의 refund 시간이 도래하지 않았기 때문에 refund를 시도할 수 없다.
  • Bob이 refund transaction을 발동시킨 뒤 나중에 R값을 받더라도, 이미 payment가 무효한 상태이기 때문에 해금할 HTLC 대상이 존재하지 않는다.
  • Chan이 시간이 지나 refund를 시도하려고 해도, Bob의 refund가 이미 진행되었기 때문에 refund할 대상 자체가 사라진다.

 즉, 중간 노드가 피해자가 되는 상황이 발생할 수 있다. 따라서 이러한 문제를 방지하기 위해 목적지에 가까울수록 timelock을 짧게 설정해야 한다.