典型区块链存储与查询技术综述

2022-08-18 03:51钱海洋姚中原斯雪明
郑州大学学报(理学版) 2022年6期
关键词:以太存储系统哈希

潘 恒, 钱海洋, 姚中原, 刘 炜, 斯雪明,5

(1.中原工学院 前沿信息技术研究院 河南 郑州 450007; 2.河南省区块链与数据共享国际联合 实验室 河南 郑州 450007; 3.郑州市区块链与数据安全共享重点实验室 河南 郑州 450007; 4.郑州大学 网络空间安全学院 河南 郑州 450002; 5.上海交通大学 计算机科学与工程系 上海 200240)

0 引言

区块链是密码学、P2P网络、共识算法以及智能合约等多种技术的集成,具有去中心化、防篡改、可追溯等特性[1]。近几年区块链技术发展迅速,其应用也由最初的数字货币、金融服务,扩展到医疗[2]、教育[3-4]、政务[5-7]、供应链[8]、版权保护[9]、物联网安全[10]等诸多领域,展现出其存在的巨大价值。

目前,基于区块链的应用多是利用区块链的分布式存储及其不可篡改、可追溯等特性来实现可信存证以及查询溯源等功能[11]。区块链系统在上述应用中可以被看作是一种新型的安全可信的分布式数据库系统。然而,区块链自身在存储查询方面存在着不足,如存储效率低、存储开销巨大、查询速度慢以及链上查询功能单一等问题,这些问题一直制约着区块链的发展,成为区块链应用落地的瓶颈。针对上述问题,虽然国内外学者做了大量研究,但大多是从数据管理的角度出发,分析传统数据库与区块链数据库之间数据管理技术的异同[12-16]。本文聚焦典型的区块链系统,通过对典型区块链系统的数据存储与查询技术分析,研究区块链数据存储与查询技术的发展。在众多区块链系统中,比特币[17]、以太坊[18]、Hyperledger Fabric[19]以及FISCO BCOS[20]是目前较为成熟、研究相对较多的公有链和联盟链系统,研究它们的存储及查询方法具有较强的代表性。因此,本文针对比特币、以太坊、Hyperledger Fabric以及FISCO BCOS四个典型区块链系统,从存储系统、查询机制等方面,分析了典型区块链系统的数据存储及查询方法,归纳出当前区块链系统在存储及查询方面存在的主要问题,总结了区块链存储与查询方面的优化方法,并对未来区块链存储与查询技术发展趋势进行了展望。

1 典型区块链的数据结构

在四种典型区块链系统中,比特币和以太坊是最具影响力的公有链系统,Hyperledger Fabric是应用最为广泛的联盟链,FISCO BCOS则是由微众银行开发的最具代表性的联盟链。

1.1 典型区块链介绍

(1) 比特币

比特币是中本聪在2008年11月提出,于2009年1月上线的点对点电子现金支付系统[17],其支撑技术就是后来的区块链。比特币建立起了在节点互不信任环境下的去中心化数字货币交易体系,这一创新开创了区块链1.0时代。

比特币对用户没有任何审查机制及准入要求,其通信也采用完全分布式。作为电子现金交易系统,比特币链上存储系统全部状态数据实际就是“未花费交易输出”(unspent transaction output, UTXO),而比特币程序也仅是能够实现转账锁定和解锁功能的简单脚本等。因此,比特币的存储及查询还不足以作为分布式数据库系统使用。但作为第一个区块链系统,比特币采用的分布式账本、块链式数据结构、交易哈希Merkle树、工作量证明(power of work, PoW)共识技术[21]等都成为区块链的经典,其存储结构和查询技术等也仍然是目前区块链最常用、最经典的方法,很多新方法均是由此演进而来的。

(2) 以太坊

作为区块链2.0的代表,以太坊应用范围从比特币的简单支付扩大到更广泛的金融、半金融及非金融领域[18]。以太坊的存储、查询、共识、程序设计等方法与比特币也出现了很大不同。例如,以太坊提出的基于虚拟机的智能合约[22]、支持工作量证明、权益证明(power of stake, PoS)的共识算法等,支持用户面向更复杂、更灵活的场景建立去中心化应用,建立分布式网络信任平台等。以太坊设计了外部账户、合约账户,链上记录状态数据、收据数据、交易数据等不同类型数据。与比特币相比,以太坊向分布式存储系统又迈进了一步。

(3) Hyperledger Fabric

虽然公有链对金融及相关业务有天然优势,但其完全去中心化的特点,也存在安全、隐私等问题,一定程度上限制了公有链在非金融领域的应用。现阶段半去中心化、有一定用户准入机制的联盟链逐渐成为非金融领域应用的热点。联盟链的出现标志着区块链进入3.0时代。Hyperledger Fabric是开源超级账本中应用最广泛的联盟链,其设计目的就是为了促进了各行业与区块链技术的结合,构建企业级通用区块链系统。

作为联盟链,准入审核机制使得节点间存在一定的信任,因此其共识算法可使用各种非拜占庭算法提高共识效率[23-24]。在Hyperledger Fabric系统中链码就是智能合约,具有更加丰富的功能。由于Fabric面向的应用场景更加广泛,其链上存储内容、存储结构、查询访问方法与以太坊有明显区别。例如,以太坊与Fabric链上数据都包括状态数据,但以太坊的状态数据主要表示账户余额,而Fabric的状态数据主要表示系统中某一键值数据的最新状态值,且引入Bucket树对状态数据进行组织[25]。

(4) FISCO BCOS

作为国产联盟链的代表,FISCO BCOS发展迅猛。虽然FISCO BCOS的架构是基于以太坊底层技术发展而来的,但根据实际性能需求又做了较大改进,与以太坊有较大的差异,例如FOSCO BCOS的共识算法支持Hyperledger Fabric所采用的非拜占庭算法(practical byzantine fault tolerance, PBFT)或Raft等。除了支持以太坊的智能合约编译外,FISCO BCOS还实现了一个预编译的合约框架,该框架支持使用C++编写合约,响应运行速度更快,资源消耗更少。从数据存储和访问的角度看,FISCO BCOS的数据模型以及链上数据类型与以太坊基本相同。

