[블록체인] Lightning Network(2) - Invocies
Alice가 Dina의 팬이어서 donation이 하고 싶다.
이건 계속해서 하는 거래가 아니라 일회성이다.
이럴때 Lightning Network을 사용할 수 있는 방법이 있다.
Announcing the Channel
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 값을 제시 한다.
전달 과정 구체적인 예시
Alice가 Dina에게 50,000 sat를 보내고 싶다.
R값을 알고 있는 사람은 Dina만 존재한다.
1, 2, 3 이후에
Alice는 H를 포함한 HTLC를 만들어서 Bob에게 보낸다.
이것부터 순서대로 살펴본다.
4. Alice -> Bob
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
Dina에게 입금이 완료되고 r 값을 Chan에게 제시한다.
Chan이 Bob에게 r 값을 제시한다.
Bob이 Alice에게 r 값을 제시한다.
최종적으로 Alice가 받은 r 값은 영수증 역할을 한다.
- 만약 누군가 r 값을 넘기지 않고 redeem해서 쓴다면?
어차피 LN을 종료하고 redeem 한다는 것은 bitcoin network에 breoadcast 해야한다.
그러면 나머지 참여자들도 r 값을 알게 된다.
최종 모습은 이렇게 된다.
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 값이 탈취된 경우
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를 위해 사용한다.
자세한 내용은 생략.