比特币作为第一个区块链应用与运行到目前为止最被信任的公链,其扩展性问题却持续被作为焦点贯穿着整个链的发展周期。事实上,在 2009 年 1 月 4 日比特币出现的那一天到 2010 年 10 月 1 日之间,并没有明确的区块上限,根据比特币区块链区块的数据结构最高可达到 32M 的容量。而在 2010 年 10 月 1 日的一个 commit 当中,中本聪第一次在代码中明确限定了 1M 的区块上限,就在 10 月 3 日,Jeff Garzik 发布了将区块上限扩展到 7M 的补丁,成为了第一个硬分叉的尝试。当然,这个补丁并没有用户使用,而彼时的平均区块数据量仅在几十 k 左右,中本聪也在当时说明为了保证比特币系统的安全和稳定,建议不要采用 Jeff Garzik 所发布的补丁。
随着比特币网络规模的持续扩张,链上交易变得更为活跃,区块内的数据量也逐渐增多,于是每秒 7 笔的交易处理速度成为瓶颈的趋势也越发明显。
http://ww1.sinaimg.cn/large/0073VfK9ly1g1wcc4od9aj30ym07udi6.jpg
图表 1 比特币区块链历史大小( BitinfoCharts.com )
从 2015 年开始 Jeff Garzik 就曾再次通过 BIP100 提出移除 1MB 上限,回归最早的 32MB,而此时比特币算力早已突破了 1P 的规模边界,利益相关方中比起一般的支付用户,更多的是矿工。然而对于矿工来说,打包更多的交易意味着消耗更多的资源,也因此,一直以来比特币区块链区块的扩容从未真正达成共识,随之而来的是 BCH、BSV 等的分叉。而无限放大区块容量上限来解决交易处理速度的问题,显然只是权宜之计。
类似的问题,在以太坊上依然存在。虽然其区块大小并未像比特币那样以一个常数作为限制,但 gaslimit 作为上限的设置与矿工利益的平衡也同样对以太坊的交易处理速度形成了限制,使其秒处理速度在 15 笔左右。也因此在 ICO 盛行的 2017 年以及类似以太猫这样的游戏爆火的时候,整个以太坊网络都会陷入交易堆积成山的瘫痪状态。
在主链扩展难以破局的过程中,一方面出现了将主链区块链数据验证和计算的责任仅交由一小组高性能节点来完成的解决方式,比特股、EoS 等的 DPoS 机制即通过这种方式啦实现。这类解决方案通过模拟现实中的议会制选举高性能节点,而难免引起了利益集团与中心化趋势的疑议。除此之外,也有通过链下交易来解决这类问题的尝试,其中比特币的闪电网络和以太坊的雷电网络是较为典型的两个实例。
由于比特币 UTXO 的区块链模型和以太坊基于账户余额模型的区别,在链下交易通道的具体协议设计上就有了闪电网络和雷电网络的差异。然而两者之间有着共通的基本逻辑,即通过在主链外开辟针对特定交易对象的交易通道。也就是说,特定交易对象之间通过共同锁定一笔保证金,来用于特定时间区间内的交易结算,只要双方或多方交易结果没有超出保证金的额度,或者没有超时,或者没有任何一方选择中止交易通道,双方或多方的交易就不需要向全网广播获得确认,也不需要向区块链主网支付任何手续费。这使得高频小额的交易不再依赖于区块的大小或者区块的出块速度。
当然,为了实现尽可能多的匹配高频交易的各种需求,闪电网络中会出现多个中转节点,用于匹配交易需求的各方。也是由于闪电网络中的交易过程要求收款环节通过签名回收,因此交易方需要实时在线,也而从这个逻辑来看,似乎中心化的交易所最适合担任中转节点的角色。而这也让社区担忧,是否最终会让高频小额交易变得日益中心化并在安全性上做出妥协。
当然,不管如何,闪电网络与雷电网络的设计已经将扩展性问题的解决引导向了主链之外的第二层,将不同需求的网络和主链网络分层,成为了解决扩展性问题的一大趋势。
分片源于数据库设计中的概念,通过分类备份和冗余来增加整体数据库的处理效率和容错性。分布式数据库中通过建立不同的分片机制满足业务系统的不同要求。区块链中针对性能扩展所提出的第二层( Layer 2 )解决方案也借用了这一概念,通过将不同业务对区块链的不同需求进行分类,并各自分布在不同的子链当中,从而解决全链共识的性能瓶颈。
然而,区块链与分布式数据库中较大的区别在于,分布式数据库的增删改查以及计算来自于业务系统或者中心化的数据管理系统,分布式数据库各节点仅负责响应数据管理员( DBA );而区块链的业务逻辑也来自于各节点即包含也业务逻辑、计算、也包含了至少账本层面数据的管理,也就是每个节点都可以是 DBA,或者理解为根本没有 DBA,因此在设计上则更为复杂。
由于分布式数据库的交易逻辑为中心化控制,因此其分片可以被看作是单纯的存储分片。区块链的分片则主要分为相对简单的交易分片:即仍然保持全网络节点在数据上的全同步,仅通过分片来让不同节点运行不同的运算逻辑;和更为困难的状态分片:即同时包含了对交易与存储的分区。狭义上来理解,最直观的状态分片其实就是各种分叉,不同分叉链上各自处理的自己的交易、存储自己的账本数据,验证历史区块有效性的时候可以选择一直回溯到分叉发生前的区块,通过快照来确认历史交易。但这种类型的分片由于没有后续跨片交互的机制设计,因此并没有提升太多实际价值。
那么状态分片的跨片交易需要解决的就是如何去相互验证不同分片内交易的有效性了。分片内部交易的有效性由分片内的节点通过共识机制确保,也因此在 SimpleChain 的设计当中,不同的分片内也同样拥有着区块链的运行机制,因此跨片交易问题在 SimpleChain 当中就被理解为跨链交易的问题,而分片则被定义为子链。
由于跨子链交易来自于两个账本数据不一致的区块链用户之间,因此通过构造一个不作为状态存储在账本中的“对象”,可以实现类似于 SPV (简单支付验证)的机制,即通过互相之间所同步的区块头来完成梅克尔证明,来验证这个构造出来的“对象”所传递信息的有效性。我们可以把这个对象称为收据。
http://ww1.sinaimg.cn/large/0073VfK9ly1g1wcc4fn7aj318p0pm75a.jpg
图表 2 基于收据的跨链交易确认( Ethereum wiki )
在上述图表中,表示的是一个从区块链 X 中的用户 A 向在区块链 Y 中的用户 C 发送 100 个单位的资产的过程。
( 1 ) 这个过程首先通过生成一笔交易以及一个编号为 154016 的收据,并在区块链 X 的账本中扣除 A 的 100 个单位资产来发起。
( 2 ) 这个收据发送到区块链 Y 之后,通过梅克尔证明可以验证到收据所包含的信息是否正确,也就是第一笔交易是否已经在 X 区块链被确认,A 是否已经被扣除了 100 个单位的资产。
( 3 ) 获得确认后,用户 C 从区块链 Y 发送一笔包含了对收据 154016 的梅克尔证明的交易给到区块链 X,可以把这笔交易看作回执,并增加 C 账本中的 100 个单位资产。
( 4 ) 区块链 X 收到这个回执,并将之前的收据进行销毁,同时区块链 Y 也在后续的区块中将收据 154016 进行销毁,跨链交易完成。当然区块链 X 与 Y 也可以保留回执,用于验证后续跨链交易的持续性。
为了确保上面这个机制的持续有效,我们还需要考虑跨链交易中的终局性问题,或者叫做分叉选择机制。区块链 Y 所验证的区块链 X 交易必须来自于区块链 X 有效链的块中的交易,而不是来源于一个孤块或者孤链。Vlad Zamfir 提出过一个合并块的设计,也就是两条链在需要发起跨链交易时,两个在不同链上的块合并为同一个区块,各自的链都基于这个合并块去延长之后的块数据。但实际上合并块意味着两条链的账本同步,因此我们认为并不能解决两个分片或者两个链之间的相互独立性问题。但是跨链交易中,如何寻找正确的对方链的块去完成收据的梅克尔证明,是可以从 Vlad 的思路中找到答案的。
Vlad 将两条需要实现跨链的链进行等级排序,分为“父链”和“子链”,“子链”需要在与“父链”高度相同,或高于“父链”高度所产生的区块与“父链”进行区块合并,或者在我们的场景中是在“父链”上进行区块跨链验证。这样能够确保两个链在各自延长的过程中,跨链部分数据能够持续保持一致。
http://ww1.sinaimg.cn/large/0073VfK9ly1g1wcc4snp3j30ju0fdjui.jpg
图表 3 合并块机制( Vlad Zamfir )
但是,在上述的解决方案中存在需要两个区块链同步出块的前提,因为如果“父链” X 的交易迟迟不能确认,或者没有延长,或者“子链” Y 没有及时收到 X 的延长情况,亦或者“子链”与“父链”存在间断性同步,则“子链” Y 的后续交易有效性也都会受到相应的影响。
http://ww1.sinaimg.cn/large/0073VfK9ly1g1wcc43tg0j309q04daa3.jpg
图表 4 非同步跨链(跨片)交易在分叉时的情况( Alexander Skidanov )
从上图中可以看出,两个分片或者链各自存在分叉的情况下,如果分片 1 中的 A-B 以及分片 2 中的 V ’-X ’-Y ’-Z ’各自被确认为主链,则跨链或跨片交易没有问题,亦或 A ’-B ’-C ’-D ’和 V-X 成为了主链,则跨片交易就失效。但假设是另外两种情况,则存在了原子性故障,也就是在一个分片中交易有效而在另一个分片中交易无效。由于两个分片或者链的异步性,导致在发起跨链交易时并不能确定两个链内部各自的主链确定情况,因此这种问题就会产生。于是分片或者子链之间的跨链交易就需要一个中间共识机制来进行协调。
在以太坊 2.0 的设计中,信标链被赋予了这个职能。信标链可以被认为是以太坊 2.0 设计中所有分片链的主链,这条主链通过 Casper 共识机制来选举并在每一轮中随机产生分片验证者,用于协调分片之间的交易正确性。但是在属于 PoS 的 Casper 共识机制中,由于没有了难度要求、nonce、块哈希这些原本在 PoW 中能够执行无状态 SPV 证明的工具,因此要验证分片链的有效性需要回溯到可信区块,再重新计算可信区块后的区块状态一致到当前区块,才能完成验证。导致了验证者增加了工作量。因此在 SimpleChain 当中,为了减少验证者的工作量,类似信标链的角色则通过 PoW 的主链来完成。
主链当中存在锚定矿工的角色,所谓锚定矿工承担三个功能角色,1. 负责在某子链发起跨链交易时验证该子链状态的有效性; 2. 负责在主链中写入子链交易并广播获得确认; 3. 将意在主链确认的跨链交易结果分别写入交易发起子链与交易接收子链的区块中。
锚定矿工在验证、广播、和传递跨链交易时,既作为子链矿工也作为主链矿工存在。然而在主链上的矿工数量会比子链中的矿工数量多,因此在子链中伪造交易传递到主链的成本将大大低于在主链伪造交易写入子链。因此需要一种更为合理的锚定矿工选举机制。
http://ww1.sinaimg.cn/large/0073VfK9ly1g1wcc4ax7oj309y05laah.jpg 图表 5 子链中作恶矿工的概率将会高于主链( Alexander Skidanov )
锚定矿工不针对于某个子链长期存在,但需要长时间作为主链矿工存在。由于 PoW 的主链能够允许无状态 SPV 证明,因此我们在 SimpleChain 中将锚定矿工的选举通过随机的形式来完成。
一次跨链交易验证的锚定矿工数量上限=Min[(全网矿工数 /子链数量)*3,全网矿工数]
由于锚定矿工来自于 PoW 主链矿工,因此通过从小到大排列主链矿工所计算出的工作量证明计算结果,进行锚定矿工筛选。由于数值越小的工作量证明计算结果获得的概率越低,因此在锚定矿工预选列表中的排名越高,超出该次锚定矿工数量上限排名的矿工则在当前轮的交易验证中不参与签。锚定矿工选举过程的 PoW 排序与主链延长的 PoW 同步进行,即主链矿工不仅将使用工作量证明计算结果获得主链 SIPC 奖励,还将获得锚定矿工奖励。锚定矿工奖励来自于子链跨链交易发起者所支付的 SIPC 矿工手续费。
在保证主子链的一致性问题上,我们采用了 n 个确认的机制。当发起一笔跨链交易时,子链内的区块应首先获得 n 个块高的确认,才能够通过锚定矿工的验证并广播至主链上。经过主链 n 各块高的确认后,才分别将确认后的交易状态写入跨链交易所涉及的两个子链当中。
n 的大小与跨链交易的金额、数据量成正比,也就是价值越高的交易所需要的在子链和主链中的确认数要求越高。目前设计中,主链确认数 n 沿袭了比特币的常数设定思路,由于主链平均出块时间 12 秒,因此主链的 n 值设定为 15 时其安全性将会接近于比特币 6 个确认的时间。而子链确认数则以主链 15 个确认的基础,基于跨链交易的金额、数据量进行动态调整。
http://ww1.sinaimg.cn/large/0073VfK9ly1g1wcc47titj30bh06y3yz.jpg 图表 6 SIPC 模型 ( Simplechain Foundation )
SimpleChain 在白皮书 1.0 中提出了主链数字资源 SIPC 的微通胀机制,即随着子链的增加、子链活跃度的增加以及对跨链交易需求的增加,SIPC 的区块奖励会在原本的衰减曲线基础上产生微调(上图中从绿色虚线变为黑色实线)。这种微调的结果就是当主链 SIPC 被作为一种资源,子链对其的需求量增加的时候,主链出块奖励将相应增加,以当前状态为例,主链出块奖励将可能从 20SIPC 增加到 21SIPC。
这一设计的目的在于让子链与主链上的角色之间的关系更为稳固。子链对主链的需求在于通过主链协调跨链交易,一笔跨链交易的过程为:
( 1 ) 子链用户发起跨链交易并支付手续费,手续费包含子链 Token ( T )与主链 SIPC ( S );
( 2 ) 子链矿工或验证节点完成共识验证并收取部分子链 Token ( t1 )作为手续费;
( 3 ) 被选举出来的跨链矿工收取剩余部分子链 Token ( t2 )以及手续费中的全部主链 SIPC ( S )以及运营池中的部分 SIPC ( s2 )作为手续费完成跨链锚定与广播;
( 4 ) 一般主链矿工收取主链交易手续费 SIPC ( S ’)打包跨链交易;
( 5 ) 另一条子链锚定矿工读取主链中的跨链交易,广播至目标子链中。
以上过程中 T=t1+t2,然而一般主链矿工收取的主链交易手续费 S ’=R+k,R 为原始主链出块奖励,即当前的 20SIPC,k 则为微通胀调节奖励。
上面出现了运营池的概念,所谓运营池即是在子链初期创建时,创建节点通过抵押 SIPC 的形式向子链注入的启动资源,运营池中的 SIPC 将在跨链交易中作为部分奖励 s,输出给锚定矿工。
假设一个资料的启动运营池容量是 10SIPC,在跨链过程中,每次会分出其中的 0.1SIPC 给到跨链矿工作为跨链矿工的部分奖励,一次交易过后运营池容量减少为 9.9SIPC。此时,一般主链矿工收取到的交易手续费 S ’=20+0.01 ,这 0.01 就是微通胀调节奖励。
运营池可以由任何 SimpleChain 用户选择再次注入 SIPC,也可由子链共识触发活跃度下限,更改跨链矿工奖励来使得跨链矿工获得的 s2 为负,即部分跨链手续费被存入子链运营池。此时,一般主链矿工收取的手续费中的微通胀调节奖励 k 将为 0 或转向负数。这种情况下表明子链走向衰退期,或子链与主链将逐渐通过减少互相激励而脱离关系。
上述模型中可能存在的技术风险包括主链区块当中对于包含跨链交易的交易量上限问题,以及过多锚定矿工造成的主链负担过重的问题。
经济模型方面,存在“损人不利己”攻击的可能,即通过创建衰减子链,影响主链矿工与用户利益的情况。
[1]. BitInforCharts (2019) Bitcoin Block Size historical chart, Available from: https://bitinfocharts.com/comparison/bitcoin-size.html [Accessed on 02/04/2019]
[2]. Buterin. V(2015) On Slow and Fast Block Times, Available from: https://blog.ethereum.org/2015/09/14/on-slow-and-fast-block-times/ [Accessed on 04/04/2019]
[3]. Buterin. V(2019) Merge blocks and synchronous cross-shard state execution, Available from: https://ethresear.ch/t/merge-blocks-and-synchronous-cross-shard-state-execution/1240 [Accessed on 03/04/2019]
[4]. Buterin. V(2019) How can we facilitate cross-shard communication?, Available from: https://github.com/ethereum/wiki/wiki/Sharding-FAQ#what-is-the-train-and-hotel-problem [Accessed on 03/04/2019]
[5]. Prestwich. J(2019) What to expect when eths expecting, Chinese Version Translated by EthFans, Available from https://ethfans.org/posts/what-to-expect-when-eths-expecting [Accessed on 02/04/2019]
[6]. Skidanov. A(2019) The authoritative guide to blockchain sharding part 1, Chinese Version Translated by EthFans, Available from: https://ethfans.org/posts/the-authoritative-guide-to-blockchain-sharding-part-1 [Accessed on 02/04/2019]
[7]. Skidanov. A(2019) The authoritative guide to blockchain sharding part 2: Unsolved problems in blockchain sharding, Chinese Version Translated by EthFans,https://ethfans.org/posts/unsolved-problems-in-blockchain-sharding [Accessed on 02/04/2019]
[8]. Zamir. V(2018) Casper, Ethereum Community Conference on March 8-10,2018, Available from: https://www.youtube.com/watch?v=GNGbd_RbrzE[Accessed on 03/04/2019]