1.2 典型区块链数据结构

由于四种区块链系统的发展背景及应用场景不同,其存储内容及数据结构各有特点,直接影响其存储与查询方法。

(1) 比特币

四种典型区块链都采用块链式结构作为其核心数据结构,每个区块包括区块头和区块体两部分。如图1所示,比特币的区块头中存放了前一区块哈希值、时间戳、版本号以及Merkle树根值等,区块体中存储多笔交易。

图1 块链式结构Figure 1 Block chain structure

图2 比特币区块结构Figure 2 Bitcoin block structure

比特币区块的详细结构如图2所示。每笔交易由输入和输出组成。比特币中交易之间相互连接,每笔交易的输入都对应着先前某笔交易的输出[1]。交易的输入内容主要包括上笔交易的哈希、上笔交易的输出索引和输入解锁脚本,交易输出内容主要包括输出交易的比特币数量、输出脚本长度以及输出锁定脚本。

Merkle树是比特币重要的数据结构。最初由Ralph Merkle提出,用于生成数字证书目录摘要[13],在比特币中用来存储每个区块的交易。Merkle树是一个交易哈希组成的完全二叉树。它的每个叶子节点对应一笔交易哈希,逐层进行哈希运算,最后将所有的数据块计算成一个Merckle根值,如图1所示。

(2) 以太坊

相比于比特币,以太坊的数据类型更加多样。如图3所示,以太坊有了状态树、交易树、收据树、账户存储树等,状态树、收据树、交易树的根值都存储在区块头上[18]。其中:状态树是账户地址到账户状态数据之间的映射,状态树代表了以太坊所有交易的当前状态,是一个类似比特币UTXO的全局量,要求全网所有节点始终保持一致;交易树是本区块内所有交易组成的;收据树是本区块所包含交易的具体信息;账户存储树是对单独一个账户的所有状态信息的归纳。

图3 以太坊存储整体结构Figure 3 The overall structure of ethereum storage

以太坊融入了前缀树的思想[26],对前缀树进行改进,提出MPT树(merkle patricia tree, MPT)[27]。具体包括:前缀树节点的键值经过运算转换成相同的长度,减少其因键值的长度不同而存在的空间浪费;树的节点分为扩展节点、分支节点以及叶子节点,通过键值对的组合方式存储不同内容,方便对节点控制;连续两级以上的扩展节点进行合并,缩短了树高,提高遍历速度。交易树、状态树和收据树均是MPT树。如图4所示,状态树包含了扩展节点、分支节点以及叶子节点。例如,扩展节点包含了前缀树中相同前缀的Key,账户ab113、ab716、abf19都有ab前缀,分布在同一扩展节点。分支节点在扩展节点之后,表示前缀在扩展节点之后产生的分支。账户ab113、ab716、abf19在ab之后的字符串不再相同,所以分支节点中的Key为相同前缀后的数据,实现树的分支。叶子节点Key包含分支节点Key之后的前缀,例如账户ab113,其前缀ab和1都存储在扩展节点和分支节点中,剩余前缀13存储在叶子节点作为Key值,Value保存账户的状态数据。

图4 MPT树结构Figure 4 MPT tree structure

虽然相比于比特币的Merkle树,以太坊的MPT树能有效提高查找效率并且减少存储消耗,但MPT树结构相对复杂,易产生数据聚集等问题,影响查询效率。

(3) Hyperledger Fabric

图5 Fabric账本结构Figure 5 Fabric ledger structure

账本是Fabric的关键组件,Fabric系统中所有数据都记录在账本上。如图5所示,Fabric账本结构由文件系统、状态数据库、历史数据库和索引数据库组成。文件系统用于存储所有区块数据,历史数据库以及索引数据库主要存储区块数据的索引信息,用于查找区块数据文件。状态数据库记录交易执行结果的最新状态,每执行完一个区块,需要对当前状态数据进行计算,保证每个节点在执行完一个区块后的世界状态保持一致。

Fabric用Bucket树计算当前状态数据的根值。Bucket树是由底层的哈希桶以及上层的Merkle树组合而成。Bucket树对键值进行哈希运算,计算出数据在哪个哈希桶中。每个哈希桶内可存储多条数据项,每个数据项代表一条用户数据,桶中的数据项按Key的字典序排列。叶子节点的哈希值是桶内所有数据内容哈希计算的结果。如图6所示,B0~B5表示组织数据的哈希桶,Merkle树叶节点可对应n个哈希桶。每n个相邻节点的哈希值计算得到其父节点哈希值,以此向上组成Merkle树。

图6 Bucket树结构Figure 6 Bucket tree structure

由于Bucket树的叶子节点是哈希桶中所有数据项的杂凑值,而Merkle树以及MPT树的叶子节点仅包含单独一条数据项杂凑的哈希值。所以,在相同规模的数据下,Bucket树节点的数量较小,带来的存储消耗及查询开销也小于其他两种树。另外,Bucket树节点重新计算的代价变小,方便数据的添加与更新。

(4) FISCO BCOS

FISCO BCOS引入表结构来归纳存储链上数据,将链上生成的数据转化为抽象表结构,不同类型的数据分类归纳到不同的表中。具体包括系统表、用户表和账户表。系统表默认存在并组织系统中的全部数据,用户表是对用户调用系统预编译合约的记录,账户表存储着外部账户相关信息[20]。在系统中,数据库存储类型分关系型和非关系型,以交易数量上限所在的表为例,其表结构如图7所示。

图7 FISCO BCOS的表结构Figure 7 Table structure of FISCO BCOS

