天涯书库 > 区块链:从数字货币到信用社会 > 第三章区块链进阶[18] >

第三章区块链进阶[18]

一、简单支付验证(SPV)

简单支付验证(Simplified Payment Verification,简称SPV)是一种无须维护完整的区块链信息,只需要保存所有的区块头部信息即可进行支付验证的技术。该技术可以大大节省区块链支付验证用户的存储空间,减轻用户存储负担,降低区块链未来交易量剧增而给用户带来的压力。以比特币系统为例,节点只需保存所有区块头信息,即可进行交易支付验证。节点虽然不能独立验证交易,但能够从区块链其他节点获取交易验证的必要信息,从而完成交易支付验证,同时还可以得到整个区块链网络对交易的确认数。

要理解SPV的概念,首先需要理解如下两类概念的区别。

一是SPV与轻钱包(或瘦客户端)的区别。轻钱包指的是节点本地只保存与其自身相关的交易数据(尤其是可支配交易数据),但并不保存完整区块链信息的技术。SPV的目标是验证某个支付是否真实存在,并得到了多少个确认。比如爱丽丝(Alice)收到来自鲍伯(Bob)的一个通知,鲍伯声称已经从其账户中汇款一定数额的钱给了爱丽丝。如何快速验证该支付的真实性,是SPV的工作目标。轻钱包或瘦客户端的目标不仅是支付验证,而且是用于管理节点自身的资产收入、支付等信息。比如爱丽丝使用轻钱包或瘦客户端管理自身在区块链的收入信息、支出信息,在本地只保存与爱丽丝自身相关的交易数据,尤其是可支配交易数据。轻钱包与SPV的最大区别是,轻钱包节点仍需下载每个新区块的全部数据并进行解析,获取并本地存储与自身相关的交易数据,只是无须在本地保存全部数据而已。而SPV节点不需要下载新区块的全部数据,只需要保存区块头部信息即可。虽然轻钱包或瘦客户端中部分借鉴了SPV的理念,但和SPV是完全不同的。

二是区块链支付验证与区块链交易验证的区别。SPV指的是区块链支付验证,而不是区块链交易验证。这两种验证方式存在很大的区别。区块链交易验证的过程比较复杂,包括账户余额验证、双重支付判断等,通常由保存区块链完整信息的区块链验证节点来完成。而支付验证的过程比较简单,只是判断该笔支付交易是否已经得到了区块链节点共识验证,并得到了多少的确认数即可。还是以比特币系统为例,用户爱丽丝收到来自鲍伯的通知,鲍伯声称已经从其账户中汇款一定数额的钱给爱丽丝。爱丽丝进行交易验证的过程如下:首先,爱丽丝遍历完整的区块链账本,在区块链账本的交易中保存了鲍伯的历史交易信息(包括鲍伯的汇款账户、鲍伯的签名、历史收款人的地址以及汇款金额信息等),查询鲍伯的账户,就可以判断鲍伯提供的账户是否有足够的余额,如果余额不足则交易验证失败;其次,爱丽丝要根据区块链账本判断鲍伯是否已经支出了这个账户上的钱给别人,即是否存在双重支付问题,如果存在则交易验证失败;最后,判断鲍伯是否拥有其提供账户的支配权,如果判断失败则交易验证失败。而如果爱丽丝只是进行支付验证,则过程简单得多:通过SPV,爱丽丝可以进行支付快速验证,即检查此项支付交易是否已经被收录存储于区块链中,并得到了多少个确认数,就可以判断支付验证的合法性。详细的技术原理如下。

(一)SPV的技术原理

在区块链中,区块信息主要包括区块大小、区块头、交易数量和交易信息四部分内容。其中,区块头大小为固定字节,比如比特币中区块头的大小始终为80字节。区块头中一般包括如下信息:前一区块(也称父区块)的哈希值、区块中交易默克尔树的根哈希值、时间戳等。以比特币为例,其区块头的数据结构如表3-1所示。

表3-1 区块头的数据结构

通过区块的哈希值,可以识别出区块链中的对应区块。区块前后有序链接,每一个区块都可以通过其区块头的“前一区块的哈希值”字段引用前一区块。这样把每个区块均链接到各自前一区块的哈希值序列就创建了一条一直可以追溯到第一个区块(创世区块)的链条。前一区块的哈希值,可以确保区块链所记录的交易次序。默克尔树的根哈希值则可以确保收录到区块中的所有交易的真实性。

区块链节点利用SPV对支付进行验证的工作原理如下:

①计算待验证支付的交易哈希值;

②节点从区块链网络上获取并存储最长链的所有区块头至本地;

③节点从区块链获取待验证支付对应的默克尔树哈希认证路径;

④根据哈希认证路径,计算默克尔树的根哈希值,将计算结果与本地区块头中的默克尔树的根哈希值进行比较,定位到包含待验证支付的区块;

⑤验证该区块的区块头是否已经包含在已知最长链中,如果包含则证明支付真实有效;

⑥根据该区块头所处的位置,确定该支付已经得到的确认数量。

上述方法可以减轻用户的负担。以比特币为例,无论未来的交易量多大,区块头的大小始终只有80字节,按照每小时6个的区块生成速度,每年产出52560个区块。当只保存区块头时,每年新增存储需求约为4兆字节,100年后累计的存储需求仅为400兆字节,即使用户使用的是最低端的设备,正常情况下也完全能够负载。

SPV的工作原理中,最为关键和复杂的是步骤③,节点从区块链获取待验证支付对应的默克尔树哈希认证路径的过程。例如,一个区块链节点想要知道其钱包中某个比特币地址即将到达的某笔支付,该节点会在节点间的通信链接上建立起布鲁姆过滤器,限制只接受含有目标比特币地址的交易。当节点探测到某交易符合布鲁姆过滤器的要求时,将以默克尔区块消息的形式发送该区块。默克尔区块消息包含区块头和一条连接目标交易与默克尔树根的默克尔哈希认证路径。默克尔树哈希认证路径是验证待验证支付是否存在于默克尔树的关键条件,该认证路径由默克尔树所有路径中节点的哈希值共同构成,自下而上进行哈希计算。节点能够使用该路径找到与该交易相关的区块,进而验证对应区块中该交易的有无。如图3-1所示为根据交易A、B、C、D、E、F、G、H生成的默克尔树。这是一棵自下而上通过哈希运算生成的二叉树。叶子节点为交易信息的哈希值,叶子节点两两进行哈希运算得到其父节点,继续此过程,直至生成默克尔树根节点。需要注意的是,如果存在单个叶子节点无法匹配成对,则用复制的方法构成完整的二叉树,比如图3-2中交易H不存在,则可以将交易G的哈希值M(G)复制一份替代M(H),从而完成二叉树的生成过程。

