闪电网络设计说明书

1. 引言

比特币闪电网络论文笔记参见:

闪电网络实际实现参见设计文档 Basis of Lightning Technology (BOLT) :

BOLT设计文档分为10个子部分:

  • BOLT #1:Base Protocol
  • BOLT #2:Peer Protocol for Channel Management
  • BOLT #3:Bitcoin Transaction and Script Formats
  • BOLT #4:Onion Routing Protocol
  • BOLT #5:Recommendations for On-chain Transaction Handling
  • BOLT #7:P2P Node and Channel Discovery
  • BOLT #8:Encrypted and Authenticated Transport
  • BOLT #9:Assigned Feature Flags
  • BOLT #10:DNS Bootstrap and Assisted Node Location
  • BOLT #11:Invoice Protocol for Lightning Payments

在这里插入图片描述

1.1 闪电网络关键技术简介

闪电网络为使用通道网络实现比特币快速支付的协议。
闪电网络中使用的核心技术有:

  • 1)Channels通道
    两个参与者创建闪电支付通道,往通道内存入一定数额的比特币(如0.1BTC),通道内的比特币金额会锁定在Bitcoin主网上,仅有双方签名才可消费。
    最初,他们各自持有一个比特币交易,可将所有金额(如0.1BTC)全部发送回一方。
    稍后,他们可签名新的比特币交易,将资金拆分,如0.09BTC给一方,0.01BTC给另一方,然后设置之前的比特币交易为无效的——即之前的比特币交易不可再消费。
    – 通道创建的信息,可参看 BOLT #2:Channel Establishment。
    – 创建通道时的比特币交易格式,可参看 BOLT #3:Funding Transaction Output。
    – 当参与方不同意或失败时,必须消费cross-signed bitcoin transaction,详细的处理流程可参看 BOLT #5:Recommendations for On-chain Transaction Handling。

  • 2)Conditional Payments 有条件支付
    一个闪电通道仅支持两个参与者之间支付,但是很多通道连接成网络,将支持网络内的所有用户之间进行支付。这其中用到的技术为:有条件支付——可附加在通道上,如,“若你能在6小时内公开某个秘密,你将获得0.01BTC”。一旦接收方公开了秘密,则该笔比特币交易将被一个缺少有条件支付的交易所替代,并将相应的资金添加到接收方的output中。
    – 某一方添加有条件支付交易的命令格式,详细参见 BOLT #2:Adding an HTLC,完整的比特币交易格式可参见 BOLT #3:Commitment Transaction。

  • 3)Forwarding 转发
    有条件支付可 以lower time limit的方式安全地转发给另一参与者,如“若你能在5小时内公开某个秘密,你将获得0.01BTC”【”5小时“ < 之前的”6小时“】。一旦接收方公开了秘密,则该笔比特币交易将被一个缺少有条件支付的交易所替代,并将相应的资金添加到接收方的output中。
    – 转发支付的详情参见 BOLT #2:Forwarding HTLCs
    – 如何传送支付指令参见 BOLT #4:Packet Structure

  • 4)Network Topology 网络拓扑
    要进行支付,参与者需要知道可通过哪些通道进行发送。参与者相互告知通道和节点的创建及更新信息。
    – 详细的通讯协议参见 BOLT #7:P2P Node and Channel Discovery
    – 初始的网络bootstrap参见 BOLT #10:DNS Bootstrap and Assisted Node Location

  • 5)Payment Invoicing 支付费用清单
    参与者会收到支付清单,以告知他该支付什么。
    – 描述收款对象及支付目的的协议,以便付款人以后能证明支付成功,协议详情见 BOLT #11:Invoice Protocol for Lightning Payments

