比特币闪电网络论文笔记参见:
- Bitcoin的闪电网络
闪电网络实际实现参见设计文档 Basis of Lightning Technology (BOLT) :
- Lightning Network In-Progress Specifications
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)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
- 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。
此协议假定一个底层的经过身份验证且有序的传输机制,该机制负责对单个消息进行帧处理。详细实现可参见 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通道。
当在现有消息类型中添加新的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之后。
基础类型有:
- 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.
某些消息会使用channel_id
来标识通道。channel_id
派生自funding transaction,结合了funding_txid
和 funding_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。
在对连接进行认证(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 ----->| |
| || B |
| || |
| || |
| || |
| || |
| || |
| |--(2)---- update_add_htlc ---->| |
| || |
| A || |
| |
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?