相比利用树结构组织数据存储,FISCO BCOS结构较为简单,具有构建时间快、存储消耗低等优势。数据基于表结构存储和管理也更为方便。同时,表结构能够兼容各种存储引擎,更利于业务开发。

2 典型区块链的数据存储方法

四种典型区块链系统使用到的存储系统包括文件系统、嵌入式键值数据库(如LevelDB[28]、RocksDB[29]等)以及关系型数据库(如MySQL)存储数据,但考虑到数据的用途和访问频次情况,各系统对数据存储系统的选择与用法各有不同。

表1总结了典型区块链使用的数据存储系统的特点。文件系统主要存储区块数据,一般将数据进行二进制编码存储在文件中,按照文件编号查找数据,其写性能尚可,但读性能差,主要用于存储区块数据。LevelDB、CouchDB[30]以及RocksDB都是基于Key-Value结构的键值数据库。其中LevelDB和RocksDB都被应用到存储链上的各种数据。LevelDB基于日志排序合并树结构(the log-structured merge-tree, LSM-Tree),具有较强的写性能,尤其适用于早期区块链系统写入密集型应用。RocksDB基于LevelDB改进,性能更高,并且能够根据情况灵活调节读写性能。因CouchDB具有较好的读性能并且支持复杂查询被Fabric用来存储状态数据。MySQL是关系型数据库,读写性能均衡但弱于其他存储系统,是FISCO BCOS用来处理复杂查询场景而提供的存储引擎。

表1 典型区块链使用的存储系统Table 1 Storage systems used by typical blockchains

(1) 比特币数据存储系统

比特币的存储系统主要以文件系统与LevelDB 为主。如图8所示,文件系统主要存储区块数据和区块“undo”数据,分别以blk*.dat和rev*.dat的形式存储,每个文件大小设置为128 M。文件中存储的区块数据主要包括区块体中的交易以及区块头等信息。区块“undo”数据是在系统产生链分叉时,对区块链进行回滚修正的数据。比特币的状态数据与索引数据都以键值对的形式存储在LevelDB中,分为状态数据库和索引数据库。其中:状态数据库主要存储当前所有交易的UTXO,数据的Key值为交易哈希,Value值为当前该笔交易的UTXO信息等;索引数据库主要存储该笔交易在某区块中的位置,可以快速定位到相关交易数据。

图8 比特币数据存储系统Figure 8 Bitcoin Data Storage System

比特币使用文件系统存储,可方便系统以日志形式追加数据以及对区块进行查找追溯。但当查找某笔交易时,通过遍历文件的方式效率极低。因此,系统将文件系统和LevelDB相结合,两者相互配合共同运作。依靠LevelDB存储区块所在文件等索引信息,有效提高访问效率,快速定位到相关交易区块的位置,辅助系统查询。

(2) 以太坊数据存储系统

由于以太坊的存储数据结构主要以MPT树为主,而MPT树有明显的前缀标识,特别适用键值对存储数据,所以以太坊将LevelDB作为主要的数据存储系统[14]。

如图9所示,LevelDB中存储着区块数据、账户数据、收据数据以及索引数据等。区块数据库的存储包括区块头和区块体,区块头中存储前一区块哈希值以及状态树、交易树和收据树的根值、随机数等信息,区块体中主要存储交易数据和块数据。通过区块哈希或区块号作为Key值,Value存储对应的区块头或区块体数据。而账户数据库主要存储以太坊账户的状态数据,通过账户地址作为Key值,其对应的Value值包括账户余额、合约代码等信息。在以太坊中,收据数据记录交易到区块后产生的交易收据,每个区块中交易的收据数据都存储在一个集合中。因此,在收据数据库中,区块哈希与区块号的组合作为Key,对应的Value是所指区块内的交易收据集。同样,以太坊也设置了索引数据,将交易号或交易哈希等信息作为Key,其Value包括交易所在的区块号等。

图9 以太坊数据存储系统Figure 9 Ethereum data storage system

实际上,以太坊在实现执行交易、验证数据等功能时,并不像比特币依赖区块间的联系。因此,以太坊使用LevelDB可帮助其高效地完成以上功能,并消耗较小的存储空间。

(3) Hyperledger Fabric数据存储系统

Fabric的存储系统同样以文件系统及LevelDB 为主,二者相互配合完成运作。如图10所示,Fabric的文件系统用于存储区块数据,相比于比特币将每个文件大小设置为128 M,Fabric将每个文件的大小减小到64 M,以方便更快地检索每个文件的区块数据。Fabric中的LevelDB主要负责存储索引数据和状态数据,状态数据是系统存储的业务数据的最新值,索引数据记录历史业务数据存储的文件位置以及交易的偏移量等信息。

图10 Fabric数据存储系统Figure 10 Fabric data storage system

Fabric除了有区块位置信息索引,还利用LevelDB存储历史状态数据索引,为快速查询某一数据的所有历史状态提供支持。在历史数据库中,历史数据库中的Key值是一个组合Key值,包括业务数据Key值及其历史状态值所在的区块号、交易号系统存储着业务数据Key的所有历史状态Value值的索引信息。

对于状态数据的存储,Fabric还引入了可选的CouchDB。CouchDB同样使用键值存储,但CouchDB具有较强的读性能,能实现相对复杂的查询,例如模糊查询等。

(4) FISCO BCOS数据存储系统

最初FISCO BCOS采用MPT结构组织数据,将所有链上数据,包括交易、收据、区块和合约数据以及一些交易区块相关的索引信息等都存储在本地LevelDB中。但是为了提高存储性能,FISCO BCOS在2.0版本后,采用了分布式存储架构。