图3-1 交易默克尔树结构示意图
图3-2 默克尔树哈希认证路径示意图

假设待验证交易为E,则交易E的默克尔树哈希认证路径为图3-2虚线框所示的M(F)、M(GH)和M(ABCD)。通过该哈希认证路径,即可以通过哈希计算找到一条链接交易E与默克尔树根的完整路径。

(二)SPV的功能扩展

虽然SPV可以高效地进行支付验证,但对于节点当前状态(账户余额、账户信息甚至合约状态等)均无法给出证明。SPV能否扩展并更进一步呢?以太坊对SPV的功能进行了扩展:每一个区块头,并非只包含一棵默克尔树,而是包含了三棵默克尔树,分别对应了三种对象——默克尔交易树、默克尔收据树和默克尔状态树。其中默克尔收据树和默克尔状态树是比特币等现有区块链系统没有的。默克尔收据树是由展示每一笔交易影响的数据条构成的默克尔树。而在默克尔状态树中,则保存账户信息、账户余额等信息。三棵默克尔树的功能分工如下。

①默克尔交易树:保存交易信息,用于验证交易是否真实包含于区块链中。

②默克尔收据树:保存某个地址的历史事件实例,比如一个交易是否成功执行、一个众筹合约是否完成了目标等。

③默克尔状态树:保存了账户名称、账户余额等信息。

基于上述三棵树,以太坊不仅可以实现SPV的支付验证,而且可以快速验证账户是否存在、了解账户余额甚至快速判断交易是否执行成功等信息,实现了良好的SPV扩展。

(三)SPV面临的问题

SPV面临的第一个是问题是SPV节点与区块链系统去中心化程度似乎存在一定的矛盾。随着SPV节点数量的增多,那么区块链参与完整验证的节点数量就会减少。然而,SPV却不能完全独立构成区块链。由于SPV节点没有存储完整的区块链信息,SPV的实现离不开存储区块链完整信息的节点或系统的辅助。

SPV面临的第二个问题是交易可锻性攻击[19]。由于SPV实现中一个关键步骤是根据支付哈希值定位其在区块中的位置,而该过程可能遭遇交易可锻性攻击。比如比特币系统中,交易可锻性攻击体现在交易ID(账号)可被伪造,而交易ID可被伪造的原因是比特币签名算法不够完善。以比特币为例,交易可锻性攻击的过程如下:在比特币的交易中,第三方交易系统会将交易发送方、接受方、交易金额等数据作为一个交易发送到比特币网络中,发送之前会对这条交易信息进行加密和签名,接着根据生成的签名最终获得一个哈希值,这个哈希值作为交易ID返回给提现的用户。一次交易请求过后,用户接收到的仅有一个交易ID,根据这个交易ID可以查看交易是否成功。当交易发送到比特币网络中后,网络中的各个节点会根据之前生成的签名来验证交易的真实性。问题就出在签名算法上:椭圆曲线数字签名ECDSA这个算法的一个问题是,修改签名的某个字节能够使签名依然校验成功,这样伪造签名之后交易依然能够成功进行。由于交易ID是根据签名生成的,而伪造之后的签名会生成一个完全不同的交易ID,第三方判断到两个ID不同便会确定当前交易失败,而事实上交易已经成功了。这时如果用户发现交易提示失败,可以再次发起交易,第三方交易系统一看之前交易确实失败了,那就会再进行一次交易。这时用户的比特币钱包里就会多收到一份比特币,也就造成了第三方交易平台资金损失。交易的可锻性体现在虽然交易签名被“锻造过”(即修改伪造过),但最终的交易依然有效。上述攻击对于SPV是有效的,因为在交易可锻性攻击场景中,伪造的交易和正常的交易都在区块链网络中,如果伪造的交易先被处理,那么攻击就成功。从而,SPV支付在区块链中的位置定位过程可能无法完成或出现错误,最终影响支付验证的进程和准确性。

有人提出可以通过改进SPV的工作流程来提升攻击防范的有效性,比如不再仅根据哈希值来判断支付的状态,而是使用双因素或者多因素验证,包括账户余额、支付信息追踪等来综合判断支付是否真正成功,但这会增加SPV的复杂度。如何更加有效地解决SPV面临的问题还值得进一步研究。

二、侧链

(一)侧链的起源

侧链(sidechains)实质上不是特指某个区块链,而是指遵守侧链协议的所有区块链,该词是相对于比特币主链来说的。侧链协议是指可以让比特币安全地从比特币主链转移到其他区块链,又可以从其他区块链安全地返回比特币主链的一种协议。

显然,只需符合侧链协议,所有现存的区块链,如以太坊、莱特币、暗网币等竞争区块链都可以成为侧链。元素链(Elements)就是这样一种侧链。所不同的是,它是由BlockStream公司,即提出侧链协议的公司开发的一个侧链的参考实现。

侧链协议具有重大意义。它意味着比特币不仅可以在比特币区块链上流通,还可以在其他区块链上流通,其应用范围和应用前景会更加广泛;有创意的人们会研发出各种各样的应用以侧链协议与比特币主链对接,使得比特币这种基准自由货币的地位更加牢固。

侧链协议的产生有以下几个原因。

1.应对其他区块链的创新威胁

以太坊(Ethereum)区块链、比特股(Bitshares)区块链后来居上,对比特币区块链产生相当大的威胁。智能合约和各种去中心化应用在以上两个区块链上兴起,受到人们的欢迎。而基于比特币的应用则因为开发难度大,项目不多。

