引言
随着区块链技术的日趋成熟,更多企业开始探索区块链的实际使用场景。HyperLedger Fabric(下称Fabric),由Apache社区开发的开源的,企业级的,带权限的分布式账本平台,被广泛应用于学术研究和企业应用领域。其查询技术是使用和开发Fabric不可或缺的一项功能模块,但由于区块链技术的去中心化特性,其查询机制的设计和常规分布式系统存在较大差异,并且存在一定的技术理解门槛。目前官方文档或相关资料对查询章节的描述通常与其它技术(如系统部署,更新等)一同描述,没有单独对查询进行描述,或缺乏原理层面的系统描述,难以理解和运用。本文较为详细的描述Fabric查询的设计原理,可作为生产和开发中系统设计的参考依据。
文章分为4个部分。首先介绍于查询相关的Fabric基础名词概念,接着介绍Fabric的经历的各查询过程以及查询对象的存储结构,最后通过描述区块链的系统结构以描述Fabric的一种特殊查询机制——跨链查询。
基本概念[1]
- 节点(Peer):一个维护一个账本的网络实体。节点会运行链码容器以实现对账本的读写操作。节点由Fabric内的成员持有和维护。
- 通道(Channel):在Fabric中,通道是私有区块链,可实现数据隔离和保证机密性。部署在一个通道内的账本由通道中的所有节点之间共享,并且交易方必须通过通道进行身份验证才能与通道内节点进行交互。
- 链码(Chaincode):在Fabric中,链码即智能合约。一个链码就是由客户端应用程序调用的代码,它可以通过事务(Transaction)改变通道的状态。在Fabric中,用户不能直接访问通道,只能通过链码改变通道的状态。
- 组织(Organization):节点以组织的身份加入通道,一个组织可以有一个或多个节点。
查询过程
在Fabric中,查询过程涉及区块链五层协议[2]中的应用层,合约层和存储层。其查询过程如图所示。当用户需要执行查询操作时,首先在合约层编写用户链码,一份完整的用户链码应包含对多个对事务的读写函数,每个读写函数由判断逻辑和系统链码组成。系统链码由Fabric封装了更改通道记录的函数,包括处理事务的验证链码(VSCC)和查询事务的查询系统链码(QSCC)。对于查询系统链码,截止2.2版本,Fabric已经实现了K-V查询,范围查询和溯源查询三种基本功能,以及区块链中特有的跨链码查询和跨通道查询功能。由用户编写的用户链码会被分别部署在Fabric的各个节点上,并向节点上的更下一层存储层查询用户请求数据。当链码部署完毕后,查询者可以通过调用RESTAPI以HTTP协议方式向节点请求调用链码,或者可以将RESTAPI封装为基于去中心化的存储的应用程序。
查询对象
如图所示,我们可以查询对象分解为文件系统的数据库两层架构。文件系统记录以区块的链式结构记录数据的存储信息,每个区块包含记录当前区块信息的区块头和元数据,以及若干事务组成的区块体。为了加速查询或实现特定查询功能,Fabric将区块信息分类提取存储在KV数据库中。目前,Fabric支持LevelDB [3]和CouchDB [4]两种数据库。
- 状态数据库:维护最新的KV状态,这些状态会根据最新的区块事物进行修改。状态数据库支持基于键的查询,组合键值对查询和键范围查询。
- 键历史索引:记录键的值历史变更状态,用于溯源查询。
- 块索引:存储块对应的Hash值和块在文件系统中的位置;存储块编号与其在文件系统中的位置;存储事务ID与其在文件系统中的位置。通过以上三种方式实现对区块和事务的快速定位。
特殊查询机制
在实际运用中可能出现不同业务的交叉应用场景,对于传统分布式系统而言,这代表单次查询可能设计多个数据库的交互。由于Fabric采用账本的形式记录数据,并且应用与账本的交互通过链码实现,跨数据库查询在Fabric中转变为跨链码查询。为了更好的理解链码间的交互查询机制,我们需要先了解Fabric中链码,组织,信道和节点的关系。下图展示了查询角度下,Fabric中各模块的简化交互方式。
模块交互遵守以下规则:
- 链码部署在节点上,且只有已部署链码节点才能请求读写通道数据。
- 节点以组织的形式加入通道,一个节点只能加入一个组织,但一个组织可以同时加入多个通道。
- 每个通道中相同的链码共同维护一份完整的的交易状态视图,不同链码之间信息不共享,不同通道之间的链码信息不共享。
基于上述规则,Fabric的跨链码和跨通道通信需要由节点完成。在节点部署的用户链码中通过调用系统链码实现跨链码调用。在同一节点上,若部署了同通道内的链码(如Peer3在Channel1的Chaincode1和Chaincode2),Fabric允许直接在用户链码中调用和修改目标链码维护的视图。若链码处于不同通道中(如Peer3在Channel1的Chaincode1和在Channel2的Chaincode2),若当前节点所在组织同时加入了链码所在通道,并且部署了需要跨通道交互的的链码,Fabric虽然也提供跨链码调用,但只能返回调用结果,不能对调用目标进行更改。
参考文献
[1] Hyperledger Fabric [G/OL] https://hyperledger-fabric.readthedocs.io/en/latest/glossary.html
[2] 袁勇, 王飞跃. 区块链技术发展现状与展望.[J] 自动化学报 42.4 (2016): 481-494
[3] LevelDB [G/OL] https://github.com/google/leveldb
[4] CouchDB [G/OL] https://couchdb.apache.org/