如图11所示,FISCO BCOS的分布式存储系统分为三层,包括状态层、分布式存储层以及驱动层。其中:状态层主要是由以太坊虚拟机(ethereum virtual machine, EVM)调用存储访问接口,包括分布式存储适配层和MPT存储适配层,分布式存储的适配层为分布式存储的表结构存储数据进行适配,MPT存储适配层为MPT结构存储数据进行适配;分布式存储层抽象了存储的增删改查接口,由状态层和预编译的合约调用,主要把区块链的核心数据分类存储到不同的表中;驱动层主要实现具体数据库的访问逻辑,数据库类型包括LevelDB、RocksDB和MySQL等[20]。在驱动层的数据库系统中,LevelDB作为常用的数据存储系统,存在内存占用高以及文件描述符超限导致节点故障等缺陷。FISCO BCOS引入RocksDB解决了LevelDB此类缺陷,具有更好的读写性能,并且RocksDB与LevelDB接口类似,迁移成本低。FISCO BCOS还引入了MySQL等关系数据库,使得系统数据存储支持关系型和非关系型两种数据类型,能够根据不同场景选择合适的数据库进行存储。

在四种典型区块链系统中,比特币和Fabric都使用文件系统和LevelDB数据库结合的方式存储数据。而Fabric利用LevelDB设计多种索引数据库,如历史状态索引等,使得查询更加高效,Fabric还支持CouchDB,提升查询的丰富性。以太坊则将所有 类型数据都用LevelDB存储。而FISCO BCOS在以太坊基础上,引入读写效率比LevelDB更高的RocksDB,同时支持MySQL等多种数据库类型。总体来说,为了适应更多应用场景,平衡链上数据读写功能、区块链存储设计正在从写密集向读写均衡转变。

图11 FISCO BCOS数据存储系统Figure 11 FISCO BCOS data Storage System

3 典型区块链的数据查询方法

区块链的不可篡改性是与其他数据库系统最大的区别之一,为此区块链也仅能进行增加和查询两类操作。

由于主流区块链系统的数据结构、存储内容以及数据存储方法均有所差异,因此系统所支持的查询内容、处理策略也不相同。上述四种区块链系统的查询处理在实际中主要包括简单支付验证查询(simplified payment verification, SPV)和索引查询两类,两类方法在查询内容以及应用场景上均有所不同,如表2所示。

表2 典型区块链数据查询处理Table 2 Typical blockchain data query processing

3.1 SPV机制查询

SPV机制查询主要基于Merkle 树结构,实现快速查询验证某笔交易是否上链,一般应用于交易支付验证[31]。根据Merkle树结构的特点,区块链中SPV轻节点仅存部分交易信息便可以验证某笔交易是否真实存在链上。如图12所示,例如需验证交易3是否在链上,只需通过SPV机制获取Hash4和Hash5信息即可。具体SPV查询验证过程如下:

(1) SPV轻节点先向全节点同步当前区块链中最长链的区块头信息,存储到本地;

(2) SPV轻节点计算待验证交易的哈希值,创建布隆过滤器。布隆过滤器是基于哈希运算快速确定某一元素是否在该集合内的一种方法[32],全节点根据布隆过滤器结果,快速查找到交易所在区块;

(3) 全节点判断交易所在区块是否为当前有效区块。如果符合条件,全节点向轻节点返回待验证交易的 Merkle树验证路径。验证交易3时,需获取Merkle树中交易4所在叶子节点的哈希值H(4)以及交易1与交易2所在叶子节点的哈希值H(1,2);

(4) 收到验证路径后,轻节点根据验证信息进行哈希计算,得到Merkle树的值Root′。例如,在验证交易3时,须根据在步骤(3)收到验证信息作计算,即Root′=Hash(H(1,2)&Hash(H(3)&H(4)));

图12 SPV查询流程Figure 12 The process of SPV

(5) 最后,通过验证路径信息计算出Merkle树的根值Root′,与本地获取的区块中的Merkle树根值Root进行对比,如果相等,则可以证明交易存在。

由于SPV的查询验证效率与树的路径有关,而Merkle树验证路径的长度和树的高度成正比,显然树的高度越高查询验证的效率就越低。以太坊和比特币拥有相同的SPV机制。但以太坊使用MPT树结构易产生前缀积聚的现象,相同数据规模下,以太坊MPT树的高度一般要高于比特币Merkle树。所以,以太坊的SPV查询验证的效率弱于比特币。而对于Bucket树,叶子节点存储的哈希值是哈希桶中的所有数据集合的杂凑值,使用Bucket树结构进行SPV验证不光要传输验证路径上的数据,还要传输哈希桶中的数据集合,这样大大增加了网络传输负担。

因此,在应用SPV查询时,比特币最优。SPV轻节点仅存储区块头和Merkle树路径,节省了存储空间,参与的用户无需承担高昂的系统维护代价,降低了查询门槛。实际上,SPV查询也仅适用于比特币、以太坊等数字货币交易区块链系统,无法支持更多的应用场景。因此,Fabric以及FISCO BCOS不再支持SPV机制,而改为以索引查询为主。

3.2 索引查询

索引查询是四种典型区块链系统共同使用的查询机制。在查询具体链上数据时,对区块遍历显然效率太低,因此需要使用各种索引结构来提高查询效率[12]。

(1) 比特币的索引查询设计

比特币自身交易结构简单,缺乏语义描述,难以进行复杂查询。交易查询处理基于LevelDB中的索引数据,通过交易号或交易哈希进行有限查询。查询具体流程如下:系统先通过索引数据库找到目标交易的相关索引信息,包括交易所在文件号、区块位置以及交易在区块中的偏移量等,根据索引信息定位交易在文件系统中的位置获取目标信息,查询流程如图13所示。

图13 比特币索引查询流程Figure 13 Bitcoin index query process

(2) 以太坊索引查询设计