2.比特币核心开发组不欢迎附生链

比特币区块链也有合约币(Counterparty)、万事达币(Mastercoin)和彩色币(ColoredCoin)等附生链,但是比特币核心开发组并不欢迎它们,觉得它们降低了比特币区块链的安全性。他们曾经一度把OP_RETURN的数据区减少到40字节,逼迫合约币开发团队改用其他方式在比特币交易中附带数据。

3.BlockStream商业化考虑

2014年7月以太坊众筹时,获得了价值1.4亿元人民币的比特币,还有20%的以太币,开发团队获得了巨大的回报。但是比特币核心开发组并没有因为他们的辛勤工作获得可观回报,因而他们成立了BlockStream,拟实现商业化价值。

基于以上三个原因,提出侧链协议、把比特币转出比特币区块链、另行开发二代区块链,这样的选择既能保证比特币区块链的安全,又能应对二代币的冲击,还能针对不同应用场景实现商业化,因而成了BlockStream的必然选择。

(二)侧链协议

侧链协议的目的是实现双向锚定(Two-way Peg),使比特币可以在主链和侧链中互转(图3-3)。

图3-3 比特币主链与侧链关系图

双向锚定分为以下几个阶段(图3-4)。

1.发送锁定交易,把比特币锁定在主链上

由比特币持有者操作,发送一个特殊交易,把比特币锁定在区块链上。

图3-4 双向锚定示意图

2.等待确认期

确认期的作用是等待锁定交易被更多区块确认,可防止假冒锁定交易和拒绝服务攻击,等待时间是1~2天。

3.在侧链上赎回比特币

确认期结束后,用户在侧链上创建一个交易花掉锁定交易的输出,并且提供一个SPV工作量证明,输出到自己在侧链上的地址中。该交易称为赎回交易,SPV工作量证明是指赎回交易所在区块的工作量证明。

4.等待一个竞争期

竞争期的作用是防止双重支付。在此期间,①赎回交易不会被打包到区块;②新传输到侧链的比特币不能使用;③如果有工作量更大的工作证明出现,即该赎回交易包括了比特币主链更大难度的SPV证明,则上一个赎回交易将被替换。

竞争期结束后,该赎回交易将被打包到区块中,用户可以使用自己的比特币。

从侧链转比特币到主链的过程也是如此。这就是侧链双向锚定协议。

(三)元素链

元素链是BlockStream实现的一个参考侧链,Alpha(阿尔发)版于2015年7月推出。元素链Alpha旨在演示技术并且提供测试环境,目前还未开发完成。作为一个与比特币测试网络相对接的侧链,元素链Alpha有可能被其他技术取代。

元素链Alpha是比特币测试链的一个侧链。它依赖可审计的联合签名者来管理传输到侧链的测试币(参见确定性锚定特性),并且以此来产生签名区块(参见签名区块特性)。这样做能快速探索侧链实施的可能性,考虑如何使用不同的安全措施。在未来版本中,升级协议接口以完全支持去中心化的侧链联合挖矿,最终达到完全双向锚定的目标。

元素链所包括的技术如下。

1.私密交易

元素链中最具创新意义的特性莫过于私密交易。私密交易中的金额仅有该交易的参与者知道(或者参与者指定的人),元素链以密码学算法保证不会多花币。比特币用地址来保证隐私,同时公开交易让别人验证;元素链在保护个人隐私上更进一步,隐藏了交易金额。金额隐藏的具体技术见下文。

私密交易最明显的一点是引入了一种新地址类型,称为私密地址。私密地址含了一个盲化因子,比普通比特币地址更长,这种地址在元素链Alpha版本中是默认地址。

2.隔离见证

Alpha版的交易中,签名从交易中分离出来。此举完全消除了任何已知形式的交易可塑性的威胁,并且允许有效的区块链剪枝。

在比特币中,交易包含转账信息(未花费交易集、地址和金额)和用于证明交易合法性的签名;对于隔离见证来说,交易ID仅由转账信息生成,区块中包含签名。这样做有如下好处:

①比特币有一些“正常化交易ID”的建议,隔离见证包含了这些建议。因为正常化交易ID机制在可塑性的输入后还要重写所依赖的交易,对高层协议如闪电网络来说是必要基础。

②交易ID不覆盖签名,以比BIP62更好的方式,避免了交易可塑性的所有形式,而后可以安全地使用更大尺寸的多语句智能合同。

③具有更有效提供SPV证明(用于轻钱包)的潜力,因为签名可以从交易中被省略而不破坏默克尔树结构。节点无须存贮或验证签名,可以把签名从磁盘中删除或无须在网络上传输它,以大幅度减少区块链存储容量和宽带要求。但在Alpha版本中,证明数据比比特币签名更占空间,因为还包含了大段的输出金额证明(因为使用了私密交易,隐藏了金额,因而要使用密码学证明以防止多花)。

3.相对锁定时间

为序列号赋予了新的意义,使已签名交易被确认后,其输入在一段特定时间内保持无效,目的是支持交易替换功能。

比特币每个交易都有个序列号,初始想法是相比低序列号,最高序列号应该最占优势,矿工应该更喜欢它,但这个想法从未真正实现。在假设矿工利益最大化的前提下,为了使得交易替换机制得以加强,新增一个操作码CHECKSEQUENCEVERIFY,用于比特币脚本检查序列号限制。

相对锁定时间与常规锁定时间用途一致,如时间锁定的担保服务等。但所指的“相对”会使以区块链为媒介的应用更有意思。例如双向锚定阶段可描述为以交易开始的一个相对锁定时间条件,该交易声明了赎回证据。

4.Schnorr签名验证

元素链未使用ECDSA签名方案,而使用了同一曲线上的Schnorr签名方案。其好处如下。

①更有效的n/n阈值签名。多个Schnorr签名可以被合成一个签名,该签名对公钥的总和来说是有效的,所以任意大的n/n多签名只需用一个合签名就可以完成,同时可以被一个CHECKSIG操作所验证。

