什么是分片(Sharding)
分片技术并不是什么创新的概念,早在区块链技术出现之前,就已经在传统数据库中运作了,主要用于大型商业数据库的优化。其概念就是将数据库中的数据,切割成很多数据分片,再将这些分片分配到不同的伺服器中储存,如此一来,就不会因为短时间内出现大量数据访问请求,而出现单一伺服器压力过大的问题。
在传统的区块链网路中,交易必须有网路中的每个节点进行确认,以保证交易的安全,然而这也是导致交易速度难以提升的主因之一。
而把分片技术运用到区块链网路中的方式,是将区块链网路划分成若干个子网路 (或称分片,shard),每一个子网路都会包含一部分节点,网路中的资料储存与交易,会被随机分配到各个分片中做处理,如此一来,每个节点只需要处理一小部份的工作,且不同分片上的交易可以并行处理,网路的交易速度便能因此获得提升。
另外,传统的区块链大部分都是单链结构,所有矿工都会相互竞争取下一个区块的计帐权。且大部分区块链产生区块的平均时间是固定的,例如比特币平均每 10 分钟产生一个区块,即便有越来越多的矿工加入挖矿行列,区块链也会自动提升挖矿难度,以确保区块产生速度固定在每 10 分钟产生一个区块。简单来说,区块链网路中算力的提升没办法增加交易速度,这也就是为什么区块链会是不可扩展。
如果要用简单一点的例子来形容的话,就好比你把汽车改车 V8 大马力引擎,但汽车电脑却设置了速度限制,不能开超过 60。
延伸阅读: 比特币挖矿
在分片技术中,区块链算力的提升,意味着分片数量的提升。也就是说网路中所投入的算力越多,能够同时并行处理的交易也会越多,整个网络的交易速度也会线性提升。
运用在区块链上的分片技术,又能够分为三种 : 网路分片(network sharding)、交易分片(transaction sharding)、状态分片(state sharding)。
网路分片(network sharding)
由于区块链的区块与区块之间具有强连结性,也就是说,每一次的区块新增,都需要矿工互相通信确认新区块的有效性,虽然这能确保链上交易纪录的正确性,却也导致区块链结构上存在不可扩展性的缺点。因此,分片的第一步,需要先将区块链网路分片,再尽量降低互相通信的前提下,由各个分片处理链上交易。说的简单一点就是将矿工随机分组,再将工作分配给各组矿工独立验证。
网路分片涉及到的问题是,分片后如何确保链上交易安全性能够维持。
随机分配
矿工分组之后,网路分片第一个会面临到的问题是,攻击者的攻击成本会大幅降低。下方这张图说明的是,本来假设有 100 个矿工, 要掌握 51 个才能瘫痪网路,自从有分片后, 假设是 100 个分片,矿工一人顾一个分片下,就变成我只要有全网 1% 的攻击力,就有机会瘫痪某一个甚至两个分片,而这 1% 在原本的 PoW 下,根本起不了作用。要防范攻击者最好的做法,就是建立随机性。在区块链领域建立随机性的方式主要是利用可验证随机函数(VRF, Verifiable Random Function),利用此演算法,网路可以随机抽取节点分组形成分片。这样一种随机抽样的方式可以防止恶意节点控制单个分片。
分片的共识机制
解决了矿工分组的问题后,所要面临的问题是分组后的矿工,验证过程如何达成共识。达成共识的算法可以选择我们熟知的 PoW、PoS、PBFT等共识机制。简单来说,网路分片就是矿工的挖矿规则,为了在分片的同时不失去去中心化特性,开发者需要尽可能地在安全与效率取得良好的平衡。例如,网路中分片的数量与每个分片中节点的数量等问题,都需要谨慎考虑。
交易分片(transaction sharding)
网路分片针对的是矿工的遊戏规则,而交易分片所针对的是哪些交易要被分配到哪些分片,然而,区块链的帐本模型的不同会对交易分片的开发造成影响。
UTXO 帐本模型
UTXO 的帐本系统,例如比特币,交易纪录是由多个 input 和多个 output 构成,没有帐户的概念,也不会有余额的纪录,我们没有办法按照地址进行交易分片来有效地避免双花问题。
UTXO 较直观的交易分片方式是按照交易 hash 值的最后几位进行分片。例如,「如果哈希值的最后一个值是 0 的话,那么交易将被分配给分片1,否则它被分配给分片 2 (假设只有两个分片)。」
然而,我们说过,UTXO 的交易是由 input 和 output 构成,假设 A 发起了一笔交易,该交易的哈希值的最后一个值是 0,被分配到第一个分片验证,此时,A 又发起一笔 input 相同但output 不同 (发给不同人) 的交易,该笔交易被分配到第二个分片,如果不采取任何措施,这两笔交易将因为同时在两个分片当中进行处理和验证,而导致双花攻击。
在 UTXO 帐本系统的交易分片中,解决双花攻击的办法是分片1和分片2相互通信,以确保同一笔钱没有被重复花费。但是在实际过程中,分片数量众多且交易的 hash 值是随机的,交易会被随机分配到各个分片,这就表示每个分片之间都必须相互沟通。很明显,这方法行不通,因为如果这么做,就代表分片无法独立验证,分片就没有意义了,因此 UTXO 先天上就较难以实现分片。
Account 帐本模型
由于 UTXO 帐本模型较难实现交易分片,因此,大多数采用分片技术的区块链,都是像以太坊一样的 Account 帐户帐本系统。有了帐户,每一笔交易将会包含发送者的地址与余额,因此我们只需要将交易按照发送者的地址进行分片,即可保证同一个帐户发出的多笔交易将被在同一个分片当中被处理,这样该分片即可有效的检测双花交易。不过一但涉及到跨分片交易,例如:分片1的帐户要与分片10的帐户进行交易,势必需要跨分片的沟通来验证交易的有效性,但与 UTXO 相比,至少不需要跟所有的分片沟通,只需要分片1与分片10沟通即可。
状态分片(state sharding)
状态分片可以简单理解为,在区块链资料分配在在不同分片中储存。其所涉及的是链上资料的分片,也就是链上资料与交易纪录分片储存,藉此减少节点的存储负担。与其他两个分片机制相比,状态分片是最棘手的难题。目前的状态分片有以下三个问题需要解决。
跨分片交易通讯的效益平衡
过去区块链的状态,例如帐户余额状态储存在全网中,由全网节点共同更新维护。但是在分片机制下,交易会根据地址分配在不同的分片处理,也就是说,状态只会储存在其地址所在的分片中,此时要面临的一个问题是,交易不会只在一个分片中进行,时常会涉及到跨分片交易,因此若交易双方帐户被分配在不同分片,分片与分片之间势必要进行沟通才能够确保交易的有效性,频繁的跨分片互动,很容易导致整体网路效率下降。
例如 :
A 的地址分配在分片1,交易的纪录也会储存在分片1。
B 的地址分配在分片2,交易的纪录就会储存在分片2。
一但 A 要打币给 B ,就会形成跨分片交易,分片2就会向分片1调用过去的交易纪录,确认交易的有效性,A 频繁的打币给 B,分片2 就必须不断跟分片1 互动,交易的处理效率便会因此降低。
分片动态刷新和节点状态更新之间的平衡
区块链的节点会随着时间而增加,且节点若长时间未重新分配,会导致交易状态过度集中化,降低遭受攻击时的弹性。因此网路每隔一段时间需要重新调整网路节点,也就是所谓的动态分片,而新进节点也会藉此更新与同步其所在分片的状态。然而每一次的节点调整,都必须在该分片完成网路同步后,才能开始处理交易,这会造成部分延迟问题,因此设计时必须掌握好节点调整的数量与时间,否则很可能会造成分片瘫痪。
全网数据备份与中心化风险之间的平衡
还有一个问题是,若某些特定的分片遭到了攻击而导致其验证失去有效性。由于分片并没有复製系统 的全部状态,所以网路也无法验证那些依赖于该分片的交易。
解决此问题的方法是维护存档或进行节点备份,这样就能帮助系统进行故障修復以及恢復那些不可用的数据。但是,这样就代表系统的状态只会储存在少数节点,这会引发一些中心化的风险。
总结
虽然分片技术与其他解决方案相比,较复杂也较难实现,但分片技术依然是目前备受期待的 Layer 1 扩容方案,知名的分片项目 Zilliqa 主网在2019年1月31日正式上线了,过去在测试网上都有相当不错的表现,实际的效能还有待确认。
而我们所熟悉的以太坊,也将会慢慢开始进化,从以太坊1.X进化到以太坊2.0,除了会将共识机制从 PoW 改成 PoS 外,还会加入 Beacon Chain 让分片技术得以在以太坊上实现。
分片技术的发展,或许将成为区块链迈向落地应用的一项重要决定性因素。