以太坊的索引查询内容包括区块数据查询、账户状态数据查询等。以太坊数据全部存储于LevelDB中,但不同于表结构的数据库(表之间可以通过外键相关联),LevelDB各存储字段间没有关联,因此只能多次获取不同索引信息来找到需要的数据。如图14所示,查询流程如下:系统通过输入的参数获取对应的索引Value值,再将获取的索引值与参数组合成新的Key值,进一步获取想要的Value值。如果没有查询到结果,系统会通过此次查询获得的信息,重新组成新的Key值进行新一轮查询。

图14 以太坊索引查询流程Figure 14 Ethereum index query process

(3) Hyperledger Fabric索引查询设计

Fabric的区块与交易查询与比特币查询机制类似,都是依靠设计的区块、交易在文件系统中的索引信息进行查询。此外,Fabric中除了依据交易哈希值进行索引查询外,还增加了通过业务数据键值Key查询当前Key的状态信息以及历史状态信息。如图15所示,对于当前状态数据查询可以直接访问状态数据库,利用业务对象的Key值获取对应的Value值;对于历史状态数据查询,可以先在历史数据库中查询历史更改记录,获取Key所有历史状态数据相关的区块号与交易号,再利用索引数据库的信息获取相关文件位置定位到相关文件。

图15 Hyperledger Fabric索引查询流程Figure 15 Hyperledger Fabric index query process

(4) FISCO BCOS索引查询设计

FISCO BCOS查询内容与以太坊大致相同,包括区块、交易和状态数据查询。但FISCO BCOS系统可采用库表结构,在保留以太坊存储查询机制外,还可以利用传统关系表结构进行查询。这里仅基于FISCO BCOS表结构的内容,对其索引查询流程进行介绍。

如图16,以交易查询为例,在根据交易哈希查询交易详情时,先要访问到系统中的信息汇总表,汇总表里包含所有表名以及表所包含的字段名,通过汇总表找到相关索引信息表,获取交易所在区块的信息以及区块的索引信息,通过区块索引信息得到区块详情,通过交易索引信息便可以查询到交易详情。

图16 FISCO BCOS索引查询流程Figure 16 FISCO BCOS index query process

在典型区块链中,支持的查询处理机制普遍单一。尽管SPV查询处理机制设计巧妙,效率较高,但因其只能验证交易是否存在链上,应用场景十分有限。另外,当系统存在过多SPV轻节点,也会增加通信开销。基于当前块链式存储结构的性能缺陷,很难支撑更复杂的查询,目前典型区块链大多仍以设置相关索引数据来提高查询效率和丰富查询功能。

4 典型区块链的存储与查询主要问题

目前区块链在非金融领域的应用仍以存证、溯源为主,这两类应用与链上存储及查询联系紧密。本节对四种典型区块链系统存储和查询技术中存在的主要问题进行剖析,这些问题也是当前限制区块链大规模应用的瓶颈。

(1) 存储信息爆炸

节点账本的全备份是区块链在完全去中心化条件下保持一致性的需要。这种多节点高冗余机制一方面给区块链带来了及时共享、及时更新、全网数据保持一致的优点,同时也带来了节点存储爆炸的问题。这一问题在比特币、以太坊等公有链中尤其明显,除需要在各全节点完全备份一份相同区块数据外,为提高节点链上内容的查询效率,还存储了状态数据、索引数据等信息,因此节点存储的资源消耗大。由于区块链系统中的数据只添加而不删除,运行时间越长,各节点更加不堪重负。

比特币全局共享保持一致的就是全网一致的所有用户的UTXO记录,由于比特币的应用仅仅是简单转账交易,所以UTXO记录也较短。比特币主要采用Merkle树来压缩账本存储量,其全节点和轻节点的分类以及与轻节点配合的SPV查询机制等也都是为了减少冗余。

以太坊面向的应用较比特币复杂很多。为了压缩节点存储,提出了世界状态树、收据树、账户存储树、交易树等不同内容树。同时为了节约存储空间,提高查询效率,对Merkle树进行改进提出了MPT树。此外,在四类树中,需要以太坊网络全局共享,保持一致的只有世界状态,因此在世界状态树的更新中采用合并、关联其他树的信息以及综合bloom filter等多种技术,力求存储信息量小的同时方便快速查询,并保证全局一致。

私有链与联盟链对完全去中心化要求进行了弱化,其中私有链中心化程度更强,一般用于一个单位内部,其技术与联盟链类似。目前联盟链是面向非金融应用的主要区块链技术。联盟链在各联盟单位之间协同工作,属于半中心化结构。严格全局一致性的要求较公有链有所降低,且联盟全节点一般由存储处理能力较高的服务器担任,在一定程度上可以缓解节点存储爆炸及查询压力。FISCO BCOS引入了分布式存储后,节点可将数据存储在远端分布式系统[33]。这样对节点存储高冗余的情况有一定的缓解,但平台对于一些设计的完成度较低,仍存在许多需要完善的地方。

(2) 链上信息查询能力

以上述四种典型区块链系统为代表的绝大多数区块链系统仍是块链式结构。块链式结构的优点是通过哈希链可以有效防止篡改,但突出问题也正是由于哈希链导致倒查追溯效率低。

比特币SPV 机制和Merkle树结构的设计为了降低杂凑计算量、提高查询效率。以太坊的查询通过不同树的划分尽量提高查询效率,且通过不断组合Key进行查询,以弥补系统缺少关系查询的缺点。

在四类区块链系统中,基本都用LevelDB这种面向内容查询的非结构化数据库。LevelDB是谷歌的开源项目,处理Key-Value类型的数据,数据处理规模高达10亿级别,具有持久性存储、写性能远超读性能等特点[28]。上述性能正好符合区块链的全局数据量大、存储时间长、增加交易需求远远高于查询交易等特点。比特币和以太坊的上述特点最为明显,因此主要采用LevelDB。

除了上述优点,以块链结构和LevelDB来存储区块链的系统普遍存在查询丰富性低以及保存的数据字段量以及类型较少的缺点,无法有效支持复杂场景的数据处理,难以扩大应用领域范围。