②更小的签名容量(64字节,而非71~72字节),没有DER编码问题。潜在支持批量验证(同时验证32个签名达到最高2倍加速),这需要知道R.y坐标(ECDSA忽略这个参数)和脚本级别,确保所有签名验证错误导致脚本运行错误(比如所有CHECKSIG操作与CHECKSIGVERIFY类似),以便提供更强的安全证明。

③能证明没有固有的签名可塑性问题。ECDSA有可塑性问题,并且不知道是否存在其他形式的可塑性问题。注意,分离证据使得签名可塑性不会导致交易可塑性。

④比ECDSA的签名和验证速度更快一点。

5.新操作码

元素链Alpha版本新增几个新脚本操作码。

①被禁用的操作码。比特币以前支持许多操作码,一些操作码在2010年因为安全考虑被禁用,需要硬分叉才能重新启用。Alpha版本重新启用了一些被禁用但是安全的操作码,如字符串连接和字串操作码,整数位移码和几个位操作码。

②DETERMINISTICRANDOM操作码:根据种子在一个范围内产生一个随机数。

③CHECKSIGFROMSTACK操作码:验证堆栈中对消息的签名,而不是验证对交易本身的签名。

这些新操作码有一些使用场景,包括双花保护债券、彩票、允许1/N多签名的默克尔树结构(N可为成千上万)、概率支付等。

6.金额隐藏技术

以下工作由亚当·拜克首次在Bitcointalk上的帖子《同态值比特币》中提出。

①佩德森的承诺。CT(密码学承诺)的基础密码学工具是佩德森的承诺。

承诺场景让你把一段数据作为私密保存,但是要承诺它,使你以后不能改变该数据。一个简单的承诺场景用哈希函数构建如下:

如果你仅告诉别人承诺,别人没法确定你承诺了什么数据。但你后来揭露了盲化因子和数据,别人可以运行该哈希函数来验证是否与你之前的承诺相匹配。盲化因子必须存在,否则别人可以试图猜测数据。如果你的数据比较少而简单,猜测成功的可能性比较大。

佩德森承诺与以上场景中的承诺类似,但是附加一个特性:承诺可以相加,多个承诺的总和等于数据总和的承诺(盲化因子的集合即盲化因子总和):

换句话说,加法律和交换律适用于承诺。

我们用椭圆曲线点来构建具体的佩德森承诺(读者无须理解椭圆曲线密码学体系,把它当成黑盒行为来了解就可以了)。通常,ECC公钥由私钥x乘基点G生成。

结果保存为33字节的数组。ECC公钥遵守以前描述过的加法同态性:

(以上特性被BIP32分层确定性钱包用来允许第三方生成新的比特币地址。)

由于佩德森承诺的额外基点(称之H点)生成方法,因而没人知道H对G的离散对数(反之亦然),即没人知道x,且xG=H。我们使用G哈希来选择H:

这里to_point把输入当成椭圆曲线上某个点的x值,并且计算出y值。给定两个基点我们能构建如下承诺场景:

这里x是私密盲化因子,a是我们要承诺的金额,你可以用加法交换律验证加法同态承诺场景中的相关关系。

佩德森承诺是信息理论上的隐私,你看到的所有承诺,总能找到一些盲化因子,可以和任意金额一起匹配该承诺。如果你的盲化因子是真随机,那么拥有无穷计算力的攻击者都不能分辨你承诺的金额。这种承诺无法被假冒,没法计算出任意其他能被验证的承诺。如果你做到,这就意味着你能找到两个基点相对于彼此的离散对数,意味着承诺椭圆曲线公钥体系被破解。

②佩德森承诺应用。

利用该工具,我们替换比特币交易中的8字节金额为32字节佩德森承诺。如果一个交易的发送人认真选择他们的盲化因子,以便正确相加,然后人们还能通过承诺相加为0来验证该交易。

以上公式需要明确的交易费用,在实际交易中,这点没有问题。生成承诺和承诺验证非常简单,不幸的是,如果没有附加的措施这个场景是不安全的。

问题在于该群是循环群。加法要mod P(一个256位的质数,用于定义群的秩),结果大数的加法会“溢出”,从而像个负数金额,因而当有些输出金额为负数时,承诺加起来为0的特点依然存在,导致可凭空创造5个比特币。

以上式子可以被解释成“有人花了2个比特币,得到-5个比特币和7个比特币”。为了防止产生这种情况,交易中有多输出的时候,我们必须证明每个承诺输出金额都在允许范围(如[0,2~64])内且没有溢出。

我们可以公开金额和盲化因子,以便其他人能检查,但是这样一来就损失了所有隐私。因而,我们要证明承诺的金额在允许范围内,除此之外不透露任何信息。我们可以使用类似于Schoenmakers二元分解的技术来解决此问题,但是在此基础上进行了许多优化(包括不使用二元)。

我们从基本的EC签名开始,如果生成了一个签名,签名的消息是公钥的哈希,该签名证明签名者知道私钥,即公钥对于某些基点的离散对数。

对于一个类似公钥的P=xG+aH,因为基点H的存在,没有人知道P对于基点G的离散对数,因为没人知道x使得xG=H,除非a为0。如果a为0,则P=xG,离散对数恰好是x,有人会为该公钥签名。

把承诺当成公钥,对承诺的哈希值签名,通过这种方法,某个佩德森承诺可以被证明是对0值的承诺。在签名中使用公钥用于防止把签名设置成任意值并且破解出承诺。签名使用的私钥正是盲化因子。

更进一步,假定我想证明C是对金额1的承诺,但不告诉你盲化因子,你能做的就是计算:

然后向我要公钥C′的签名(相对于基点G的签名),如果我能做到,则C一定是对金额1的承诺(否则我就破解了EC离散对数的安全性)。

③环签名。

为了避免给出金额,我们还需要另一个密码学技术:环签名。环签名是当存在两个(或多个)公钥的签名场景时,签名证明签名者知道至少一个公钥的离散对数。使用环签名,我们可以构建另一个场景。我证明一个承诺是对金额0或金额1的承诺,我们叫这种场景为“或证明”。

首先,我给你C,你计算C′: C′ = C - 1H

然后我提供{C,C′}上的环签名。

