二、侧链
(一)侧链的起源
侧链(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%。我们使用该原理向接收者提供金额和盲化因子,但是也可以用来存储编号或撤款地址等信息。