1.2 词汇及术语指南

  • Announcement:peers之间发送的gossip message,用于发现通道或节点。
  • chain_hash:目标区块链的唯一标识hash值(通常为genesis hash值)。chain_hash允许节点在多个区块链上创建和引用通道。节点将忽略来源于其未引用的chain_hash 消息。与bitcoin-cli不同,该hash值不是反向的,而是可直接使用的。
    比特币主网的chain_hash值为:6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000
  • Channel:在2个peers之间实现快速链下交互。为了进行资金交互,peers交换签名来创建updated commitment transaction。
    channel通道支持mutual close,revoked transaction close以及unilateral close (单方关闭)。
  • Closing transaction:为mutual close时生成的交易之一。Closing transaction与commitment transaction类似,但是没有pending payments。
  • Commitment number:用于每个commitment transaction中,为48位递增计数器。通道内每个peer的计数器是独立的,都从0开始。
  • Commitment revocation(废除) private key:每一个commitment transaction都有一个唯一的commitment revocation private-key value,另一方若拥有该key value值,则可立马花费所有outputs中的金额:通过reveal该key value值,即可废除 old commitment transaction。为了支持废除,每个commitment transaction都引用了废除该commitment对应的public key。
  • Commitment transaction:为花费funding transaction的transaction。每个peer都拥有对方对该笔交易的签名,因此,各自都有一个可花费的commitment transaction。当有新的commitment transaction时,老的将被废除。
  • Final node:一笔支付由初始节点发起,经由多个中间节点(hops),到达的最终接收方。同时为链路中的最终接收节点。
  • Funding transaction:为不可逆的链上交易,在一个通道内向2个peers付费。只有在双方同意的情况下才能使用。
  • Hop:一种节点。通常为起始节点和最终节点之间的中间节点。
  • HTLC:Hashed Time Locked Contract。
    为2个peers之间的有条件支付:接收方通过展示其签名和支付preimage来获得相应金额,否则付款人可在指定时间后取消该付款合约。这些以commtiment transaction outputs的方式实现。
  • Invoice:A request for funds on the Lightning Network, possibly。费用清单中包含:支付类型、支付金额、过期时间以及其他信息。这是闪电网络内的支付形式,而不是使用比特币式地址。
  • It’s ok to be odd:为某些数域内的规则,表示对某种feature的可选或强制支持。偶数表示2个endpoints都必须支持所讨论的feature,而奇数表示endpoint可忽略该feature。
  • MSAT:为一个millisatoshi,常用作field name。
  • Mutual close:对通道的合作式关闭,通过广播一个unconditional spend of the funding transaction with an ouput to each peer(除非某个output太小才可不包含在内)。
  • Node:作为闪电网络一部分的计算机或其他设备。
  • Origin node:为一笔支付的初始节点,经由数个hops,到达最终节点。Origin node为链路上的第一个发送peer。
  • Outpoint:唯一标识unspent transaction output的transaction hash和output index。需作为输入来组成一笔新的交易。
  • Payment hash:HTLC中包含了payment hash,payment hash为payment preimage的hash值。
  • Payment preimage:为付款已收到的证明,由最终接收方持有。只有最终接收方知道该秘密。最终接收方为了release funds,需release该preimage。支付preimage 在HTCL中以payment hash的方式存在。
  • Peers:为两个相互通讯的节点。2个peers在建立通道之前可相互gossip。2个peers可通过建立通道来相互交易。
  • Penalty transaction:通过使用commitment revocation private key来消费revoked commitment transaction中所有outputs的交易。若某peer试图通过广播一个废弃的commitment transaction的方式来作弊,则另一peer可发起penalty transaction。
  • Per-commitment secret:每个commitment transaction都基于a per-commitment secret来派生keys,通过该方式,所有之前commitments的一系列per-commitment secrets都可以压缩的方式存储。
  • Processing node:为正在处理a packet的节点。该packet由origin node发起,路由发往final node。Processing node作为receiving peer来接收消息,作为sending peer来发送packet。
  • Receiving node:为正在receiving 消息的节点。
  • Revoked commitment transaction:为已废弃的old commitment transaction。因为已产生新的commitment transaction。
  • Revoked transaction close:为一个无效的通道关闭,广播的是废弃的commitment transaction。由于另一peer知道该commitment revocation secret key,可发起penalty transaction。
  • Route:为闪电网络中的路径,允许由初始节点发起的支付,经由一个或多个hops,到达最终节点。
  • Sending node:为正在sending消息的节点。
  • Sending peer:为正在给直接连接的peer发送消息的节点。
  • Unilateral close:(单方关闭)为通道的不合作关闭方式。通过广播commitment transaction来实现。该交易比closing transaction更大(即更低效),commitment被广播的peer在预设时间内,无法访问其自身的outputs。

2. BOLT #1: Base Protocol

此协议假定一个底层的经过身份验证且有序的传输机制,该机制负责对单个消息进行帧处理。详细实现可参见 BOLT #8,也可替代为其他传输机制。
默认的TCP端口为9735,对应的16进制表示为0x2607,为 the Unicode code point for LIGHTNING
除非明确指出,所有数据field都是以unsigned big-endian形式存储。(默认SHA2和比特币公钥都是以big endian的方式编码的。)

每个peer有一个单独的连接(connection),通道信息(其中包含channel ID)应可在单个连接上复用。

2.1 闪电消息格式

解密后,所有的闪电消息格式为:

  • 1)type:为2字节的big-endian field,表明消息的类型。
  • 2)payload:为可变长度的payload,包含了剩余message的内容,其格式与type类型匹配。
  • 3)extension:为可选的 TLV(Type-Length-Value Format) stream。

不同的type类型,其解析payload的方式也不同。type类型遵循”It’s ok to be odd“规则,若不确定接收方是否理解,可发送奇数类型。(”It’s ok to be odd“规则 允许将来的可选extension扩展,而不需要协商,也不需要在客户端进行特殊编码。在可选扩展中,未来可包含额外的TLV data。注意,只有当payload长度不等于65535最大长度时,才可附加extension field。)

闪电消息类型逻辑上可分为5类,由最高有效位的值来区分:

  • Setup & Control (类型值为0-31):表示建立连接、control、supported features以及error reporting相关的消息。Setup类型对应有init消息和error消息;Control类型对应有ping消息和pong消息
  • Channel (类型值为31-127):用于建立和关闭微支付通道的消息。
  • Commitment(类型值为128-255):用于更新当前commitment transaction的消息,包括adding、revoking、settling HTLCS以及更新费用和交换签名。
  • Routing(类型值为256-511):节点和通道声明消息,以及任意的active route exploration消息。
  • Custom(类型值为32768-65535):为测试和应用相关消息。

应传输层要求,message的size应为2字节的unsigned int,因此消息的最大size为65535 bytes。(可借助密码学wrapping技术来保证消息长度不超过65535字节。实际实现时,可将message数据以8字节对齐的方式存储,但是额外附加6个字节被认为是一种浪费,因此只在对message解码到buffer中时才做一个6字节的pre-padding。)