如果C是对金额1的承诺,则我不知道它的离散对数,但是C′成为金额0的承诺,我知道它的离散对数(就是盲化因子)。如果C是对金额0的承诺,我知道它的离散对数;C′是对金额1的承诺时,我不知道离散对数。如果这是一个对任意其他金额的承诺,没有一个结果为金额0,因而我没法签名。

以上机制对任何数字对有效,只需把金额进行合适的预处理再放到环中,或者超过2个数字。

假定我想证明C在范围[0,32)之中,现在我们有一个或证明,想象我发送给你一个承诺集合,每个承诺都有个或证明:

C1 is 0 or 1C2 is 0 or 2C3 is 0 or 4C4 is 0 or 8C5 is 0 or 16

我为C1—C5选择了正确的盲化因子,能使得C1 + C2 + C3 + C4 + C5=C。我建立了一些有效的二进制数,和一个只能在区间[ 0,32)内的5位数。

众多优化手段可以让证明过程更有效。

首先,我们提出一个新的、更有效的环签名方法——Borromean环签名,它仅要求每个公钥32字节,再加上能被其他不同环所共享的32字节。与以前提出的构建方式相比,该环签名能达到两倍效率。

CT金额并非直接表述金额,而是使用十进制浮点数来表示,每个数字要与以10为基数的指数相乘,这意味着如果在基数10之前有较少重要数字,你能用小容量证据来证明大金额。比如:11.2345和0.0112345可以有相同大小的证明,即使两个数相差一千倍。

还有一个非隐私的发送“最小金额”。如果用户愿意泄露一些最小金额信息(最小金额信息将对外公开),那么就允许更小的证据覆盖更大范围的金额,并且当使用指数时还允许最小重要数字非零。用交易中第一个金额减少最小的金额,然后证明该值非负。

其次,浮点尾数用四进制编码而不用二进制,因为可以减少要发送的承诺的数值,使得签名数据大小与二进制相当。对最后的尾数数字的承诺可以跳过,从前向后对已经证明的金额创建承诺,其他数字也一样。

最后,通过在证明中小心使用非随机化签名,对于币的接收者(由于带接收者公钥的ECDH密钥协议,他与发送者共享一个私钥)来说,“重绕”证据并且用它提取发送者发送的消息是可能的。该消息大小为证据大小的80%。我们使用该原理向接收者提供金额和盲化因子,但是也可以用来存储编号或撤款地址等信息。

三、闪电网络

闪电网络(The Lightning Network)是一个去中心化的系统。闪电网络的卓越之处在于,无须信任对方以及第三方即可实现实时的、海量的交易。

(一)闪电网络的起源

近年来,随着比特币的蓬勃发展,比特币交易数量越来越多,而单个区块体积有1MB的最大值限制,因此区块空余空间显得越来越小。如图3-5所示,区块体积中位数在2015年里得到了翻番,从1月的292KB(千字节)快速增长至12月的749KB。

图3-5 比特币区块体积大小

数据来源:区块元blockmeta.com

扩容问题在2015年得到了充分的重视与讨论,在2015年6月左右陆续推出了诸多扩容方案,代表有BIP100、BIP101、BIP102、BIP103、BIP109、BIP248等若干方案(见表3-2)。

表3-2 区块扩容方案表

虽然提出各种方案,但基本可以划分为两类:长期规则派与短期搁置派。长期派偏理想、规则型,一口气敲定便不再折腾,典型代表是BIP101/103,设定一个增长规则,便不再调整。短期派则认为未来不可预测,固定的规则过于简单暴力,希望设置一个短期数年方案暂时先避开,搁置至未来解决,代表为BIP100,但由于投票过程复杂,后简化为BIP102/109等,而BIP248则一口推迟至2020年,近几年就简单采取翻番增长。

自2015年6月至今,经过了大半年来大范围的反复讨论,目前长期规则派基本完败。2015年12月比特币香港扩容会议由Pieter Wuille提出了隔离见证(Segregated Witness)之后,扩容问题甚至已经简化为仅升级至2MB,但陷入了关于实施时间点的争论之中。

一个看似简单的扩容技术问题,却引发比特币社区花了大半年时间,开了数次全球技术会议、私下打了无数回口水仗,却依然未有明确定论。其背后深刻的原因是,区块限制值上调是无法真正解决比特币扩容问题的。

(二)扩容问题

总的来说,根据对比特币网络的理解,有两个划分:清算系统和现金系统。

1.清算系统

比特币区块链是全球的、分布式的、有限容量的且代价昂贵的系统。每一笔交易的价值含量是不一样的,当块容量不够用时,我们应该保障高价值的交易进块。高价值的交易有意愿、有能力支付足够高的网络手续费,从而获得足够高的优先级进块。

随着比特币的繁荣,交易数量会越来越大,有限的块容量会使低价值的交易(例如发送1分钱)永远无法进块,因为低价值的交易不可能支付高网络手续费。进而,网络退化为清算系统,低价值含量交易被赶出,这些交易由第三方记账系统进行代替完成。

在闪电网络出现之前,第三方记账系统主要是链外钱包提供商。用户信任某第三方钱包平台,把比特币存入其中,同一平台用户之间转账仅带来账户余额变更,并不会产生比特币交易。

2.现金系统

现金系统意味着所有交易均应该进入区块,那么当块容量不够用时,则应该及时调整块体积限制,对系统进行扩容。短时间可能发生交易入块堵塞,但长期来看所有交易应该均可以入块,人人都享有比特币系统带来的巨大便利和优势。

3.扩容大小的选择

我们进行一个简单的估算,假设每个交易大小为512字节,手续费单位为0.0004/KB(见表3-3)。

表3-3 区块未扩容方案表

根据VISA在2015年的记录,全年共产生92064百万笔支付交易,折合比特币网络数据(见表3-4)。

表3-4 区块扩容方案表

若提高区块体积限制至30MB,最大的问题不是CPU计算能力瓶颈,而是块的传播与存储。

30MB的块可能会导致全网孤块率和空块率大幅上升,一年产出1.5TB的区块链数据也超出大部分节点机器的硬盘容量。基于这1.5TB的数据,区块链浏览器、钱包服务商等则可能膨胀10倍达到15TB。这对于目前来说,已经远超普通机器/数据库的磁盘容量。