由于联盟链的半去中心化特征以及其多种应用场景的需要,为了提高查询效率,开始使用其他数据库对上述存储系统进行补充。Fabric引入了CouchDB,可以支持Jason格式数据,实现多样的查询。FISCO BCOS引入RocksDB,支持多线程处理,性能相比于LevelDB更高。此外,FISCO BCOS还支持MySQL等关系型数据存储引擎,能提供更加复杂的查询功能。但总体来说,链上链下多种数据库存储内容的划分、关联及交互仍然存在诸多研究及实践问题。

5 区块链的存储与查询优化方法

实际上,区块链的链上信息存储爆炸及查询效率问题不仅是企业、开源社区关注的重点,也一直是学术研究的热点。

5.1 存储优化方法

5.1.1区块内容剪裁的存储优化方法 为解决区块链存储过程中的节点存储压力过大问题,有学者提出对区块数据进行剪裁的存储优化方法。在区块链账本中,部分数据过于久远,使用频次极少,在链上的存储意义低,通过对部分历史、低频使用的数据删除,同时将删除操作作为一条交易记录上链,可以释放磁盘空间,达到降低节点存储压力的目的。

早在Bitcoin-core中就针对比特币区块数据存储容量问题设计了一种区块数据的修剪策略。在系统中的区块数据构建完UTXO集合后,便可以将历史交易裁剪丢弃,以节省节点的本地存储空间,其本质是就是删除旧数据[34]。在以太坊中,状态数据树存储所有账户的状态数据,生成区块时,状态树通过修改分支节点获得新的状态树,而之前的节点仍然保留,系统保存状态树的所有历史数据,增加了存储压力。因此,Buterin提出对以太坊的状态树中的数据进行修剪。在区块生成后,系统使用“引用计数”技术来跟踪记录系统中状态树节点的变化,对于从状态树中退出的节点,将其在数据库存储的数据永久性删除[35]。微众银行在设计FISCO BCOS的数据仓库组件中提出冷热数据分离思想。区块链数据按照使用频率可分为冷数据和热数据,冷数据的使用频率低于热数据的使用频率,将热数据存储在链上,冷数据存储在链下低成本的硬件设备上,以此节约链上存储空间[36]。另外,数据仓库组件设计了数据调度层,以实现对冷数据和热数据的灵活访问。KokorisE等[37]在构建OmniLedger中提出通过集体签名状态块对区块数据进行修剪的方案,以达到节省存储空间,并且减少新节点初始化时间的目的。

表3 区块链存储查询优化方法Table 3 Blockchain storage query optimization methods

5.1.2基于分片技术的区块链存储优化方法 分片是一种传统的数据库技术,它将数据从大型数据库中分离出来,存储在不同的数据服务器中,每个服务器只需要管理部分数据,以此缓解数据处理和存储的压力。区块链分片技术是将拥有许多节点的区块链网络划分成多个小组,每个小组内的节点组成一个独立的区块链,也就是一个分片。系统中的交易被分配到各个分片中,节点只处理所在的分片内的交易,整个区块链系统可以并行处理多笔不同的交易。在基于分片技术的区块链中,单一节点无须处理与存储全部的交易数据,整个区块链的处理能力也不会受限于全网中的某一节点的计算能力[69]。根据分片技术的实现方式分为网络分片、交易分片和状态分片。

区块链分片技术最早是Luu等[43]提出的分片协议Elastico,网络中的每个节点基于PoW计算决定节点分配到不同委员会(即分片)。当交易提交到系统时,系统依据交易发送者的地址计算将交易分配到不同的委员会中执行,每个委员会在片内通过PBFT共识机制处理交易数据,并将达成共识的数据提交到通过随机选择得到的最终委员会节点。在区块链系统中,Zamani等[38]提出了一个RapidChain分片方案,RapidChain建立在Elastico的分片协议基础上,每个分片只存储区块链的部分数据,不同分片间定期相互验证新的交易,从而达成片间共识,减少了数据冗余。Jia等[39]基于区块链的存储容量受网络中存储空间最小的节点影响这一思路,提出了ElasticChain模型,该模型对区块链数据进行划分,将划分后的数据按特定的比例存储在部分节点。模型还基于数据可检索性证明(proofs of retrievability, POR)对存储数据的节点进行实时检测,通过检测节点稳定性值来选择哪些节点存储新数据,以提高数据存储稳定性。Raman等[40]将Shamir秘密共享等密码算法与分布式存储相结合设计了一个片间分发交易数据的编码方案,使得每个节点只存储单笔交易的部分数据,从而降低存储成本。与其他方法相比,该方法在节省存储资源的同时能进一步增强数据的完整性。

5.1.3链上存储结构的优化方法 链上数据的存储系统直接影响链上数据的存储效能。Dinh等[41]提出了通用的链上分布式数据存储系统,称为UStore。链上存储结构基于类似Git(一种流行的源代码版本控制系统)的数据结构进行构建,同时综合了许多分布式系统和数据库的特点进行改进。Ustore比一般键值存储系统有更好的性能和丰富的查询功能。Wang等[42]基于对Ustore存储系统的改良而设计了Forkbase存储引擎,可以存储数据的多个版本,每个版本有唯一标识数据内容及历史。另外,ForkBase在存储结构中引入了面向模式的分裂树结构(pattern-oriented-split tree, POS-Tree),能高效确定并消除重复数据,以此降低系统中的数据冗余。

5.1.4基于链下存储支持的优化方法 在实际应用中,结合链下存储系统辅助存储是最常见的区块链存储优化方法。其基本思想是将部分数据转移到链下数据库存储,链上仅保存少量关键信息以及链下数据的存储位置索引信息。在访问数据时,通过获取存储在链上的链下位置索引信息,在链下数据库查找到相应内容。该方法利用链下存储系统空间大、存取效率高等特点来分担链上数据存储压力。根据结合的链下存储系统不同,大致分为以下三种方案类型。

