CS/BlockChain

[블록체인] Lightning Network(2) - Invocies

grammiboii 2025. 6. 6. 00:34

Alice가 Dina의 팬이어서 donation이 하고 싶다.

이건 계속해서 하는 거래가 아니라 일회성이다.

이럴때 Lightning Network을 사용할 수 있는 방법이 있다.

Announcing the Channel

image

Alice가 Dina에게 돈을 보내기 위해 최소한 Bob, Chan의 존재를 알고 있어야 하고

그러기 위해 Bob, Chan이 channel을 announce 하는 것이다.

즉 Dina에게 가는 경로를 제공하고 수수료를 받는다.

단, unAnnounced channel이 있을 수 있다.

이러면 존재를 알고 있는 node만 이용할 수 있을 것이다.

이때 announce 하는 방법으로 gossip protocol을 사용한다.

(모든 node가 서로의 정보를 공유하는 방법)

단, 경로는 Alice가 찾아야 한다 (source based path finding)

Fairness Protocol

  • Trustless operation

  • Atomicity

  • Multihop

Invoices

쉽게 말해 견적서다.

전달 될때는 atomic way로 전달된다. 즉 중간에 실패하는 일은 없고 보내지거나/안보내지거나 둘중 하나로 보장된다.

보장 되어야 중간에 있는 node가 참여 할것이다.

Bitcoin (on-chain) vs LN (off-chain)

Bitcoin LN
address invoice
sender(Alice)가 receiver(Bob)의 address를 찾는다 receiver(Bob)가 sender(Alice)에게 invoice를 보내준다
adddress로 sender가 돈을 보낸다 sender가 invoice에 payment에 하면 routing된다.
어떤 miner가 block에 포함 시키는지 관심 없음 (on-chain에 등록 되기만 하면 된다) 어떤 경로로 Bob에게 가야하는지 sender가 정해서 보내야 한다.

-> 마지막 문장이 가장 큰 차이점이다.

sender가 경로를 정해야 한다는 점에서 확장성 측면에서 한계가 존재한다.

어떤 알고리즘으로 경로를 정할 수 있는게 아니다.

Payment Hash

Dina는 random number(preimage / payment secret)를 고른다.

그리고 random number를 hash 한다.

그리고 hash(r) 값을 payment hash라고 한다.

의미

r 값을 Dina가 돈을 받았다는 proof로 사용한다.

Dina가 Invoice에 payment hash를 포함해서 보낸다.

Hash는 일방향성을 가지고 있으니, payment hash로부터 payment secret을 알 수 없다.

정확히는 Alice와 Bob이 약속을 하고 (약간의 수수료와 함께)

Bob과 Chan이 약속을 하고 (약간의 수수료와 함께)

Chan과 Dina가 약속을 한다.

돈을 전달 받았는지 proof로 제공하는 증거가 r 값이다.

그리고 실제로 동작하는 방식은 거꾸로이다.

Dina가 Chan의 local balance로 돈을 받고 r 값을 제시 한다.

Chan이 Bob의 local balance로 돈을 받고 r 값을 제시 한다.

Bob이 Alice에게 돈을 받고 r 값을 제시 한다.



전달 과정 구체적인 예시

image

Alice가 Dina에게 50,000 sat를 보내고 싶다.

R값을 알고 있는 사람은 Dina만 존재한다.

1, 2, 3 이후에

Alice는 H를 포함한 HTLC를 만들어서 Bob에게 보낸다.

이것부터 순서대로 살펴본다.

4. Alice -> Bob

image

HTLC는 이렇게 생겼다 (locking script)

OP_SHA256 0575...f6b3 OP_EQUAL <목적지 생략>

unlocking script는 이렇게 생겨야 한다.

<R>

execute 할 unloking + locking은 다음과 같다.

<R> OP_SHA256 <H> OP_EQUAL 



복습해보면 스택의 모습이

스택 스크립트
R R
h(R) SHA256
h(R) H H
TRUE EQUAL

-> 이 script를 쓰려면 올바른 R값을 알아야만 한다.

즉 Bob은 이 transaction을 사용할 수 없다.

Dina에게 보내고 싶은 금액은 50,000 sat.

수수료를 Bob과 Chan에게 100sat씩 주는 것으로 설정한 것이다.

Alice의 balance는 70,000 -> 19,800

Bob의 balance는 70,000 -> 120,200

여기서 Bob이 수수료 100sat을 챙기고 Chan에게 50,100 HTLC를 제시한다.

5. Bob -> Chan

Bob의 balance는 120,200 -> 70,100

Chan의 balance는 4,000.000 -> 4,050,100

이제 Chan이 100sat을 수수료로 챙기고 Dina에게 50,000 sat을 보낸다.

6. Chan -> Dina

Chan의 balance는 200,000 -> 150,000

Dina의 balance는 50,000 -> 100,000

7. Dina -> Chan -> Bob -> Alice

image

Dina에게 입금이 완료되고 r 값을 Chan에게 제시한다.

Chan이 Bob에게 r 값을 제시한다.

Bob이 Alice에게 r 값을 제시한다.

최종적으로 Alice가 받은 r 값은 영수증 역할을 한다.

  • 만약 누군가 r 값을 넘기지 않고 redeem해서 쓴다면?

    어차피 LN을 종료하고 redeem 한다는 것은 bitcoin network에 breoadcast 해야한다.

    그러면 나머지 참여자들도 r 값을 알게 된다.

image

최종 모습은 이렇게 된다.

Signature Bindng

위에서 살펴본 HTLC script는 미완성이었다. (unlocking + locking)

<R> OP_SHA256 <H> OP_EQUAL <목적지 생략>

이걸 안성시켜보자.

Alice -> Bob 상황이었으니까 Bob의 public key가 목적지일 것이다.