诚然,这些数据对于中性化的系统而言,并不具有多么大的挑战性,但对于一个全球分布式系统而言,则非常具有挑战性,会极大削弱节点数量,提高开发接入门槛,使比特币变得中心化。

扩容争论的最后,还是倾向于2MB,使升级过程更加可控一些,风险更低一些。

(三)微支付通道

闪电网络在一片扩容的吵闹声中于2015年7月发出了首篇论文。在介绍闪电之前,我们先介绍一下微支付通道(Micro-Payments Channel)。

微支付通道概念于2012年首次被提出,是解决小额度、高频次支付场景的方案,目的在于缩减支付的交易数量,使高频、小额支付成为可能。下面我们先研究一下微支付通道的原理。

假设爱丽丝为消费者,鲍伯为一家视频网站。爱丽丝非常喜欢去鲍伯网站看电影,看一部电影需要支付0.1BTC(比特币),那么爱丽丝看了10部电影就需要支付10次0.1BTC,共计1BTC并发出10笔交易。而采用微支付通道就会缩减至两笔,或者说任何多次的交易均会缩减至两笔,只要总金额不超过存入通道的额度即可。

通道(Channel)的建立以及更新过程如下。

①爱丽丝支付1BTC至一个多重签名地址,签名采用2/2方式,我们把该交易称为FTX(Fund Tx)。爱丽丝生成该交易后,并不广播。

图3-6 微支付交易结构

②爱丽丝再构造一个赎回交易,称之为RTX(Refund Tx)。其输入为交易FTX的输出,输出为爱丽丝自己。同时,该交易有Locktime锁定期,所以N天之后才会生效,才可以进块。

③爱丽丝把构造好的空RTX给鲍伯,并让鲍伯进行签名。

④爱丽丝拿到带有鲍伯签名的交易RTX后,广播出FTX。此时的交易结构如图3-6所示,图中带有尖括号的签名表示待填入。

⑤爱丽丝再看了一部电影,那么她需要再支付0.1BTC给鲍伯。于是,爱丽丝构造另一笔交易PTX2:输入依然是交易FTX;输出为两个地址,其中爱丽丝为0.8BTC,鲍伯为0.2BTC。爱丽丝对该交易签名,并将交易和她的签名给鲍伯(图3-7)。

⑥鲍伯可以随时签名并广播交易PTX2,当然,他依然可以广播交易PTX1。作为一名理性经济人,鲍伯必然总是广播自己收益最大的那笔交易,也就是当前的PTX2。在目前总是爱丽丝付款的情况下,鲍伯总是乐于广播最后一个交易。

⑦当鲍伯广播出最后一笔交易PTXn时,则意味着通道关闭,合作结束。鲍伯需要在交易RTX锁定期结束前关闭通道,否则意味着爱丽丝可以在交易RTX解锁后拿回她所有的币。

上述,就是微支付通道建立、更新与关闭过程。在一个完整的过程中,有且仅有两笔交易广播至链上,

同时双方均无须信任对方,任何一方也无法侵害另一方的利益。在更新过程中双方只是交换交易和签名数据,并无交易广播至链上,那么意味着在存入额度范围内,

图3-7 微支付交易广播收益最大化的那笔交易

可以创造出无数笔交易。不仅通道内的更新次数不受限制,频率也可以达到非常高,只要系统允许,目前硬件条件可以轻松达到每秒数千笔。

在特定场景下,微支付通道拥有着巨大优势,让小额高频支付成为可能。但它存在一个巨大制约:币在通道中的流向是单向的。在上述例子中,币仅能从爱丽丝流至鲍伯。

(四)闪电网络交易合约

微支付通道解决了合并交易的问题,但并没有解决撤销上个交易的问题,利用“理性经济人”和单向流动来达到撤销上个交易目的,并不是真正的撤销。若交易可以撤销,则币可双向流动。

闪电网络是基于微支付通道演进而来,创造性地设计出了两种类型的交易合约:序列到期可撤销合约RSMC(Revocable Sequence Maturity Contract),哈希时间锁定合约HTLC(Hashed Timelock Contract)。

RSMC解决了通道中币单向流动问题,HTLC解决了币跨节点传递的问题。这两个类型的交易组合构成了闪电网络。

1.RSMC创建

我们先来创建一个序列到期可撤销合约(RSMC)。爱丽丝和鲍伯是合作方,经常有比特币往来,所以他们决定各拿出0.5BTC放入通道中,便于业务往来。

RSMC交易结构(图3-8)的下方,左侧为爱丽丝的视角,右侧为鲍伯的视角。中间Funding Tx为共同可见;C1a和RD1a为爱丽丝持有;C1b和RD1b为鲍伯持有。交易图中带有尖括号的签名表示待填入。

图3-8 RSMC交易的结构图

①双方各拿出0.5BTC,构建Funding Tx,输出为爱丽丝和鲍伯的2/2多重签名。此时,Funding Tx未签名,更不广播。

②爱丽丝构造Commitment Tx:C1a和RD1a,并交给鲍伯签名。C1a的第一个输出为多重签名地址,爱丽丝的另一把私钥爱丽丝2和鲍伯的2/2多重签名,第二个输出为鲍伯0.5BTC。

③RD1a为C1a第一个输出的花费交易,输出给爱丽丝0.5BTC,但此类型交易带有sequence,作用是阻止当前交易进块,只有前向交易有1000个sequence确认时才能进块。

④鲍伯构造Commitment Tx:C1b和RD1b,并交给爱丽丝签名。结构与C1a、RD1a是对称关系。

⑤鲍伯对C1a和RD1a进行签名,并将签名给爱丽丝;同理,爱丽丝对C1b和RD1b签名,完成后给鲍伯。此时,由于并未对Funding Tx进行签名,任何一方均无法作恶,任何一方也不会有任何损失。

⑥双方均完成对Commitment Tx的签名并交换后,各自再对Funding Tx进行签名,并交换。此时,Funding Tx是完整的交易,广播之。

上述过程以及结构图的描述,就是创建RSMC的全部过程。

