闪电网络建立在微支付通道的基础上,要理解闪电网络就要首先理解微支付通道。
下面我们讨论一下微支付通道建立过程。
考虑如下场景:A 是用户,B 是一个数据提供商,B 需要把1个 100G 的大数据文件发给A,价值是100元。
为了降低风险,A 不想1次性把100元给 B,而是每接收到1G的数据,给 B 支付1元。
那就需要 100 次的交易。现在看一下,微支付通道如何解决这个问题:
- 生成但不发起证金交易(Funding Transaction)用户A生成1笔保证金交易,把100元打到 A、B 控制的多重签名的地址上面。这笔钱,需要 A,B 2个人同时出具私钥,才能把钱取出来。
- 生成并保存退款交易(Refund Transaction)用户 A 生成一笔以保证金交易为输入的退款交易,然后把交易发送给 B 让其签名,签名返回给 A。用户A验证保证金交易内容无误后,提交第1步生成保证金交易。
关于保证金交易1、保证金交易的
nLockTime
为一个>0
的值,也就是该笔交易是 Hold 在那的,不会立即生效。2、保证金交易的输出有2个:A,100元;B,0元。
3、保证金交易的目的在于确保第一步生成的保证金交易不会被 B 用户锁死。
- 不断发起承诺交易用户 A 拷贝一份退款交易,并调整输出为:A, 99元;B, 1元,签名并发送给 B。B 保留这个交易,不广播到网络上。这个交易的目的在于给用户 B 一元。B 收到用户承诺交易之后,把 1G 文件发送给 A;等 A 收到 B 的 1G 文件之后,重新调整输出,变成: A,98;B,2元。A,B 重新签名,A 再把这个交易发给 B 。如此重复直到最终结束,这些交易不会被广播到网络上,只在 A、B之 间传递。
- 发起清算交易(Settlement Transaction)在 A 收到最后的 1个G的文件,发起清算交易。这笔交易输出为:A,0元, B,100元。其
nLockTime = 0
,B 收到这个交易,广播到网络上,交易立即生效,B 收到100元。
微支付通道的巧妙之处
- 整个过程,只有第一步的保证金交易和最后一步的清算交易会广播到网络上,中间的交易都不会广播。
- 如何避免 B 跑路,A 的钱永远锁死在公共账号里面?这个是通过在确认退款交易无误后才会发送保证金交易来保证的。
- 如何避免 A 跑路,B 拿不到自己的钱?每个承诺交易都有 A,B 共同的签名。如果 A 跑路了,B 就把最新的交易广播到网络上,该交易被执行,B 就会拿到最新的钱。承诺交易有个特点,每1次交易 的
nLockTime
,都是逐级减小的,所以 B 把最新的交易广播到网络上之后,肯定会被最先打包,最先执行。先前其他的交易就不会被执行了。 - 如何避免 A、B 篡改交易内容?任何 1 笔交易里面,都是先让 B 签名,再返回给 A,A 再签名,再发给 B。每笔交易里面都有 A,B 的双重签名,B 改了交易内容,和 A 的签名就对不上了,反过来,A 改了交易内容,就和 B 的签名对不上了。所以 A,B 都不可能更改篡改交易内容!!
- 如何防止 A 双花这笔钱?在第2步里面,A拿到了退款交易,A把这个交易广播到网络上,拿回这100元,再花到别处呢?做不到。因为退款交易有
nLockTime
,处于锁定状态。并且这个nLockTime > 后面的任何1笔承诺交易的值
。
微支付通道的不足
- 它是单向的,只能用来 A 给 B 转账。如果反过来,需要另外再建立1个 B 到 A 的通道。
nLockTime
的限制。假设 B 跑路了,A 也要等到退款交易的nLockTime
到期了,才能拿回自己的钱;同样,假设 A 跑路了,B 也要等到承诺交易的nLockTime
到期了,拿到属于自己的钱。