(1) 结合链下云存储

为了处理大规模数据,很多区块链应用方案选择云存储作为链下存储系统[44-46]。在这些区块链应用系统中,完整的原数据一般存储在云服务器上,而链上只存储原数据的唯一标识以及哈希值等信息。在云上获取到的数据可以在链下做哈希计算,计算的哈希值与链上值的哈希进行对比验证,验证云上的数据是否完整,既降低了链上数据存储开销又保证了数据的完整性。He等[47 ]对此只将最近一周的区块数据保留在链上,其他区块数据存储到云上,在云上存储历史区块数据中最新区块的散列值会存放在链上,以保持链上链下数据一致性。

(2) 结合IPFS的存储

星际文件系统(inter planetary file system, IPFS)是一个基于内容寻址的P2P文件系统[70]。当文件上传到IPFS后,系统会自动将文件分段并加密分散存储。同时IPFS是基于内容寻址的存储系统,能够自动消除重复文件,保证存储在IPFS上数据的安全性和高效性。目前很多相关区块链应用将IPFS作为链下存储系统,以扩展系统的存储容量。原始数据存在IPFS后会返回对应的IPFS地址,IPFS地址和原数据的标识一起存储在链上,从而扩展现有区块链应用系统的数据存储能力[48-51]。Zheng等[52]针对比特币系统对存储空间的需求提出了使用IPFS存储交易数据,区块链系统中的交易数据会存储到IPFS中,IPFS会返回交易在IPFS中的地址,地址信息会被打包到区块中,这样就减少了区块存储信息,节省了链上存储空间。Norvill等[53]针对区块链系统中不再使用的智能合约代码仍存储在链上占用空间的情况,设计了将以太坊智能合约代码存储在IPFS上的方案。链上只保留合约代码在IPFS中的地址,以减少链上不必要的存储消耗。除此以外,类似系统还有Sia[71]、Storj[72]等。

(3) 基于DHT协议的分布式存储

分布式哈希表(distributed hash table, DHT)是一种基于哈希算法实现分布式存储的技术[73]。在DHT网络中基于哈希算法,数据分配存储的节点位置具有随机性,确保了各节点存储数据的均衡性。赖业宁等[54]基于DHT的可拓展分布式存储来解决区块链存储伸缩性受限的问题,提出了基于区块链和DHT技术的电网安全稳定控制终端分布式认证方案,使得经过共识的认证数据能分布式存储在特定终端中,而非完整地备份在每个终端上,能够实现准确高效地按需查询,进而在不影响认证实时性的同时,保障认证安全性,并提高数据存储效率。Ali等[55]为全球端到端互联网性能测量项目(ping end-to-end reporting, PingER)设计了一个基于区块链的数据存储和访问框架,以消除其对集中式存储库的完全依赖。在框架中,文件的元数据存储在区块链上,而实际文件则通过DHT协议存储在链下,使用PingER监控代理的对等网络节点在多个位置为PingER框架提供分散的存储、分布式处理和高效的查找功能。

5.2 区块链查询优化方法

5.2.1改进链上数据结构的查询优化方法 这类查询优化方法主要通过改进区块数据结构来优化查询路径,提高查询效率。例如贾大宇等[56]结合平衡二叉树与Merkle树的特点,提出一种新的存储结构,能有效提高链上每个区块内的局部查询效率,同时使得系统支持范围查询。张学旺等[57]针对区块链SPV轻节点中查询验证信息占用过多存储资源的问题,引入Merkle山脉(merkle mountain range, MMR),设计了一种高效的数据可信验证查询方法,可动态追加数据,既节省了SPV轻节点中的存储资源,还提高了查询验证的效率。此外,Xu等[58]提出了一种基于累加器的认证数据结构,引入两个新索引来聚合块内和块间数据记录,对任意查询属性进行动态聚合,以实现高效的查询验证。此外,郑浩瀚等[59]将链上数据根据属性进行分类,将Merkle树与布隆过滤器以及B+树等多种索引结构结合创立了一种新的索引结构,使得系统能依靠数据属性快速索引查询。

5.2.2基于多链的查询优化方法 传统区块链系统中通常是单链结构,随着业务增多、节点增加,通信量会变得非常大,导致单链结构的区块链访问性能低。这类方法通过引入多链结构,来减轻链上数据查询压力,以提高查询效率。例如,蔡维德等[60]基于多链的思想构建了一种双链模型,该模型按照存储内容分为账户链和交易链,账户链存储着账户信息和交易后的信息,主要负责查询、保存账目;交易链用来存储对交易有用的信息并执行相关交易。采用双链架构使得整体系统能进行并发处理交易,交易处理与查询的速度大幅提升。尤瑶等[61]利用多链结构设计了一种混合索引机制,即在账户的交易中增加指向该账户在前一个交易所在块的指针,通过指针可以快速跟踪账户交易形成跟踪链,以提高账户历史交易的查询效率。Xing等[62]利用多链结构针对跟踪链进行优化,设计了基于子链的账户交易链索引结构,将账户交易链划分为子链,每个子链的最后一个块由一个散列指针连接,该结构将跟踪链中的逐块查询模式转换为子链逐子链的查询模式,缩短了查询路径,从而提高了查询效率。