C1a和C1b两笔交易花费的是同一个输出,故他们两个交易只有一个能进块。若爱丽丝广播C1a,则鲍伯立即拿到0.5BTC(C1a的第二个输出),而爱丽丝需要等C1a得到1000个确认,才能通过RD1a的输出拿到0.5BTC。另一方,若鲍伯广播C1b,则爱丽丝立即拿到0.5BTC,鲍伯等待C1b得到1000个确认,才能通过RD1b拿到0.5BTC。也就是说,单方广播交易终止合约的那一方会延迟拿到币,而另一放则立即拿币。

2.交易更新

爱丽丝和鲍伯各自有0.5BTC的余额,此时爱丽丝从鲍伯处购买了一件商品,价格为0.1BTC,那么余额应该变为爱丽丝0.4BTC,鲍伯0.6BTC。于是创建新的Commitment Tx,对于爱丽丝来说是C2a和RD2a,对于鲍伯来说是C2b和RD2b,过程与上面类似(图3-9)。

图3-9 交易更新时的交易结构

此时两个状态均是有效的,那么最核心的问题来了:如何才能彻底废弃C1a和C1b呢?

RSMC采用了一个非常巧妙的方法:在C1a的第一个输出中,采用了爱丽丝2和鲍伯的多重签名,爱丽丝将爱丽丝2的私钥交给鲍伯,即表示爱丽丝放弃C1a,承认C2a(图3-10)。

图3-10 交易更新时的多重签名

爱丽丝交出爱丽丝2的私钥给鲍伯,那么鲍伯就可以修改RD1a的输出给他自己,形成新的交易BR1a。若爱丽丝破坏合约,在存在C2a的情况下依然广播出C1a,那么爱丽丝受到的惩罚就是失去她全部的币。爱丽丝交出爱丽丝2的私钥,或者对交易BR1a进行签名,两者是等同的,都是对C1a的放弃。

反之亦然,鲍伯交出鲍伯2的私钥给爱丽丝即意味放弃C1b,而仅能认可C2b。

引入sequence的目的是,阻止后续交易进块(RD1a),给出一个实施惩罚窗口期,当发现对方破坏合约时,可以有1000个块确认的时间去实施惩罚交易,即广播BR1a代替RD1a。若错过1000个块时间窗口,则无法再实施惩罚了(RD1a进块了)。

3.交易关闭

关闭RSMC,直接按照最终的余额构造出一个Commitment TX即可。例如,输出为爱丽丝0.1BTC,鲍伯0.9BTC,无需再设置多重签名,构造惩罚交易等。

4.中转交易

爱丽丝想要支付0.5BTC给鲍伯,但她并没有一个渠道来和他进行交易。幸运的是,她和查理有一个交易渠道,而查理正好和鲍伯有一个交易渠道。这样爱丽丝就能借助查理的交易渠道,通过哈希时间锁定合约(HTLC)来和鲍伯进行交易了(图3-11)。

图3-11 中转交易示意图

为了完成这次交易,爱丽丝就会给鲍伯发短信说:“嘿!我要给你付笔款。”这时鲍伯将收到一个随机数字(R),接着鲍伯便会回一个被哈希的数字(H)(你可以认为被哈希的数字H是随机数字R的一种加密形式)给爱丽丝。然后爱丽丝的钱包紧接着就会联系查理说:“嘿,查理。如果你给我生成(H)的未加密值(R),那么我就同意更新我们渠道的支付分配,这样你得到的就会比0.5BTC多一点,我得的比0.5BTC少一点。”尽管查理并不知道R,但他也会同意。之后查理便会去找鲍伯说:“嘿,鲍伯。如果你给我那个能生成H的未加密的值R,我将同意更新我们渠道的支付分配,这样你得到的会比0.5BTC多一点,我得到的比0.5BTC少一点。”

因为R就是从鲍伯这里生成的,所以他肯定知道。接着他马上将R告诉查理,并更新了其渠道的支付分配。然后查理将R告诉给了爱丽丝之后也更新他们的渠道,最后交易完成,爱丽丝以脱链的形式付给鲍伯0.5BTC。

5.总结

RSMC通过巧妙地设置Commitment TX的多重签名输出,以及sequence的延迟进块形成惩罚窗口期,解决了在微支付通道中的币单向流动问题。

(五)闪电网络面临的问题

闪电网络的最初设想为一个中心辐射型网络(图3-12)。你的钱包将会连接到一个“支付中转站”,由于各种支付渠道彼此之间都保持畅通,爱丽丝有一个和中转站A相通的渠道,而鲍伯也有一个和中转站B相通的渠道,爱丽丝只需通过一两个中转站的跳跃就能直接和鲍伯交易了。

图3-12 中心辐射型网络

如果能有成百上千个中转站(小额支付中心),那么这个网络拓扑结构就能完美运行。但是,若是只有少数几个大型中转站,那么这个网络的去中心化就会受到损害,变成另一个VISA卡、万事达卡或者美国运通。

1.中转站的中心化风险

要精确地预测出存在于网络均衡中的中转站的数量是完全不可能的,但是由于众所周知的马太效应,这个数字会逐渐变小,而不是变大。然而不可否认的是,在开源项目中,任何人都可以在上面运行一个支付中转站(至少在政府部门决定监管之前),只是支付中转站运行的高成本就像是给进入者们设置了一道坚固的壁垒,从而产生了中心化压力。

为什么建立支付中转站需要高成本?让我们回到查理扮演“交易中转站”的那个例子。回想一下,爱丽丝需要通过查理把比特币付给鲍伯,所以查理不得不在更新他和爱丽丝的分配渠道之前就更新他与鲍伯的分配渠道(付给鲍伯的多,自己得到的要少)。也就是说,查理在得到鲍伯的0.5BTC之前,就得先付钱给爱丽丝。

这意味着如果查理想要成为一个支付中转站,那他自己必须在与“客户”共有的渠道里存足够多的比特币,这样才能促成这些“客户”的脱链交易。如果查理没有预存至少0.5BTC到鲍伯的渠道里,那么这笔交易就不能做成。