对于sending node:

  • 未经事先协商,不得发送此处未列出的evenly-typed message。
  • 未经事先协商,不得在extension中发送evenly-typed TLV records。
  • 协商中的可选项:必须包含该可选项中注释的所有字段。
  • 当定义custom messages时:为避免与其他custom type冲突,应选择随机type值;应不与此处列出的其他测试值冲突;当要求regular nodes可忽略additional data时,应选择奇数type值;当regular node可拒绝消息并关闭连接时,应选择偶数type值。

对于receiving node:

  • 当接收到奇数或未知type值时,必须忽略所接收到的消息;
  • 当接收到偶数或未知type值时,必须关闭连接,可fail通道。
  • 当接收到已知消息,但其内容长度不够时:必须关闭连接,可fail通道。
  • 当接收到的消息包含extension时:可忽略该extension;或者若该extension为invalid的,必须关闭连接,可fail通道。

2.2 TLV (Type-Length-Value Format)

当在现有消息类型中添加新的field时,为了向后兼容,可使用TLV。
tlv_record表示一个单独的field,其编码格式为:

  • [bigsize: type]:type以BigSize格式编码。为64位标识。
  • [bigsize: length]:以BigSize格式编码,表示value的字节大小。
  • [length: value]:根据type类型来编解码。

tlv_stream表示0个或多个tlv_record,直接将tlv_record串接在一起。当用于扩展现有消息时,tlv_stream通常位于现有所有定义fields之后。

2.3 基础类型

基础类型有:

  • byte: an 8-bit byte
  • u16: a 2 byte unsigned integer
  • u32: a 4 byte unsigned integer
  • u64: an 8 byte unsigned integer

TLV record中的类型有:

  • tu16: a 0 to 2 byte unsigned integer
  • tu32: a 0 to 4 byte unsigned integer
  • tu64: a 0 to 8 byte unsigned integer

同时,有一些自定义类型:

  • chain_hash: a 32-byte chain identifier (see BOLT #0)
  • channel_id: a 32-byte channel_id (see BOLT #2)
  • sha256: a 32-byte SHA2-256 hash
  • signature: a 64-byte bitcoin Elliptic Curve signature
  • point: a 33-byte Elliptic Curve point (compressed encoding as per SEC 1 standard)
  • short_channel_id: an 8 byte value identifying a channel (see BOLT #7)
  • bigsize: a variable-length, unsigned integer similar to Bitcoin’s CompactSize encoding, but * big-endian. Described in BigSize.

3. BOLT #2: Peer Protocol for Channel Management

某些消息会使用channel_id来标识通道。channel_id派生自funding transaction,结合了funding_txidfunding_output_index,采用了big-endian异或操作(即,funding_output_index改变了最后2个字节)。
在通道建立之前,使用的是随机nonce值 temporary_channel_id。注意,不同节点之间可能存在相同的temporary_channel_id值。若在创建funding transaction之前,通过channel_id来引用通道的API是不安全的,同时该API产生的交易即使确认了也是不持久的。而且除非你知道对应funding output对应的script pubkey,否则没有办法来避免channel id重复的问题。在funding_created之前,由协议提供并交换的channel标识为(source_node_id, destination_node_id, temporary_channel_id) tuple。

3.1 建立通道

在对连接进行认证(BOLT #8)和初始化(BOLT #1)之后,就可开始建立通道。
具体流程为:

  • 1)funding node (funder) 发送open_channel消息。
  • 2)另一node (fundee) 发送accept_channel消息。
  • 3)在锁定通道参数的情况下,funder可创建funding transaction和2个版本的commitment transaction(具体见BOLT #3)。然后funder将funding output的outpoint、funding_created消息、签名给fundee版本的commitment transaction 发送给fundee。
  • 4)一旦fundee收到了该funding output,其可生成签名给funder版本的commitment transaction,并将其funding_signed消息发给funder。
  • 5)当funder收到funding_signed消息,其必须将funding transaction广播至比特币主链上。
  • 6)当发送/收到funding_signed消息之后,双方都需等待funding transaction交易上链并达到指定的深度(区块确认数)。当双方都发出了funding_locked消息之后,通道建立完成,即可进行normal operation了。【通道内发送的金额以msat为单位,尽管上链的金额应不低于某dust limit。】
    funding_locked消息中包含了用于构建channel authentication proof的信息。

若在以上任一环节失败,或某节点判定另一节点提供的通道条件不合适,则通道建立失败。

注意,多个通道可并行操作,所有的通道的消息要么以temporary_channel_id(在funding transaction 创建之前)标记,要么以channel_id(派生自funding transaction)标记。

    +-------+                              +-------+
    |       |--(1)---  open_channel  ----->|       |
    |       |<-(2)--  accept_channel  -----|       |
    |       |                              |       |
    |   A   |--(3)--  funding_created  --->|   B   |
    |       |<-(4)--  funding_signed  -----|       |
    |       |                              |       |
    |       |--(5)--- funding_locked  ---->|       |
    |       |<-(6)--- funding_locked  -----|       |
    +-------+                              +-------+

    - where node A is 'funder' and node B is 'fundee'
  • 1)A节点发起创建新通道的请求,在open_channel消息中的关键字段有:
[chain_hash:chain_hash]:通道所锚定的链,为该链的genesis hash。
[32*byte:temporary_channel_id]:为临时channel id(对该A节点来说是唯一标识的),在funding_created会替换为正式的channel_id(由funding transaction派生)。
[u64:funding_satoshis]:充入通道内的资金。单位为sat。
[u64:push_msat]:充入通道内的资金。单位为msta。为funding_satoshis*1000。
[u64:dust_limit_satoshis]:比特币链上支付的最小金额为546sat。低于该阈值的金额不会映射上链。
[u64:channel_reserve_satoshis]:为the minimum amount that the other node is to keep as a direct payment。该值应大于等于dust_limit_satoshis。
[u64:max_htlc_value_in_flight_msat]:为未偿付HTLC总价值的上限,允许节点限制其对HTLC的敞口
[u64:htlc_minimum_msat]:本节点所能接受的最小金额的HTLC。
[u16:max_accepted_htlcs]:限制其他节点可以提供的未完成HTLC的数量。

[point:funding_pubkey]、[point:revocation_basepoint]、[point:payment_basepoint]、[point:delayed_payment_basepoint]、[point:htlc_basepoint]为secp256k1公钥。【
其中:
    funding_pubkey:为funding transaction output的2-of-2 multisig script中的公钥。
    各种_basepoint字段:用于为每个commitment transaction派生唯一的秘钥。每个commitment transaction都使用不同唯一的localpubkey和remotepubkey。
       这样可保证对于外部观察者而言,每个commitment transaction的交易ID是不可预测的。当将penalty交易外包给第三方时,该属性可保证隐私。
】
[point:first_per_commitment_point]:为第一笔commitment transaction的per-commitment point。
[byte:channel_flags]:设置为0,表示 publicly announce the channel.。用于表示通道发起方是否将该该通道向网络公开。
[u32:feerate_per_kw]:为计算commitment transaction和HTLC transaction的fee rate。通常只与发送方(支付费用的人)有关,但HTLC交易也会支付费率;因此,不合理的高费率也可能会惩罚接收者。
[u16:to_self_delay]:对方节点的to-self output必须等待的区块数,用于OP_CHECKSEQUENCEVERIFY delays。用于breakdown情况下需等待的时长,过了之后才能赎回自己的资金。

upfront_shutdown_script和shutdown_scriptpubkey:双向关闭通道时所使用的公钥脚本。
[open_channel_tlvs:tlvs]:
  • 2)B节点接受A节点的通道开通请求,回应accept_channel消息中的关键字段有:
[32*byte:temporary_channel_id]:必须与open_channel消息中的temporary_channel_id一致。
[u64:dust_limit_satoshis]:必须小于等于open_channel消息中的channel_reserve_satoshis值。
[u64:max_htlc_value_in_flight_msat]
[u64:channel_reserve_satoshis]:必须大于等于open_channel消息中的dust_limit_satoshis值。
[u64:htlc_minimum_msat]
[u32:minimum_depth]:为防止funding transaction双花所需等待的区块数。
[u16:to_self_delay]
[u16:max_accepted_htlcs]
[point:funding_pubkey]
[point:revocation_basepoint]
[point:payment_basepoint]
[point:delayed_payment_basepoint]
[point:htlc_basepoint]
[point:first_per_commitment_point]
[accept_channel_tlvs:tlvs]
  • 3)在锁定通道参数的情况下,funder可创建funding transaction和2个版本的commitment transaction(具体见BOLT #3)。然后funder将funding output的outpoint、funding_created消息、签名给fundee版本的commitment transaction 发送给fundee。
    A节点验证完B发来的accept_channel消息之后,A会创建初始(第一笔)commitment transaction的outpoint,并在funding_created消息中描述该outpoint,funding_created消息中的关键字段有:
[32*byte:temporary_channel_id]:必须与open_channel消息中的temporary_channel_id一致。
[sha256:funding_txid]:为A节点所创建的第一笔commitment  transaction(为non-malleable transaction)的交易ID。不可将该交易广播上链。
[u16:funding_output_index]:为funding transaction output中的output序号。仅为2字节,不超过65535个output。
[signature:signature]:为A节点的funding_pubkey对第一笔commitment transaction的签名。
  • 4)一旦fundee收到了该funding output,其可生成签名给funder版本的commitment transaction,并将其funding_signed消息发给funder。
    B节点验证完funding_created之后,回应funding_signed消息中有:
[channel_id:channel_id]:生成正式的channel_id来标记该通道。派生自funding_txid和funding_output_index,对二者进行big-endian异或计算。
[signature:signature]:使用B的funding_pubkey对A发来的第一笔commitment transaction进行签名。
  • 5)当funder收到funding_signed消息,其必须将funding transaction广播至比特币主链上。
  • 当发送/收到funding_signed消息之后,双方都需等待funding transaction交易上链并达到指定的深度(区块确认数)。当双方都发出了funding_locked消息之后,通道建立完成,即可进行normal operation了。
    funding_locked消息中包含了用于构建channel authentication proof的信息。
    A确认其广播上链的funding transaction达到了在accept_channel中要求的minimum_depth时,会向B发送funding_locked消息:
[channel_id:channel_id]
[point:next_per_commitment_point]:为下一个commitment transaction将使用的per-commitment point。
  • 6)B确认A的funding transaction交易上链达到了指定的深度后,向A发送funding_locked消息。至此,通道创建完成。

3.2 关闭通道

节点可协商以mutual close的方式关闭连接,与unilateral close不同,mutual close支持双方以更低的手续费立刻获取各自的资金。

