如何使用区块链分片来进行区块链扩容
扫描二维码
随时随地手机看文章
区块链分片(Blockchain Sharding)是为区块链进行扩容的一种重要技术,以通过改变网络验证的方式,增加吞吐量。这是区块链技术走向商业化实践必须要解决的问题之一。
如何用Go实现区块链分片
1. 区块链分片要解决的问题
2. 区块链分片项目对比
3. 玻色子共识
4. go语言特点
5. go实现区块链分片
6. TPS大赛介绍
1.区块链分片要解决的问题
公链的挑战
众所周知,公共区块链平台今天面临的最大问题之一就是可扩展性。所有主流的平台都在努力提高每秒的交易量。比特币网络平均每秒可以处理7笔交易,以太坊网络15笔每秒。缓慢的交易处理造成了一个主要问题,因为大量的未完成交易阻塞了网络,使得那些诸如实时支付这样的应用程序很难在区块链上一展身手。随着确认支付的时间拉长,最终就会给用户带来诸多不便;这也是为什么像PayPal和Visa这样的信用卡支付方式仍然更具吸引力的主要原因之一。Visa每秒能处理约5.6万笔交易。
垂直扩容与水平扩容
最早很多公链使用垂直扩容,比如修改出块的速度、出块的大小,试图通过调整参数增加单条链的性能来扩容。这类似于在中心化的系统里想要扩容,就去用最快的CPU、更大的磁盘。垂直扩容的缺点是参数调整对性能提高很容易达到上限,例如由于全球P2P网络传播速度的限制,进一步减少出块间隔或增加块大小会增加孤块产生概率,从而浪费哈希算力。另一种类似垂直扩容的方案是采用权益证明(POS)和委托权益证明(DPOS),例如EOS的DPOS共识,只允许21个节点产生区块,损害了网络的去中心化程度。
区块链水平扩容的基本思想是分而治之,来源于传统概念的数据库分片,它将数据库分割成多个碎片并将这些碎片放置在不同的服务器上。在公链的情境中,分片就是把数据或者流量,分割成不同的碎片放在不同的地方并行处理。通过增加网络中分片的数量,整个区块链网络的吞吐量将会线性增加。分片技术被认为是在不损失去中心化程度和安全性的条件下可实现扩容的方案。
分片类型
分片(Sharding)是区块链扩容的链上解决方案之一。
区块链分片的层级由下到上分别为:网络分片(Network Sharding)、交易分片(Transaction Sharding)和计算分片(ComputaTIonal Sharding)以及状态分片(State Sharding)。
· 网络分片
网络分片是最基础的一种分片方式,就是将整个区块链网络划分成多个子网络,也就是一个分片。网络中的所有分片并行处理网络中不同的交易。开发者需要开发一种机制来确定哪些节点可以按照安全的方式保留在哪些分片中,这样就能避免那些控制大量特定分片的人所发起的攻击。
· 交易分片
交易分片的前提是先进行网络分片,再将全网交易划分到不同分片中进行验证和打包。主要涉及的问题是哪些交易应该按照特定的属性被分配到哪些片当中。
· 计算分片
只有网络的一个子集(如一个分片)执行计算,从而高效执行运算密集的任务。
· 状态分片
状态分片是将完整的账本信息分别存储在各个分片当中,也就是把整个区块链的状态划分为多条区块链状态,每个可以相对独立的处理交易,并且可以无缝的和另一个分片交互。
实际上,在状态分片中,每个片区中的节点就是在搭建自己的一条分片链,这条链中包含的交易只会影响这条分片链本地的状态。因此,分片中的验证者只需要存储本地的状态,并且只需执行和中继那些影响本地状态的交易。这种拆分减少了节点对计算能力、存储和网络带宽的需求。但也引入了新的问题,如数据可用性和跨分片交易。
· 各种分片类型的对比:
网络分片、交易分片可以解决计算能力瓶颈,而状态分片则一方面能够解决计算能力、网络带宽和存储能力瓶颈,另一方面降低了需要验证事务的节点的数量。因此状态分片是最为理想化的分片方式。
2. 区块链分片项目对比
当前使用区块链分片技术的公链已有不少。我们把主流做分片/跨链的公链平台做了以下对比:
从上图看,分片项目的TPS都比较高,基本上已经可以满足大部分的需求。但从拓展性看,除了QuarkChain外,其他分片项目对共识、虚拟机、账本模型、代币经济学的支持都比较单一。
我们把最近非常热门的Polkadot,Cosmos与QuarkChain也进行比较,看看有何不同?这三个项目都涉及到链之间的交互,如果把以太坊升级到2.0(信标链,有多个分片也涉及到跨片交互)算上,我们可以把这4个放在一起做个简单的对比。
从灵活性上看,Cosmos和QuarkChain上的子链(分片链)最为灵活,可以使用多种共识机制。Polkadot还是非常依赖于PoS的共识模型,包括parachain根据现在代码是不能随意配置共识的,灵活性方面相对于夸克链来说,约束多一些。
从安全性上看,Cosmos的思路是每个链自己负责自己的安全,这里面我们认为安全问题还是会发生。Polkadot跟我们QuarkChain一样,会共享安全。
从交互性上看,四个项目都是由一个中间人链来协调子链(分片链)之间的交互:以太坊2.0——信标链;QuarkChain——根链;Polkadot——RelayChain;Cosmos——Hub。
从开发进度上看,QuarkChain和Cosmos已经上线,以太坊2.0和Polkadot则还在开发中。
我们把上面的讨论总结在一张表里便于观看:
3. 玻色子共识
共识机制是区块链的根本,引入分片后,区块链的共识机制也有了相应的变化。这里我介绍一个非常重要的分片共识机制--玻色子共识。
玻色子共识是QuarkChain首次提出的通用分片共识框架,可以描述QuarkChain, Polkadot甚至eth2.0(还在设计中),并且在QuarkChain主网生产环境中运行良好。
具体而言,玻色子共识是一个基于单链共识基础上的多分链(片)共识。他是一个双层结构,分为根链(root chain)和分片(shard chains)。分片块与单链相同,用于保存交易数据,提高TPS和拓展性。根链块中只保存各个分片的区块头,用于做分片权威块确认,保障整个系统(生态)的安全。
根链本身使用的共识机制可以根据需求进行选择,如PoW/PoS/dPoS等。分片上的共识为根链优先原则+该分片自身的共识PoW/PoS/dPoS。不同分片所使用的分片自身共识可以不一样。比如说分片1中使用了PoW,而分片2中使用DPoS。
什么是根链优先原则?根链优先原则指的是当分片链出现分叉,系统需要在分叉中挑选最优分叉时,需要先对比两个分叉对应的根链哪个更优(与根链共识相关),根链最优的分叉会胜出(不会关心分片区块的优劣)。在根链优劣相同的情况下,再用分片自身的共识来比较分叉的优劣,选择最优分叉。
根据上面的描述,如果要攻击使用玻色子共识,必须要同时攻击根链和分片才能起到作用。这使得攻击难度大大增加。我们可以通过激励机制(公链)或者根链保护机制(只允许部分可信节点出块,联盟链)来增加根链的安全,从而进一步保障整个系统的安全性。
玻色子共识有许多的优点:
1. 拓展性好,支持异构分片
2. 支持跨链、跨片交易
3. 安全复用,所有的分片都收到根链的保护,使得整个系统中每一个分片的安全性都很高,即使新加入的分片也会立即受到根链的保护。
对玻色子共识感兴趣的朋友可以看看我们玻色子共识介绍文章:
http://kuaibao.qq.com/s/20180927G1JM1P00?refer=spider
玻色子共识如何对抗黑客攻击,可以看看这篇文章:
https://zhuanlan.zhihu.com/p/55842744
比较喜欢研究的朋友可以看看我们发的论文:
https://github.com/QuarkChain/pyQuarkChain/blob/master/papers/boson.pdf
该论文是借用数学的语言来描述玻色子共识,以及现有的单链共识。非常值得一看。
4. Go语言开发区块链的优势
区块链首先需要非常高效的运行,主要是由于哈希及加密算法计算和大量的交易数据处理,传播以及存储等。区块链需要网络编程,多平台支持,代码复杂性高,需要高的可维护性和安全性保证。而go语言无论在执行和开发效率上都满足了实现区块链的技术要求。
首先,从执行效率上来说,go比解释型语言的JavaScript和Python执行效率更高。Go可以直接在OS上运行,自然比Java等虚拟机上运行的编译型语言运行得更快,因此被用作开发Docker和EVM的语言。Go为分布式而生。使用Go构建的微服务可轻松扩展至数百万个请求。GorouTIne使得Go在语言层面支持并发,gorouTIne分配的初始栈大小为2k,比其他语言的线程轻量级得多,同时会根据运行状况动态扩展或收缩。Go的runTIme采用协作式调度,最大限度的发挥了多核机器的能力。
其次,从语言特性上来说,Go作为编译型语言,错误会在编译时出现并得到处理,避免运行中突然出现的错误,多人协作开发和维护更加安全可靠。编译成可执行文件后,部署非常方便,甚至支持跨平台编译运行。另一方面,Go兼具解释性语言的优点:编译时间短,启动时间短,对于测试,部署和其他脚本的开发和使用也很方便。Go的语法表达能力很强大,例如支持指针,闭包,面向对象,垃圾回收等,比同样是编译型语言的C开发效率更高,实现同样功能的代码量少,维护更容易。
最后,从社群生态来看,go的谷歌背景和开源属性吸引了越来越多的开发者:Go语法简洁,易于开发人员学习和掌握,积累了越来越丰富的标准库,特别是网络库非常强大,如rpc,grpc等。Go内置强大的工具,如go fmt,go get, go build, go doc等, 其中go fmt使得代码格式统一,交流和维护方便。Go内嵌C支持,go代码也可以直接包含C代码,利用现有的丰富的C库。
使用golang的区块链项目如Hyperledger Fabric,go-ethereum为后来者提供了良好的架构范式和底层模块,如rlp,rlpx,libp2p等,是被实践检验过的开源代码。使得用Go开发区块链项目更加简单。
使用go语言作为实现技术的还有Cosmos,Polkadot,Loom Network,Dero,GoChain,以及将go作为智能合约语言的Hyperledger Fabric chaincode等。
5. Go实现区块链分片
用go开发的分片项目有几个,这里我们以QuarkChain的go版本为例,讲讲QuarkChain是如何用go实现分片的。
· QuarkChain 的简介
QuarkChain 是第一个成功实现状态分片的公链,具有每秒十万次以上的链上交易处理能力(100,000+TPS),依靠对于分片功能的完善设计,在实现高吞吐能力的同时,实现了不同分片共识机制、账本模型、交易模型和代币经济四个维度的可定制化,成为安全、去中心化、效率集于一身的灵活、高扩展性且方便使用的区块链底层架构。整体设计除了性能还考虑到了特性上的延伸,支持跨链交易,多原生代币,安全复用,协同挖矿和算力复用,以及含有权益的工作量证明(PoSW)等特性。
QuarkChain使用我们刚刚讲的玻色子共识,使得每个分片都能能复用根链安全能力,并引入交税机制,吸引大于50%全网算力来保证根链安全。QuarkChain还依靠独创的带有权益的工作量证明(PoSW)-- 融合了PoW和PoS的两大特点,需要质押匹配挖矿算力的代币作为保证金,拉高攻击者成本,避免分片在开设早期因算力不足而遭到攻击。
执行交易的分片层具有无限的扩展性和动态添加分片的能力,新加入的分片可以立即得到根链算力的保护。每个分片可以有自己的共识,也能够在分片上发行自己的原生代币,定义自己的智能合约。也就是说我们现在看到的所谓“跨链、PoS、Defi”等等新概念,QuarkChain在设计之初就兼容了这些功能。
· QuarkChain的架构
QuarkChain借鉴了中心化世界中大型分布式系统解决方案中常用到的cluster的概念,每个节点都是一个cluster。每个cluster中有一个master 服务和一个或多个Slave服务。master 服务中包含根链,并对外提供对外服务的JsonRPC接口和节点间通讯的P2P接口;Slave 服务中包含一个或多个分片。Master 服务和Slave 服务间、Slave服务与Slave服务间(跨链交易)通过GRPC接口进行通讯。
当前代码已经开源,可以从我们的Github(https://github.com/QuarkChain/goquarkchain)下载。
在代码中,cluster目录下,master、slave服务以及他们共同需要的config、service和rpc模块。
· 分片间通信
在区块链中不同的节点通过P2P协议进行通讯,达成共识。在QuarkChain中,不同节点间的分片并不会建立P2P连接,因为当前P2P协议的连接并未到瓶颈,而那样做会引入较高的复杂度。当前分片间的通讯是通过根链P2P层进行转发。以下根链P2P消息的结构体:
在消息结构体中,我们添加了Metadata属性,来表示消息要发送到的链(根链或者某个分片)。当根链收到消息并确认要转发的分片后,就直接转发给对应的分片。在收到分片返回结果后将结果直接转发给发送该P2P请求消息的节点(cluster)。整个过程中,根链不会对发送内容(data)进行encode、decode以及验证操作,消耗很低,因此能够满足大量分片的转发工作。
为了完成相应的分片间同步,我们也相应的增加了分片操作码:
· 异构分片的支持
在区块链中最重要的几个object便是交易(transaction),区块头(header),区块(block),区块链(block chain)。而异构分片意味着这些object的定义以及对应的处理逻辑都有可能不同。但与此同时,区块链要处理流程都是大同小异的。因此我们给这些object定义了相应的接口。
以下定义了IHeader, IBlock, IHashable:
以下是交易的定义,在交易的定义中,通过TxType字段标明该交易的类型是Evm类型还是UTXO类型等,并在编解码时根据不同的类型做相应的操作。
在区块链的操作同步(sync)、交易执行(process)、验证(verification)、共识(consensus)都定义了相应的接口,而这些接口方法都会接收IHeader/IBlock作为参数。这使得添加新的异构分片、交易类型(account、utxo),共识算法、VM变得模块化,灵活可拓展。
· 跨片交易
QuarkChain特性使得用户在每个分片中都有一个地址,因此跨片交易的流程分为简单的两步:
1. 余额提取:此操作从用户A的余额中提取代币,代币数量等于转账金额+预留交易费(gasPrice*startGas)。此操作发生在分片X中。
2. 执行/退款:对于余额转账,执行操作会增加用户B的余额;或者对于访问智能合约交易,执行操作会运行智能合约C的代码。完成转账/智能合约调用后,计算实际的交易费用,并将剩余的交易费用(预留-实际)退还给用户A在Y分片的地址。这个操作发生在Y分片。
代码实现方面,当from shard 部分执行结束后,跨链交易会被发送到本cluster中的to 分片上,to 分片会将其保存。当包含该交易from部分的区块被root block确认后,to分片对余额进行转移,或者调用智能合约。