现在,虽然查理仍保留这些比特币百分之百的控制权,但是这笔钱至少还是需要放在那些渠道里,以便促成那些链外支付,因而资金的沉淀成本非常高昂。所以,要运行一个支付中转站还是需要真金实银的投入,最起码在刚开始之前就需要准备足够的预存款。

那么,一个支付中转站应该给每个渠道存入多少预存款呢?如果一个比特币是500美元的话,那么你想要运行一个服务100人的支付中转站,需要50000美元的资产来启动它。

因此,如果某天闪电网络最终演变为中转站辐射型拓扑网络,那么中心化就是它最大的隐患。

2.点对点的路径交易

闪电网络是否有比中转站辐射型更好的模式?目前已经有很多规避支付中转站的设想,开发者尝试创造出更多去中心化、有组织的钱包对钱包的路径。

试想一下,如果爱丽丝想要买一杯咖啡,在此之前,她的钱包会用相同的技术在网络中通过其他节点找到一个路径来支付这杯咖啡。如果钱包找不到任何一个节点,那么它将与咖啡店打开一个新的支付渠道来完成这笔交易,然后留着这个渠道以便日后再用。理论上爱丽丝的钱包能够维持数十个开放的渠道。

如果有人每次在尝试支付时都不能找到一个渠道,那么新的渠道将会被打开,长此以往,用户间的一些有组织的渠道路径就会形成(图3-13)。

图3-13 点对点的路径交易示意图

从图3-13我们可以看到,爱丽丝在离开咖啡店后仍保持其支付渠道的开放。鲍伯最近去了咖啡店后也保持其支付渠道的开放,而且他还从商店里买了一条新领带,这个支付渠道也是处于开放状态。

在这个例子中,爱丽丝不仅可以将比特币以链外的形式给鲍伯,还可以通过已形成的有组织的路径将比特币付给商店老板。这可以解决闪电网络中心化的问题。但在具体应用中,很难找到从爱丽丝到商店并通过咖啡店和鲍伯的支付路径。

图3-14 点对点交易的支付路径

爱丽丝和鲍伯都要花0.011BTC来买一杯咖啡(约5美元),这就是为什么咖啡店在爱丽丝和鲍伯的渠道中都有0.011BTC(图3-14)。对爱丽丝来说,不管她是想把钱给鲍伯还是商店老板,咖啡店老板都需要更新他和鲍伯的支付分配渠道。咖啡店老板自己得到的少(从爱丽丝想要付的钱中),鲍伯从中得到的多。但是注意一下,咖啡店老板在和鲍伯的渠道中只有0.011BTC(约5美元),也就是说爱丽丝最多只能付给鲍伯或是商店老板5美元。如果她想要付更多的钱,那她就需要重新开一个渠道。

当人们以不同金额买不同的东西时,这种类型的数值不对称性就很有可能会频繁发生。从一个节点到另一个节点的路径很容易被找到,但是每一次找到正确数值的跳跃路径则是最困难的部分。

3.路径交易造成更多的链上交易

设想一下,要是爱丽丝的钱包不能从商店那里找到一条她想要数额的路径时,她是怎样开启一条新的渠道的。据估算,在给定的时间内你钱包中的比特币有绝大部分会留在渠道中。那么爱丽丝的钱包哪里还有比特币来和商店开一个新的渠道呢?好,如果它不得不关闭现存的渠道之一,那么当你的钱包在交易时不能找到一条路径的过程将是这样:①关闭现有的一条渠道完成链上交易。②和收款人开启一条新的渠道完成链上交易。

这两笔链上交易中还只有一笔付款,要是有一笔大交易无法找到一条路径(因此不得不关闭一个旧的渠道来打开一条新的渠道),很多的预存款都将被浪费掉。如果有超过50%的交易找不到路径,闪电网络实际上会促成更多的链上交易,而不是即时的链外交易。

4.路径交易时,发送者和接收者需要同时在线

人们即便是使用桌面上的钱包,也不会让它24小时都开启。他们在不用钱包的时候就会关闭程序,盖上笔记本电脑的盖子,关掉电脑等。除此之外,很多人的手机钱包都是休眠状态,不会时刻保持上线状态。因此,99%的预期用户都不会参与路径付款。

在哈希时间锁定合约(HTLC)的例子中,爱丽丝的钱包联系鲍伯的钱包,并问他要一个哈希化的随机数字(R)。鲍伯需要在线才能将那个数字给她。而在比特币目前的使用中,发送者和接收者是不需要同时在线的。

参考资料

[1]http://8btc.com/article-2002-1.html

[2]http://www.bitabc.com/?id=169

[3]http://www.8btc.com/merkling-in-ethereum

[4]http://8btc.com/thread-23806-1-8.html

[5]http://8btc.com/article-1790-1.html

[6] http://www.8btc.com/confidential

[7] http://www.8btc.com/elements

[8] https://www.elementsproject.org/elements/deterministic-pegs/

[9] https://www.elementsproject.org/sidechains.pdf

[10] https://github.com/ElementsProject

[11]https://github.com/Blockstream/borromean_paper/raw/master/borromean_draft_0.01_34241bb.pdf

[12] https://people.xiph.org/~greg/confidential_values.txt

[13] https://bitcointalk.org/index.php?topic=305791.0

[14] https://www.elementsproject.org/elements/relative-lock-time/

[18] 本章《简单支付验证》部分由海滨完成,《侧链》部分由申屠青春完成,《闪电网络》部分由潘志彪完成。

申屠青春,深圳银链科技CEO,深圳大学ATR国防科技重点实验室博士。

潘志彪,现任比特大陆软件研发总监,BTC.COM团队负责人。前币付宝CTO、联合创始人。中国比特币行业知名技术专家,曾就职于百度,当当等互联网公司,对于大数据处理、推荐系统、模式识别等有较为深入的研究。

[19] 交易可锻性(transaction malleability)攻击,又称交易延展性攻击。攻击者侦听比特币P2P网络中的交易,利用交易签名算法的特征修改原交易中的input签名,生成拥有一样input和output的新交易,然后广播到网络中形成双重支付。这样,原来的交易将有一定的概率不能被确认,造成不可预料的后果。