关闭发生在2种阶段:

  • 1) 一方表示希望清理通道(因此不再接受新的HTLCs)
  • 2)当所有的HTLCs都处理完毕后,可开始协商最终的通道关闭。
 +-------+                              +-------+
 |       |--(1)-----  shutdown  ------->|       |
 |       |<-(2)-----  shutdown  --------|       |
 |       |                              |       |
 |       | <complete all pending HTLCs> |       |
 |   A   |                 ...          |   B   |
 |       |                              |       |
 |       |--(3)-- closing_signed  F1--->|       |
 |       |<-(4)-- closing_signed  F2----|       |
 |       |              ...             |       |
 |       |--(?)-- closing_signed  Fn--->|       |
 |       |<-(?)-- closing_signed  Fn----|       |
 +-------+                              +-------+

mutual close关闭通道的流程为:

  • Closing Initiation:shutdown :任一节点或2个节点发送shutdown消息来启动关闭,shutdown消息会附带其希望收款的scriptpubkey
  • Closing Negotiation:closing_signed:一旦shutdown完成,且通道内没有HTLCs,即the final current commitment transaction中没有HTLCs,即可开始closing fee 协商。Funder可选择一个自认为公平的费率,然后使用shutdown消息中附带的scriptpubkey值来对closing transaction和其自认公平的费率进行签名,并发送该签名。另一节点以类似的方式响应,使用其自认公平的费率。这种交互持续到直到双方达成相同的费率或者某一方fail the channel。

详细的消息流为:

  • 1)A发起关闭请求,发送shutdown消息:【不再接受新的HTLCs】
[channel_id:channel_id]
[u16:len]
[len*byte:scriptpubkey]:为A希望收款的scriptpubkey。
  • 2)B回应关闭请求,在shutdown消息中提供其收款地址。
  • 3)等待通道内HTLCs都处理完毕后。最后一笔commitment transaction中将没有HTLCs。然后开始关闭费用协商。
    Funder可选择一个自认为公平的费率,然后使用shutdown消息中附带的scriptpubkey值来对closing transaction和其自认公平的费率进行签名,并发送该签名。另一节点以类似的方式响应,使用其自认公平的费率。这种交互持续到直到双方达成相同的费率或者某一方fail the channel。
    A发送closing_signed消息:
[channel_id:channel_id]
[u64:fee_satoshis]:A认为合理的手续费区间。B需要从该区间选一个fee值。
[signature:signature]:采用shutdown消息中的scriptpubkey字段内的公钥对closing交易进行签名。
[closing_signed_tlvs:tlvs]

3.3 正常的通道操作

当节点双方交换完funding_locked之后(也可为announcement_signatures),通道将可借助Hashed Time Locked Contracts来发起支付。

批量修改(changes are sent in batches):在commitment_signed消息之前,发送一个或多个update_消息,具体流程为:

    +-------+                               +-------+
    |       |--(1)---- update_add_htlc ---->|       |
    |       |--(2)---- update_add_htlc ---->|       |
    |       |<-(3)---- update_add_htlc -----|       |
    |       |                               |       |
    |       |--(4)--- commitment_signed --->|       |
    |   A   |<-(5)---- revoke_and_ack ------|   B   |
    |       |                               |       |
    |       |<-(6)--- commitment_signed ----|       |
    |       |--(7)---- revoke_and_ack ----->|       |
    |       |                               |       |
    |       |--(8)--- commitment_signed --->|       |
    |       |<-(9)---- revoke_and_ack ------|       |
    +-------+                               +-------+

与直觉相反,这些更新会先添加到给对方节点的commitment transaction中,待对方节点通过revoke_and_ack方式确认后,才会将这些更新添加到本地节点自身的commitment transaction中。

每次更新都会遍历以下状态:

  • 1)pending on the receiver
  • 2)在receiver的最新commitment transaction中
  • 3)废弃了receiver之前的commitment transaction,同时the update is pending on the sender
  • 4)在sender最新的commitment transaction中
  • 5)废弃了sender之前的commitment transaction。

由于2个节点是独立更新的,所以这2个commitment transaction可能会无限期地不同步。这没有关系,重要的是双方是否不可撤销地致力于某一特定的更新。

3.3.1 转发HTLCs

通常,节点发送HTLC的原因有2种:

  • 发起其自身的支付
  • 转发另一节点的支付。

在转发情况下,必须注意确保传出的HTLC不能被赎回,除非传入的HTLC可以被赎回。在下列情况下,HTLC的相应增加或删除可被视为是不可撤销committed的:

  • 1)with/without commitment transaction由通道内的2个节点commit了,且任何之前的without/with commitment transaction均已废弃。或者
  • 2)with/without commitment transaction已不可逆地提交上链了。

3.3.2 选择cltv_expiry_delta

一旦HTLC超时,它可以被完成或者超时;无论是提供的还是收到的HTLC,都必须注意这个过渡。
考虑下面的场景,其中A发送HTLC到B,转发给C,一旦收到付款,就立即交付货物:

  • 1)C需要确认B发来的HTLC不会超时,即使B不响应。即,B在链上使该HTLC超时之前,C可在链上完成该incoming HTLC。
  • 2)B必须确保C所完成的HTLC来自于B,B完成的incoming HTLC来自于A。即,B可get the preimage from C,且fulfill the incoming HTLC on-chain before A can time it out on-chain。

这其中涉及的关键设置有:

  • BOLT #7 中的cltv_expiry_delta:为转发情况下(B)的minimum difference in HTLC CLTV timeouts.
  • BOLT #9 中的min_final_cltv_expiry:为终端情况下(C)的minimum difference between HTLC CLTV timeout and the current block height。

3.3.3 添加HTLC:update_add_htlc