그럼 locking

OP_SHA256 <H> OP_EQUALVERIFY <Bob's Pub> OP_CHECKSIG

unlocking

<Bob Sig> <R>



unlocking + locking

<Bob Sig> <R> OP_SHA256 <H> OP_EQUALVERIFY <Bob's Pub> OP_CHECKSIG

stack을 살펴보면 (append right, pop right 했다고 가정)

스택 스크립트
BobSig BobSig
BobSig, R R
BobSig, h(R) SHA256
BobSig, h(R), H H
BobSig OP_EQUALVERIFY
BobSig, BobPub Bob's Pub
TRUE OP_CHECKSIG

HTLC timelock refund

r 값을 제시해서 transaction을 사용할 수 있도록 하는 방법과

time lock이 지나면 서명을 제시해서 transaction을 사용할 수 있도록 하는 방법을 추가한다.

-> 이건 누구의 서명일까? : Alice의 서명.

즉 Alice -> Bob 상황에서 Bob이 r 값을 제시하지 않으면(응답이 없거나 협조하지 않는다면) Alice가 refund 할 수 있다.

OP_DROP <cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP OP_CHECKSIG

OP_DROP은 이전에 stack에 있는 내용을 다 지우는 것이다.

cltv_expiry는 설정된 time out 값이다.

만약 cltv_expirty = 100 이면 100 block 이후에 사용할 수 있다.

그리고 Bob이 100 block 내에 r 값을 제시하지 않으면 Alice가 refund 할 수 있다.

lock time은 block height로 설정한다. (절대 시간, 예를 들어 3일 후의 block height로 지정)

OP_CHECKLOCKTIMEVERIFY는 현재 transaction에도 lock time이 걸려 있어야 한다는 말이다.

그리고 transaction의 lock time이 cltv_expiry보다 커야 한다. (더 나중이여야 한다.)

더 먼저 걸려있다면 invalid 하게 된다.

정리하면 현재 transaction의 time lock이 cltv_expiry보다 크거나 같게 설정 되어 있어야 한다.

  • Alice->Bob

    현재 + 500 block으로 설정했다.

    그럼 Bob은 현재 + 450 block.

    Chan은 현재 + 400 block.

  • cltv_expirty는 decrement해야 한다
    time lock은 Alice, Bob, Chan 순으로 decrement 해야 한다.

    제공을 Chan Bob Alice 순이기 때문에

    이렇게 하지 않으면 Bob은 pay 하고 Alice는 refund 할 수 있게 된다.

    그러므로 회수도 Chan Bob Alice 순으로 해야 한다.



r 값이 탈취된 경우

image

Alice -> Dina 10,000 sat

Chan이 Bob에게 돈을 요구해 (Dina에게 받은 처럼) 돈을 전달한 척 한다.

  • Chan -> Dina
    Dina의 실수로 Chan이 r 값을 알게 되었다.

    Chan이 실제로 Dina에게 돈을 전달하지 않는다.
  • Bob -> Chan
    Chan이 Bob에게 돈을 요구한다.

    Bob이 Chan에게 돈을 전달한다 (10,000 sat)

    Bob에게 r 값을 제시한다.
  • Alice -> Bob
    Bob이 Alice에게 돈을 요구한다.

    Alice가 Bob에게 돈을 전달한다 (10,000 sat)

    Alice에게 r 값을 제시한다.

-> 결과적으로 Chan은 r(payment secret) 값을 알아내서 10,000 sat 이득을 봤다.


Additional Metadata

3가지 추가 정보를 가질 수 있다.

  • additional metadata (text description)

    text로 된 짧은 설명

  • additional metadata (routing hints)

    경로상에 있는 node에 대한 정보.

    unannounced channel을 사용할 수 있다. (추천해주는 느낌)

  • exprity date

    invoice가 만료되는 날짜

    (invoice를 발행한)Dina 입장에서 각각의 비밀값 r을 가지고 있어야 한다.

    만약 만료된 invoice가 있다면 r 값을 지워도 된다.



경로 찾기 (Path Finding)

경로를 찾을때 송금 금액이 channel의 capacity를 넘으면 당연히 안된다.

하지만 capacity를 넘지 않더라도 channel의 balance를 넘어서는 경우도 있다.

-> 결론은 경로를 찾는 문제가 쉽지 않다.. 로 마무리 지으셨다.

현재 Optimal한 경로를 찾는 방법은 없다.

Optimal한 경로란 최소 node를 거치며 최소 수수료를 지불하는 경로를 말한다.

즉 시행착오를 거치며 찾은 경로를 우선으로 시도해 본다.

추가적으로 privacy를 위해서 Onion Routing을 사용한다.

P2P Gossip Protocol

경로 찾기를 위해 channel 정보를 알기 위해 필요한 protocol.

그리고 이 경로를 Alice (sender)가 찾아야 한다.

이를 source based path finding이라고 한다.

channel 검증

각 Peer가 announce 하기 전에 channel이 존재하는 지 검증한다.

즉 Funding transaction이 bitcoin block chain onchain에 존재하는 지 확인한다.

이때 과도한 전파를 막기 위해 이미 알고 있는 channel 정보는 전파하지 않는다.

channel 정보 update

channel끼리 balance는 얼마든지 redistribute 될 수 있다. 그러면 다른 node가 가지고 있는 channel balance는 정확하지 않다.

이를 해결하기 위해 하루에 4번 정도 channel 정보를 업데이트 한다 (광고한다)

-> 실제 channel local balance가 몇대 몇인지 실질적으로 알 수 있는 방법은 없다. 그러므로 시행착오를 거치며 경로를 탐색할 수 밖에 없다.


Onion Routing

privacy를 위해 사용한다.

자세한 내용은 생략.