5.2.3基于外联数据库的查询优化方法 如前文所述,与链下数据库结合是目前存储优化的方法,同时也是主要的查询优化方法。数据库系统发展较早,有成熟的数据管理体系,利用数据库具有高效查询能力,通过链上链下协同,可有效提高链上数据的查询效率。Li等[63]基于以太坊提出EtherQL模型,该模型利用同步管理器实时同步来自以太坊的区块数据,并将其存储在链下MongoDB数据库中。通过构建链下查询层,利用MongDB实现分析查询操作,以此实现对区块中数据的方位查询和范围查询等更高级的查询功能。为防止外联数据库中的数据被篡改,余涛等[64]将Fabric与MySQL结合设计了FabricSQL,将Fabric的区块数据实时同步到外部MySQL中,利用MySQL提供更为丰富的查询功能。FabricSQL还设计了相关验证机制,结合加盐的加密方法,当链上数据按顺序存到链下数据库时,引用区块链中哈希链的结构对存储数据处理,以防止链下数据被篡改,用户访问时会对其进行数据的计算验证,确保链下数据存储安全。Mcconaghy等[65]提出的BigChainDB就是以分布式数据库系统为基础增加区块链特性,扩展数据存储查询能力,保留了分布式数据库存储容量大、数据传输延迟低以及查询功能丰富多样等特征,且无须进行数据全复制。焦通等[66]在此基础上,针对链上交易内的数据字段无法直接查询的情况,提出一种基于哈希指针的不可篡改索引,根据该索引快速检索区块内数据,从而能够查询链上数据的具体细节。

类似的还有ChainSQL[67]、TrustSQL[68]等都是利用区块链不可篡改的特性与传统SQL数据库结合。

6 区块链存储与查询技术展望

区块链存储与查询效能问题制约着区块链应用的发展,因此成为研究热点,实际上存储与查询技术是不可分割的,本文认为主要有以下研究问题。

(1) 协同处理的挑战

区块数据全备份的机制所造成的节点存储资源的浪费以及节点信息的爆炸是区块链面临的重要难题。这使得区块链系统难以存储较大数据,更难以保障区块链网络长期运行效率。合理降低区块链节点备份的数据量,是必须要考虑的问题。把区块链网络节点分成区域,每个区域的节点仅需要维护该区域的数据,备份存储该区域节点的所有数据可以有效降低区块链节点的备份数据量,有效提升区块链性能。分片[38-40]、多链[60-62]正是这种发展思路的代表。这类处理思路跟网络分区域治理的思想类似,分片、多链以及链上链下结合都在任务划分、负载均衡、域间同步、域间通信及域间共识等协同机制上存在众多挑战。

(2) 新型区块体系结构的挑战

即便有上文所述的各种对区块链链上存储方式及数据结构的改进,但传统块链式结构始终存在难以完全解决的链上数据爆炸问题。突破瓶颈,找到除块链式结构外更有效的区块网络体系结构及区块结构也一直是大家关注的焦点问题。例如基于有向无环图(directed acyclic graph, DAG)技术的DAG型区块链以及分区型区块链等。这些方法试图通过改变区块链网络的体系结构来根本上解决传统区块链存储与查询问题。DAG区块链不再采用链式结构而采用图的结构,每笔交易就是一个区块,每一笔交易都可以连接到多个先前的交易,所有交易区块相互连接最终形成图状结构[74]。DAG型区块链可以同时处理多笔交易,支持并行计算,具有更高的交易处理效率,数据的存储效率也更高。分区型区块链通过分区机制将节点分为多个不同小组,以此分成多个分区的区块链,系统中的通信资源、计算资源、存储资源也随之划分,使得每个分区的区块链并行运行[75]。分区型区块链的可伸缩性较强,当分区数量增多时,整个区块链系统的吞吐率以及存储容量都将呈线性增长,它比传统区块链系统更适合具有高吞吐率和高存储容量需求的场景[76]。目前,具有代表性的分区型区块链包括Zilliqa[77]、OmniLedger[37]等,但是限于这些新型区块链还处于刚起步阶段,并且设计的结构较为复杂,在去中心化程度、系统安全性等方面都尚待改进与发展。

(3) 读写均衡的挑战

当前典型区块链的底层数据存储系统还是以键值数据库以及二进制文件存储为主,结构简单,只能通过哈希值查询相关交易。对于查询的优化研究大多仍是通过借用外部数据库辅助查询,未真正解决区块链存储系统查询效率低下、查询功能单一的问题。此外,维护底层存储系统的读写速度均衡也是业内一直关注与研究的方向。最初区块链仅作为数字交易的分布式账本,记账是其主要功能,其写入数据的情况远高于查询数据情况,所以用到的底层数据库存储系统如LevelDB拥有较高的写性能。而当前存证、溯源等已经成为区块链应用最多、落地最广的场景。因此,在区块链底层数据存储系统方面需要开发及研究人员做进一步优化调整。目前,区块链底层存储系统需更多向读写效率均衡的方向发展,设计更合理、更适用目前主流业务场景的区块链底层存储系统。如何设计兼顾读写均衡的数据结构,特别是高效的索引结构也是未来研究的方向。

7 总结

区块链作为一种去中心化的数据记录账本,其存储与查询是支撑区块链系统应用的核心技术。本文重点分析了比特币、以太坊、Hyperledger Fabric以及FISCO BCOS四类典型区块链系统的数据存储及查询方法,对现有区块链存储及查询研究的相关优化方法进行了归纳总结,并对相关存储和查询技术的研究问题进行了展望。作为一项新兴技术,区块链技术及其应用发展变化很快。实际上,区块链存储与查询技术的改进均属于对区块链体系结构的研究,分片、多链等技术产生了各种协同处理问题。此外,作为一种新型的分布式数据管理系统,从比特币的重点关注写操作,日益发展到兼顾读写均衡。可以看到,从公有链到联盟链,区块链体系结构根据应用场景及范围的变化而不断变化,区块链的存储与查询技术会随着区块链技术应用的推进而不断产生更多新方法。

猜你喜欢
以太存储系统哈希
基于特征选择的局部敏感哈希位选择算法
哈希值处理 功能全面更易用
分布式存储系统在企业档案管理中的应用
文件哈希值处理一条龙
基于活跃节点库的以太坊加密流量识别方法
以太万物理论概述
天河超算存储系统在美创佳绩
车易链:做汽车业的“以太坊”
巧用哈希数值传递文件
A Study on the Contract Research Organization