通道内的任一节点都可发送update_add_htlc来给另一方提供HTLC,通过提供payment preimage可赎回该HTLC。
支付金额以millisatoshi为单位,尽管链上执行的金额需大于dust limit(在commitment中,该金额会按BOLT #3 进行四舍五入)。

update_add_htlc消息中:

[channel_id:channel_id]
[u64:id]:第一个HTLC的id为0,后续提供的每个HTLC该id加1。
[u64:amount_msat]:金额单位为msat。
[sha256:payment_hash]:
[u32:cltv_expiry]:HTLC超时时间。
[1366*byte:onion_routing_packet]:包含一个模糊的跳跃列表,以及路径上每个跳跃的指令。以payment_hash为关联数据,采用HMAC算法来对HTLC进行commit,可防止使用 之前的onion_routing_packet+不同的payment_hash进行重放攻击。

3.3.4 移除HTLC:update_fulfill_htlcupdate_fail_htlcupdate_fail_malformed_htlc

节点仅可移除由其它节点添加的HTLCs。
移除HTLC通常有4种原因:

  • 已提供了payment preimage:对应update_fulfill_htlc消息:
[channel_id:channel_id]
[u64:id]
[32*byte:payment_preimage]
  • HTLC已超时:对应update_fail_htlc消息。
  • HTLC路由失败:对应update_fail_htlc消息:
[channel_id:channel_id]
[u64:id]
[u16:len]
[len*byte:reason]
  • HTLC格式错误:对应update_fail_malformed_htlc消息:
[channel_id:channel_id]
[u64:id]
[sha256:sha256_of_onion]
[u16:failure_code]

3.3.5 迄今为止的Committing Updates:commitment_signed

当节点为远程的commitment完成了修改后,其可应用该远程commitment,签名the resulting transaction(根据BOLT #3中定义),并发送commitment_signed消息。

commitment_signed消息内容为:

[channel_id:channel_id]
[signature:signature]:A节点对发给B的resulting transaction进行签名。
[u16:num_htlcs]:该commitment中包含的htlc数量。
[num_htlcs*signature:htlc_signature]:对每个HTLC交易的签名,与commitment transaction中的顺序一致。

3.3.6 Completing the Transition to the Updated State:revoke_and_ack

一旦收到commitment_signed,对签名进行验证并确认其为有效的新commitment transaction之后,在回复的revoke_and_ack消息中附加the commitment preimage for the previous commitment transaction。

可将revoke_and_ack简单理解为是对收到commitment_signed之后的响应,因此对于commitment_signed sender来说,其在发送消息和更新任何pending updates之间存在逻辑上的时间差。

revoke_and_ack消息中有:

[channel_id:channel_id]
[32*byte:per_commitment_secret]:接收方发出的前一commitment transaction中对应的preimage(即前一commitment transaction中各公钥对应的私钥信息)【应根据该秘密可计算出前一commitment transaction中的`per_commitment_point`字段。】
[point:next_per_commitment_point]:为接收方下一个commitment transaction中将用到的值。

3.3.7 更新费用:update_fee

update_fee消息由支付比特币交易费的节点发出。与其他update类似,其首先commit to the receiver’s commitment transaction,然后收到相应的acknowledgement 后commit to the sender’s。
与HTLC不同,update_fee永不关闭,仅是简单的替换。

存在竞争的可能性,因为接收者可以在收到update_fee之前添加新的HTLC。在这种情况下,一旦接收方最终确认了update_fee,发送方就可能无法支付其自己的commitment transaction的费用。在这种情况下,费用将低于费率,如BOLT # 3 所述。
update_fee消息中有:

[channel_id:channel_id]
[u32:feerate_per_kw]

3.4 消息重传:channel_reestablish

由于通讯传输是不可靠的,可能需不时地进行重连,所以传输的设计已经明确地从协议中分离出来。

具体见BOLT #7。
channel_reestablish消息内有:

[channel_id:channel_id]
[u64:next_commitment_number]:为48位递增计数器,每个commitment transaction该值会加1。且每个节点该计数器从0开始,分别独立计数。仅用于re-establishment。
[u64:next_revocation_number]
[32*byte:your_last_per_commitment_secret]
[point:my_current_per_commitment_point]

4. BOLT #3: Bitcoin Transaction and Script Formats

transactions outputs的排序规则为:

  • 首先根据transaction outputs的值(以整数satoshi为单位,注意HTLC outputs中的millisatoshi必须忽略);
  • 接着是scriptpubkey,使用memcmp比较common-length prefix的字典顺序,然后选择更短的script;
  • 最后,对于HTLC outputs,按cltv_expiry升序排列。

闪电网络中的大多数交易outputs都为 pay-to-witness-script-hash (P2WSH) outputs:即P2SH的Segwit版本。

为了消费这些outputs,witness stack中的最后一个元素必须为the actual script that was used to generate the P2WSH output that is being spent。

Funding Transaction Output 为P2WSH to :(其中pubkey1为词典序更小的funding_pubkey,pubkey2为词典序更大的。)

2 <pubkey1> <pubkey2> 2 OP_CHECKMULTISIG

4.1 Commitment Transaction

commitment transaction格式为:

  • version: 2
  • locktime:高8位为0x20,低24位为模糊的commitment number
  • txin count: 1
    – txin[0] outpoint: txid and output_index from funding_created message
    – txin[0] sequence: upper 8 bits are 0x80, lower 24 bits are upper 24 bits of the obscured commitment number
    – txin[0] script bytes: 0
    – txin[0] witness: 0 <signature_for_pubkey1> <signature_for_pubkey2>

The 48-bit commitment number is obscured by XOR with the lower 48 bits of:

SHA256(payment_basepoint from open_channel || payment_basepoint from accept_channel)

该值可让2节点根据index快速找到某废弃的commitment transaction。

Commitment Transaction Outputs:可支持penalty transactions,必须等待to_selft_delay 个blocks。该等待操作可通过second-stage HTLC交易来实现(HTLC-success for HTLCs accepted by the local node, HTLC-timeout for HTLCs offered by the local node)。

将HTLC output分为不同交易阶段的原因在于,HTLC要么timeout,要么在to_self_delay期内被fulfill。否则,HTLC所需的最少timeout将随着该delay而延长,导致HTLC穿越网络的超时时间更长。
commitment transaction的每个output将四舍五入为整sat值。若该值减去HTLC的手续费,小于该commitment transaction owner设置的dust_limit_satoshis值,则不应生成该output。

Commitment Transaction Outputs类型有:

  • 1)to_local Output:该output将资金发回该commitment transaction owner,必须使用OP_CHECKSEQUENCEVERIFY进行time lock。而对手方无需delay,通过提交revocation private key即可拿回其资金。该output为 version-0 P2WSH + a witness script:【己方需提供:<local_delayedsig> <> 并等待to_self_delay才生效;对手方提供:<revocation_sig> 1 即立即生效。】
OP_IF
    # Penalty transaction
    <revocationpubkey>
OP_ELSE
    `to_self_delay`
    OP_CHECKSEQUENCEVERIFY
    OP_DROP
    <local_delayedpubkey>
OP_ENDIF
OP_CHECKSIG
  • 2)to_remote Output:若在commitment transaction中使用了option_anchors,对应为:<remote_pubkey> OP_CHECKSIGVERIFY 1 OP_CHECKSEQUENCEVERIFY,需等待一个block的csv lock,然后提供<remote_sig>即可。若未使用option_anchors,该output就是简单的P2WPKH to remotepubkey
  • 3)to_local_anchor and to_remote_anchor Output (option_anchors):
  • 4)Offered HTLC Outputs:当HTLC-timeout之后,该output会将资金发送给an HTLC-timeout transaction;或者,通过使用payment preimage或revocation key,该output将资金发送给远程节点。该output是 a P2WSH + a witness script:
# To remote node with revocation key
OP_DUP OP_HASH160 <RIPEMD160(SHA256(revocationpubkey))> OP_EQUAL
OP_IF
    OP_CHECKSIG //输入为<revocation_sig> <revocationpubkey>
OP_ELSE
    <remote_htlcpubkey> OP_SWAP OP_SIZE 32 OP_EQUAL
    OP_NOTIF
        # To local node via HTLC-timeout transaction (timelocked).
        OP_DROP 2 OP_SWAP <local_htlcpubkey> 2 OP_CHECKMULTISIG
    OP_ELSE
        # To remote node with preimage.
        OP_HASH160 <RIPEMD160(payment_hash)> OP_EQUALVERIFY //输入为<remotehtlcsig> <payment_preimage>
        OP_CHECKSIG
    OP_ENDIF
OP_ENDIF
  • 5)Received HTLC Outputs:当HTLC-timeout或使用revocation key,该output将资金发送给远程节点;或者,通过成功的payment preimage,该output将资金发送给an HTLC-success transaction。该output为 a P2WSH + a witness script:
# To remote node with revocation key
OP_DUP OP_HASH160 <RIPEMD160(SHA256(revocationpubkey))> OP_EQUAL
OP_IF
    OP_CHECKSIG
OP_ELSE
    <remote_htlcpubkey> OP_SWAP OP_SIZE 32 OP_EQUAL
    OP_IF
        # To local node via HTLC-success transaction.
        OP_HASH160 <RIPEMD160(payment_hash)> OP_EQUALVERIFY
        2 OP_SWAP <local_htlcpubkey> 2 OP_CHECKMULTISIG
    OP_ELSE
        # To remote node after timeout.
        OP_DROP <cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
        OP_CHECKSIG
    OP_ENDIF
OP_ENDIF
  • 6)Trimmed Outputs:每个节点设置dust_limit_satoshis,不产生低于该值的outputs。这些不该产生的outputs标记为“trimmed”。a trimmed output被认为太小,不值得创建,而是添加到commitment transaction fee中。对于HTLC,需要考虑到第二阶段HTLC交易也可能低于该限额。

4.2 HTLC-Timeout and HTLC-Success Transactions

HTLC-Timeout 和 HTLC-Success 交易几乎一样,除了HTLC-Timeout交易为timelocked。
HTLC-Timeout 和 HTLC-Success 交易均可作为valid penalty transaction来花费。

version: 2
locktime: 0 for HTLC-success, cltv_expiry for HTLC-timeout
txin count: 1
	txin[0] outpoint: txid of the commitment transaction and output_index of the matching HTLC output for the HTLC transaction
	txin[0] sequence: 0 (set to 1 for option_anchors)
	txin[0] script bytes: 0
	txin[0] witness stack: 0 <remotehtlcsig> <localhtlcsig> <payment_preimage> for HTLC-success, 0 <remotehtlcsig> <localhtlcsig> <> for HTLC-timeout
txout count: 1
	txout[0] amount: the HTLC amount minus fees (see Fee Calculation)
	txout[0] script: version-0 P2WSH with witness script as shown below

该output的witness script为:

OP_IF
    # Penalty transaction
    <revocationpubkey> //该输入为<revocationsig> 1
OP_ELSE
    `to_self_delay`
    OP_CHECKSEQUENCEVERIFY
    OP_DROP
    <local_delayedpubkey> //该输入为<local_delayedsig> 0
OP_ENDIF
OP_CHECKSIG

4.3 Closing Transaction

注意每个节点有2种可能的变体:

  • version: 2
  • locktime: 0
  • txin count: 1
    – txin[0] outpoint: txid and output_index from funding_created message
    – txin[0] sequence: 0xFFFFFFFF
    – txin[0] script bytes: 0
    – txin[0] witness: 0 <signature_for_pubkey1> <signature_for_pubkey2>
  • txout count: 0, 1 or 2
    – txout amount: final balance to be paid to one node (minus fee_satoshis from closing_signed, if this peer funded the channel)
    – txout script: as specified in that node’s scriptpubkey in its shutdown message

4.4 费用

commitment transaction和HTLC transaction的费用需基于当前的feerate_per_kw和交易expected weight来计算。
The actual and expected weights vary for several reasons:

  • Bitcoin uses DER-encoded signatures, which vary in size.
  • Bitcoin also uses variable-length integers, so a large number of outputs will take 3 bytes to encode rather than 1.
  • The to_remote output may be below the dust limit.
  • The to_local output may be below the dust limit once fees are extracted.

Thus, a simplified formula for expected weight is used, which assumes:

  • Signatures are 73 bytes long (the maximum length).
  • There are a small number of outputs (thus 1 byte to count them).
  • There are always both a to_local output and a to_remote output.
  • (if option_anchors) there are always both a to_local_anchor and to_remote_anchor output.

This yields the following expected weights:(详细可见博客比特币闪电网络中的dust limit

Commitment weight (no option_anchors):   724 + 172 * num-untrimmed-htlc-outputs
Commitment weight (option_anchors):     1124 + 172 * num-untrimmed-htlc-outputs
HTLC-timeout weight (no option_anchors): 663
HTLC-timeout weight (option_anchors): 666
HTLC-success weight (no option_anchors): 703
HTLC-success weight (option_anchors): 706

commitment transaction的交易金额和交易费均从funder账号扣除。

举例为:
For example, suppose there is a feerate_per_kw of 5000, a dust_limit_satoshis of 546 satoshis, and a commitment transaction with:

  • two offered HTLCs of 5000000 and 1000000 millisatoshis (5000 and 1000 satoshis)
  • two received HTLCs of 7000000 and 800000 millisatoshis (7000 and 800 satoshis)

The HTLC-timeout transaction weight is 663, and thus the fee is 3315 satoshis. The HTLC-success transaction weight is 703, and thus the fee is 3515 satoshis

The commitment transaction weight is calculated as follows:

  • weight starts at 724.
  • The offered HTLC of 5000 satoshis is above 546 + 3315 and results in:
    • an output of 5000 satoshi in the commitment transaction
    • an HTLC-timeout transaction of 5000 - 3315 satoshis that spends this output
    • weight increases to 896
  • The offered HTLC of 1000 satoshis is below 546 + 3315 so it is trimmed.
  • The received HTLC of 7000 satoshis is above 546 + 3515 and results in:
    • an output of 7000 satoshi in the commitment transaction
    • an HTLC-success transaction of 7000 - 3515 satoshis that spends this output
    • weight increases to 1068
  • The received HTLC of 800 satoshis is below 546 + 3515 so it is trimmed.

The base commitment transaction fee is 5340 satoshi; the actual fee (which adds the 1000 and 800 satoshi HTLCs that would make dust outputs) is 7140 satoshi. The final fee may be even higher if the to_local or to_remote outputs fall below dust_limit_satoshis.

4.5 交易中所使用key的派生规则

每个commitment transaction都使用唯一的localpubkeyremotepubkey
HTLC-success和HTLC-timeout 交易使用local_delayedpubkeyrevocationpubkey

每个交易的这些key会根据per_commitment_point修改。

要求每笔交易的key是变化的,是为了可外包trustless watching for revoked transaction。

考虑效率问题,这些key基于由单个种子产生的一系列per-commitment secrets来生成,使得receiver可对这些秘密进行压缩存储:

localpubkey, local_htlcpubkey, remote_htlcpubkey, local_delayedpubkey, and remote_delayedpubkey Derivation

5. BOLT #5: Recommendations for On-chain Transaction Handling

闪电网络支持2方(a local node和a remote node),通过给每一方一个cross-signed commitment transaction,用于描述通道内的当前状态(通常为当前balance)的方式,来实现链下交易。每当有新的支付时,该commitment transaction都将更新,且总是spendable的。

关闭通道的方式通常有3种:

  • 最好的方式——mutual close:local node和remote node同时同意关闭通道。他们发起closing transaction(与commitment transaction类似,但是没有任何的pending payments),并将该closing transaction广播上链。
  • 不好的方式——unilateral close:出了问题,可能双方都没有恶意。比如说,可能有一方崩溃了。一方公布最新承诺交易。
  • 最不好的方式——revoked transaction close:某一方试图作弊,广播过期的commitment transaction。

闪电网络为trustless的,可有效处理以上3种情况。

任何unspent output 可认为是unresolved。可通过resoling transaction来花费unspent output。
当output在链上记录的深度超过100个区块,即可认为该output是resolved的。100个区块大于目前已知的比特币分叉高度,同时等于矿工激励等待的确认数。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值