会员体验
专利管家(专利管理)
工作空间(专利管理)
风险监控(情报监控)
数据分析(专利分析)
侵权分析(诉讼无效)
联系我们
交流群
官方交流:
QQ群: 891211   
微信请扫码    >>>
现在联系顾问~
首页 / 专利库 / 分布式账本技术 / 使用分布式账本技术的关系数据管理和组织

使用分布式账本技术的关系数据管理和组织

申请号 CN202080015222.4 申请日 2020-08-19 公开(公告)号 CN113454619A 公开(公告)日 2021-09-28
申请人 DLT全球公司; 发明人 尼拉伊·斯里瓦斯塔瓦;
摘要 描述了智能合约和链下工具二者的集合,其使得能够进行数据的管理和组织,以便使得能够根据关系数据库原则将该数据存储在分布式账本中。跨分布式账本平台规范加上可重用的核心组件一起创建可以在分布式账本平台上实施以使得能够向/从由关系原则掌管的分布式账本存储和检索数据的系统。该系统的实现使得能够向添加系统链码并且使用被表示为JSON的模式和数据。在使用中,用户可以创建、更新和查询来自代码、控制台或智能合约的数据,其中每个更新是分布式账本交易。
权利要求

1.一种利用关系数据库管理查询来查询实施包括交易数据的分布式账本的分布式账本平台的方法,所述方法包括:

使用所述分布式账本平台的至少一个处理器来创建所述分布式账本上的数据库,并且记录关于所述分布式账本上的所述数据库的信息;

使用所述至少一个处理器将所接收到的关系数据库管理查询转换成能够由所述分布式账本上的所述数据库处理的查询操作;

使用所述至少一个处理器对所述分布式账本上的所述数据库执行所述查询操作以生成查询结果;以及

使用所述至少一个处理器将所述查询结果以能够由所述分布式账本上的所述数据库处理以便包括在所述分布式账本上的形式记录至所述分布式账本上的所述数据库。

2.根据权利要求1所述的方法,还包括:使用所述至少一个处理器将所述关系数据库管理查询生成为来自以下中的一个的结构化查询语言(SQL)查询:(1)来自用户、经由用户接口;(2)来自用户应用、经由应用程序接口;以及(3)来自智能合约。

3.根据权利要求2所述的方法,其中,所述智能合约执行所述分布式账本上的所述数据库的关系数据库管理查询的SQL查询的至少子集。

4.根据权利要求2所述的方法,还包括:使用所述至少一个处理器将所述SQL查询解析成包括SQL数据操纵语言(SQL DML)写操作、SQL DML读操作和SQL数据定义语言(SQL DDL)操作中的一个的SQL操作;以及创建所述SQL操作和所述SQL操作中包括的任何关系数据的JavaScript对象记号(JSON)表示。

5.根据权利要求4所述的方法,还包括:使用所述至少一个处理器确定因所述SQL操作的执行而导致的交易是否在平台相关程度上已朝着接受至所述分布式账本中进展。

6.根据权利要求5所述的方法,还包括:使用所述至少一个处理器在DML写操作结束时添加操作广播状态(OPSTAT)指令以获取对应交易的更明确的状态。

7.根据权利要求4所述的方法,其中,对所述分布式账本执行所述查询操作包括:使用所述至少一个处理器确认调用所述SQL查询的实体具有执行所述SQL操作的权限。

8.根据权利要求4所述的方法,其中,对所述分布式账本执行所述SQL查询操作包括:使用所述至少一个处理器创建能够被处理并存储在所述分布式账本上的所述查询操作和所述查询操作的结果的JSON表示。

9.根据权利要求8所述的方法,其中,所述SQL操作是SQL DML写操作,所述方法还包括:使用所述至少一个处理器从所述分布式账本检索执行所述SQL DML写操作所需的数据;使用所述至少一个处理器执行包括检索到的数据的所述SQL DML写操作;使用所述至少一个处理器准备所述查询结果中的任何新的或更新的记录的JSON表示;以及使用所述至少一个处理器将所述SQL DML写操作和任何更新的记录以能够由所述分布式账本上的所述数据库处理以便包括在所述分布式账本上的形式提交至所述分布式账本。

10.根据权利要求9所述的方法,还包括:使用所述至少一个处理器监视所述分布式账本以获得所述SQL DML写操作朝着接受至所述分布式账本中的进展;以及使用所述至少一个处理器通知调用所述SQL查询的实体所述SQL DML写操作是否在平台相关程度上作出了这样的进展。

11.根据权利要求8所述的方法,其中,所述SQL操作是SQL DML读操作,所述方法还包括:使用所述至少一个处理器从所述分布式账本检索执行所述SQL DML读操作所需的数据;

使用所述至少一个处理器执行包括检索到的数据的所述SQL DML读操作;使用所述至少一个处理器准备所述查询结果的JSON表示;以及使用所述至少一个处理器将所述查询结果的JSON表示以能够由所述分布式账本上的所述数据库处理以便包括在所述分布式账本上的形式记录至所述分布式账本。

12.根据权利要求11所述的方法,还包括:使用所述至少一个处理器将所述查询结果的JSON表示返回至调用所述SQL查询的实体。

13.根据权利要求1所述的方法,还包括:使用所述至少一个处理器通过执行配置交易和常规交易创建所述分布式账本内的所述数据库,所述配置交易创建通道并且限定哪些对等计算机将维护所述数据库的拷贝,所述常规交易写入关于所述数据库的元数据;以及使用所述至少一个处理器创建限定所述分布式账本中的交易数据和用于修改所述交易数据的交易指令的代码。

14.根据权利要求13所述的方法,还包括:使用所述至少一个处理器创建限定作为所述分布式账本中的所述交易数据的按JavaScript对象记号(JSON)的所述数据库的属性的代码;以及使用所述至少一个处理器使所述数据库用所述数据库属性更新。

15.根据权利要求1所述的方法,还包括:使用所述至少一个处理器创建考虑了能够由所述分布式账本上的所述数据库处理以便包括在所述分布式账本上的形式的经解析和翻译的结构化查询语言(SQL)查询。

16.根据权利要求1所述的方法,其中,所述关系数据库管理查询从智能合约接收,所接收到的关系数据库管理查询被转换成能够由所述分布式账本上的所述数据库处理的分布式账本交易,并且所述分布式账本上的所述分布式账本交易被执行以生成交易结果,所述方法还包括:

使用所述至少一个处理器将所述交易结果返回至所述智能合约。

17.根据权利要求16所述的方法,还包括:将所述智能合约与所述分布式账本上的所述数据库集成,由此,所述智能合约执行所述分布式账本的数据定义语言(DDL)操作,其不包括DDL数据库操作和模式改变。

18.根据权利要求17所述的方法,还包括:在所述分布式账本上以链码实施所述数据库的数据库相关操作,所述链码限定所述智能合约的至少一个资产和用于修改所述至少一个资产的至少一个交易指令。

19.根据权利要求18所述的方法,其中,将所述智能合约与所述分布式账本上的所述数据库集成包括所述智能合约调用所述链码。

20.根据权利要求18所述的方法,还包括:所述智能合约根据所述链码启动数据操纵语言(DML)读操作。

21.根据权利要求16所述的方法,还包括:所述智能合约执行至少一个操作,所述至少一个操作包括:执行数据操纵语言(DML)查询;创建所述分布式账本上的所述数据库;更新对所述分布式账本上的所述数据库的访问权;或者执行数据定义语言(DDL)查询。

22.一种系统,包括:

分布式账本平台,所述分布式账本平台实施包括交易数据的分布式账本;

所述分布式账本上的数据库;以及

至少一个处理器,所述至少一个处理器执行用以实施执行多个操作的关系数据管理和组织系统的指令,所述多个操作包括:记录关于所述分布式账本上的所述数据库的信息;

将所接收到的关系数据库管理查询转换成能够由所述分布式账本上的所述数据库处理的查询操作;

对所述分布式账本上的所述数据库执行所述查询操作以生成查询结果;以及将所述查询结果以能够由所述分布式账本上的所述数据库处理以便包括在所述分布式账本上的形式记录至所述分布式账本上的所述数据库。

23.根据权利要求22所述的系统,还包括用于将所述关系数据库管理查询生成为结构化查询语言(SQL)查询的装置,包括以下中的一个:(1)至所述关系数据管理和组织系统的用户接口,用户通过所述用户接口提供所述SQL查询;(2)将所述SQL查询经由至所述关系数据管理和组织系统的应用程序接口传递至所述关系数据管理和组织系统的用户应用;以及(3)智能合约。

24.根据权利要求23所述的系统,其中,所述智能合约执行所述分布式账本上的所述数据库的关系数据库管理查询的SQL查询的至少子集。

25.根据权利要求23所述的系统,其中,所述至少一个处理器还执行如下指令,所述指令用以:将所述SQL查询解析成包括数据操纵语言(SQL DML)写操作、SQL DML读操作和SQL数据定义语言(SQL DDL)操作中的一个的SQL操作;以及创建所述SQL操作和所述SQL操作中包括的任何关系数据的JavaScript对象记号(JSON)表示。

26.根据权利要求25所述的系统,其中,所述至少一个处理器还执行如下指令,所述指令用以:确定因所述SQL操作的执行而导致的交易是否在平台相关程度上已朝着接受至所述分布式账本中进展。

27.根据权利要求26所述的系统,其中,所述至少一个处理器还执行如下指令,所述指令用以:在DML写操作结束时添加操作广播状态(OPSTAT)指令以获取对应交易的更明确的状态。

28.根据权利要求25所述的系统,其中,所述至少一个处理器通过执行用以确认调用所述SQL查询的实体具有执行所述SQL操作的权限的指令来对所述分布式账本执行所述查询操作。

29.根据权利要求25所述的系统,其中,所述至少一个处理器还执行如下指令,所述指令用以:创建能够被处理并存储在所述分布式账本上的所述查询操作和所述查询操作的结果的JSON表示。

30.根据权利要求29所述的系统,其中,所述SQL操作是SQL DML写操作,并且其中,所述至少一个处理器还执行如下指令,所述指令用以:从所述分布式账本检索执行所述SQL DML写操作所需的数据;执行包括检索到的数据的所述SQL DML写操作;准备所述查询结果中的任何新的或更新的记录的JSON表示;以及将所述SQL DML写操作和任何更新的记录以能够由所述分布式账本上的所述数据库处理以便包括在所述分布式账本上的形式提交至所述分布式账本。

31.根据权利要求30所述的系统,其中,所述至少一个处理器还执行如下指令,所述指令用以:监视所述分布式账本以获得所述SQL DML写操作朝着接受至所述分布式账本中的进展;以及通知调用所述SQL查询的实体所述SQL DML写操作是否在平台相关程度上作出了这样的进展。

32.根据权利要求29所述的系统,其中,所述SQL操作是SQL DML读操作,并且其中,所述至少一个处理器还执行如下指令,所述指令用以:从所述分布式账本检索执行所述SQL DML读操作所需的数据;执行包括检索到的数据的所述SQL DML读操作;准备所述查询结果的JSON表示;以及将所述查询结果的JSON表示以能够由所述分布式账本上的所述数据库处理以便包括在所述分布式账本上的形式记录至所述分布式账本。

33.根据权利要求32所述的系统,其中,所述至少一个处理器还执行用以将所述查询结果的JSON表示返回至调用所述SQL查询的实体的指令。

34.根据权利要求22所述的系统,其中,所述至少一个处理器执行如下指令,所述指令用以:通过执行配置交易和常规交易创建所述分布式账本内的所述数据库,所述配置交易创建通道并且限定哪些对等计算机将维护所述数据库的拷贝,所述常规交易写入关于所述数据库的元数据;以及创建限定所述分布式账本中的交易数据和用于修改所述交易数据的交易指令的代码。

35.根据权利要求34所述的系统,其中,所述至少一个处理器还执行如下指令,所述指令:对应于限定作为所述分布式账本中的所述交易数据的按JavaScript对象记号(JSON)的所述数据库的属性的代码;以及用以使所述数据库用所述数据库属性更新。

36.根据权利要求22所述的系统,其中,所述至少一个处理器还执行用以创建考虑了能够由所述分布式账本上的所述数据库处理以便包括在所述分布式账本上的形式的经解析和翻译的结构化查询语言(SQL)查询的指令。

37.根据权利要求22所述的系统,其中,所述关系数据库管理查询从智能合约接收,所接收到的关系数据库管理查询被转换成能够由所述分布式账本上的所述数据库处理的分布式账本交易,并且所述分布式账本上的所述分布式账本交易被执行以生成交易结果,所述系统还包括:所述至少一个处理器执行用以将所述交易结果返回至所述智能合约的指令。

38.根据权利要求37所述的系统,其中,所述智能合约执行所述分布式账本的数据定义语言(DDL)操作,其不包括DDL数据库操作和模式改变。

39.根据权利要求38所述的系统,其中,所述数据库的数据库相关操作在所述分布式账本上以链码实施,所述链码限定所述智能合约的至少一个资产和用于修改所述至少一个资产的至少一个交易指令。

40.根据权利要求39所述的系统,其中,所述智能合约调用所述链码以便执行。

41.根据权利要求39所述的系统,其中,所述智能合约根据所述链码启动数据操纵语言(DML)读操作。

42.根据权利要求37所述的系统,其中,所述智能合约执行至少一个操作,所述至少一个操作包括:执行数据操纵语言(DML)查询;创建所述分布式账本上的所述数据库;更新对所述分布式账本上的所述数据库的访问权;或者执行数据定义语言(DDL)查询。

43.根据权利要求42所述的系统,其中,所述智能合约通过执行配置交易和执行常规交易来创建所述分布式账本上的所述数据库,所述配置交易创建所述分布式账本的数据隔离并且限定哪些对等计算机将维护所述数据库的拷贝,所述常规交易写入关于所述数据库的元数据,所述至少一个处理器还执行如下指令,所述指令用以执行包括创建限定所述分布式账本上的交易数据和用于修改所述交易数据的交易指令的代码的操作。

说明书全文

使用分布式账本技术的关系数据管理和组织

技术领域

[0001] 本申请涉及数据的管理和组织以使得能够根据关系数据库原理向/从分布式账本存储和检索该数据。

背景技术

[0002] 原始的关系数据库系统是响应于20世纪60年代末计算的重大新发展而出现的。随着系统变得越来越大并且越来越复杂,变得清楚的是,新的且更新的程序需要与较旧的程
序创建的数据一起工作。现有系统使其变得困难,这是因为程序通常以其自身的方式来存
储数据。关系模型对存储和检索的重要方面进行了标准化,并且采用关系模型的使用者享
有一系列好处,包括更便宜的升级和减少的供应商锁定。
[0003] 相反地,那些仍然被计算机供应商引导到特定程序存储方法的使用者后期要承受更高的维护成本和更大的努力,特别是当有时最终做出迁移至关系数据库管理系统
(RDBMS)平台的决策延迟较长时。20世纪70年代,澳大利亚国防部持续数年的项目最终摆脱
了非关系霍尼韦尔事实语言(Honeywell Fact language)是对这些成本的证明。
[0004] 从那时起不时地,其他计算领域的进步使现有的关系数据库工具不兼容或不方便。例如,早期万维网的面向文件的性质导致许多项目回到关系数据库之前的低效时期,直
到实现并实践了网页到RDBMS后端的连接。类似地,面向对象编程的出现暂时地使程序员使
用关系数据模型表示数据变得不那么自然。封装在对象中的数据很难分解为RDBMS表。然
而,关系表示的优势足够显著,以至于现在对象关系映射(ORM)是其中仍然使用面向对象编
程的常用方法。
[0005] 另一方面,分布式账本技术(DLT)具有点燃和使得能够进行相当于本世纪信息技术革命的潜力。分布式账本技术正在处理和解决互联网的最大挑战和最令人困惑的挑战中
之一——缺乏信任。分布式账本技术是新兴但功能强大的分布式计算范例,并且是到目前
为止唯一具有通过使数据不可变以用于实际目的来为互联网带来信任的潜力的技术。不幸
的是,现有的RDBMS平台和工具与分布式账本技术的约束不兼容。因此,程序/数据锁定——
其中,数据密不可分地链接至程序——对于分布式账本上的智能合约来说比其对于20世纪
60年代的预关系数据库时代的程序更重要。期望下述系统和方法:通过该系统和方法,分布
式账本中的数据将仅被锁定至部署的智能合约的细节中,如果这是开发者的特定意图的
话。

发明内容

[0006] 本文描述的系统和方法通过提供使得能够在分布式账本上存储之前进行关系数据管理和组织的智能合约和链下工具二者的集合来解决本领域的需求,从而可以利用先前
存在的关于关系数据库的开发者知识,而无需牺牲分布式账本的益处。在示例实施方式中,
根据关系原则管理和组织数据,将数据存储在选择的分布式账本平台上并且使用开发者已
熟悉的编程语言诸如结构化查询语言(SQL)进行访问。结果为分布式账本上的高度安全且
可审核的关系数据库。此外,本文描述的系统和方法可以与智能合约一起使用,以使这些智
能合约的数据存储方面更易于处理。
[0007] 在示例实施方式中,跨分布式账本平台规范加上可重用的核心组件共同创建了可以在诸如 Fabric的通用分布式账本技术平台上实施并且从流行的编程平
台诸如 访问的关系数据管理和组织系统。关系数据管理和组织系统能够实现用
于添加系统链代码以与 Fabric一起使用的能力,并且使用表示为
JavaScript Object Notation(JSON)的模式和数据。此外,使用Fabric的世界状态数据库
用于数据存储,并且使用Fabric的身份提供者用于对例如包括创建数据库、授权用户访问
数据库、添加表和修改模式、写入数据和仅查询的五个级别的数据访问控制。在使用中,用
户可以创建、更新和查询来自代码、控制台或智能合约的表格,其中每个更新是分布式账本
交易。
[0008] 在示例实施方式中,提供了利用关系数据库管理查询来查询实施分布式账本的分布式账本平台的系统和方法,分布式账本包括分布式账本上的交易数据。该方法包括:创建
数据库并记录关于分布式账本上的数据库的信息;以及将所接收到的关系数据库管理查询
转换成可以由分布式账本平台处理的查询操作。执行对分布式账本平台的查询操作以生成
查询结果,并且将该查询结果以可以由分布式账本平台处理以便包括在分布式账本上的形
式记录至分布式账本平台。在示例实施方式中,通过以下步骤生成关系数据库管理查询:
(1)从用户经由用户接口接收结构化查询语言(SQL)查询;(2)从用户应用经由应用程序接
口接收SQL查询;(3)执行SQL查询的智能合约。
[0009] 在示例实施方式中,关系数据管理和组织系统适于将SQL查询解析成可以为以下中的一个的SQL操作:数据操纵语言(DML)写操作;DML读操作;以及数据定义语言(DDL)操
作。创建SQL操作和SQL操作中包括的任何关系数据的JavaScript对象记号(JSON)表示以供
分布式账本平台处理。
[0010] 在其他示例实施方式中,因SQL操作的执行而导致的交易是否在平台相关程度上已朝着接受至分布式账本中进展是通过例如在DML写操作结束时添加操作广播状态
(OPSTAT)指令以获取对应交易的更明确的状态来确定的。执行对分布式账本平台的查询操
作还可以包括确认调用SQL查询的实体具有执行所请求的SQL操作的权限。执行对分布式账
本平台的查询操作还可以包括创建查询操作,其可以由分布式账本平台处理并存储为查询
操作及其结果的JSON表示。
[0011] 在SQL操作是SQL DML写操作的情况下,该方法可以包括:从分布式账本平台检索执行SQLDML写操作所需的数据;执行包括检索到的数据的SQL DML写操作;准备查询结果中
的任何新的或更新的记录的JSON表示;以及将SQL DML写操作和任何更新的记录以可以由
分布式账本平台处理以便包括在分布式账本上的形式提交至所分布式账本平台。该方法还
可以包括:监视分布式账本的SQLDML写操作接受到分布式账本中;以及通知调用SQL查询的
实体SQLDML写操作是否成功。
[0012] 另一方面,在SQL操作是SQLDML读操作的情况下,该方法可以包括:从分布式账本平台检索执行SQLDML读操作所需的数据;执行包括检索到的数据的SQLDML读操作;准备查
询结果的JSON表示;以及将查询结果的JSON表示以可以由所述分布式账本平台处理以便包
括在分布式账本上的形式记录至分布式账本平台。该方法还可以包括将查询结果的JSON表
示返回至调用SQL查询的实体。
[0013] 在示例实施方式中,分布式账本平台为 Fabric平台。在这样的实施方式中,可以通过执行配置交易和常规交易来创建数据库作为用于
Fabric平台的分布式账本的世界状态数据库,配置交易创建通道并且限定哪些对等计算机
将维护该数据库的拷贝,常规交易写入关于关系数据库的元数据。此外,可以创建链码,其
限定分布式账本中的交易数据和用于修改交易数据的交易指令。在示例实施方式中,链码
可以限定作为分布式账本平台上的交易数据的按JavaScript对象记号(JSON)的关系数据
库属性。在操作终结时,用关系数据库属性更新世界状态数据库。此外,该方法可以包括:创
建考虑了可以由分布式账本平台处理以便包括在分布式账本上的形式的经解析和翻译的
结构化查询语言(SQL)查询。例如,SQL查询可以考虑 Fabric平台上的关系
管理和组织系统规范的JSON元素。
[0014] 在其他示例实施方式中,提供了一种系统,该系统包括:实施包括交易数据的分布式账本的分布式账本平台;以及至少一个处理器,该至少一个处理器执行用以实施执行多
个操作的关系数据管理和组织系统的指令,所述多个操作包括:创建数据库并且记录关于
分布式账本上的数据库的信息;将所接收到的关系数据库管理查询转换成可以由分布式账
本平台处理的查询操作;对分布式账本平台执行查询操作以生成查询结果;以及将该查询
结果以可以由分布式账本平台处理以便包括在分布式账本上的形式记录至分布式账本平
台。该系统还可以包括用于生成关系数据库管理查询的装置,包括:(1)至关系数据管理和
组织系统的用户接口,用户通过该用户接口提供结构化查询语言(SQL)查询;(2)将SQL查询
经由至关系数据管理和组织系统的应用程序接口传递至关系数据管理和组织系统的用户
应用;或者(3)执行SQL查询的智能合约。
[0015] 在系统的示例实施方式中,至少一个处理器还执行指令,以将SQL查询解析成包括下述的SQL操作:作为可替选的数据操纵语言(DML)写操作;DML读操作;以及数据定义语言
(SQLDDL)操作;以及创建SQL操作和SQL操作中包括的任何关系数据的JavaScript对象记号
(JSON)表示。至少一个处理器还可以执行指令,以确定因SQL操作的执行而导致的交易是否
在平台相关程度上朝着接受至分布式账本中进展。例如,可以在DML写操作结束时添加
OPSTAT指令以获取对应交易的更明确的状态。
[0016] 在另外的示例实施方式中,分布式账本平台位 Fabric平台,并且至少一个处理器执行指令以进行下述操作:通过执行配置交易和常规交易来创建数据库作
为用于 Fabric平台的分布式账本的世界状态数据库,配置交易创建通道
并且限定哪些对等计算机将维护该数据库的拷贝,常规交易写入关于关系数据库的元数
据;以及创建限定分布式账本中的交易数据和用于修改交易数据的交易指令的链码。至少
一个处理器还可以执行如下指令,所述指令:对应于限定作为分布式账本平台上的分布式
账本中的交易数据的按JavaScript对象记号(JSON)的关系数据库属性的链码;以及用以用
关系数据库属性更新世界状态数据库。至少一个处理器还可以执行指令,所述指令用以创
建经解析和翻译的结构化查询语言(SQL)查询,SQL查询考虑了可以由分布式账本平台处理
以便包括在分布式账本上的形式。
[0017] 本文描述的实施方式还涵盖利用用于实现贯穿本公开内容描述的方法的指令编码的计算机系统和计算机可读介质。例如,本文描述的系统和方法可以在云中的用于提供
用于访问如本文描述的分布式账本平台上实现的数据库并且将数据存储至该分布式账本
平台上实现的数据库的功能的计算平台上实现。

附图说明

[0018] 在附图的图中,通过示例而非限制的方式示出了本公开内容,在附图中,相似的附图标记指示相似的要素。在附图中:
[0019] 图1是示例实施方式中的关系数据管理和组织系统的框图。
[0020] 图2是在示例实施方式中使用的其中 为编程语言并且Fabric为分布式账本平台的实现中的关系数据管理和组织系统的实现方式的框图。
[0021] 图3是示出示例实施方式中的针对关系数据管理和组织系统的数据库创建中涉及的活动、组件和数据的框图。
[0022] 图4是示出示例实施方式中的用于将关系数据写入关系数据管理和组织系统的现有数据库的操作的框图。
[0023] 图5是示出示例实施方式中的由关系数据管理和组织系统的用户接口或由用户的应用经由关系数据管理和组织系统的语言特定SDK和应用程序接口请求的数据操纵语言
(DML)读取查询的执行的框图。
[0024] 图6是示出示例实施方式中的用于添加用于超级管理级别以下的访问的用户的关系数据访问控制的第一部分中涉及的组件和数据的框图。
[0025] 图7是示出ELEMENT SDK与用户的应用的交互以及它们都被托管在其中的执行环境的框图,该执行环境在示例实施方式中被建模为用户应用节点。
[0026] 图8是示例实施方式中的使用关系数据管理和组织系统进行对分布式账本的成功SQLDML写操作的示例的逻辑流程图。
[0027] 图9是示例实施方式中的使用关系数据管理和组织系统从分布式账本中进行成功SQLDML读操作的示例的逻辑流程图。
[0028] 图10是示出示例实施方式中的成功执行数据定义语言(DDL)写入的框图。
[0029] 图11是典型的通用计算机的框图,该通用计算机可以被编程为适用于实现本文公开的关系数据管理和组织的一个或更多个实施方式的专用计算机。
[0030] 图12示出“先执行后排序”设计。
[0031] 图13示出包括对等节点的区块链网络,所述对等节点中的每个对等节点可以保存账本的拷贝和智能合约的拷贝。
[0032] 图14示出托管账本实例和链码实例的对等端。
[0033] 图15示出托管多个账本的对等端。
[0034] 图16示出托管多个链码的对等端的示例。
[0035] 图17示出与排序者一起确保账本在每个对等端上保持最新的对等端。
[0036] 图18示出允许特定的一组对等端和应用在区块链网络内彼此通信的通道。
[0037] 图19示出具有多个组织的区块链网络中的对等端。
[0038] 图20示出当对等端连接至通道时,其数字证书经由通道MSP标识其拥有组织。
[0039] 图21示出由返回签注提议响应的对等端独立执行的交易提议。
[0040] 图22示出排序节点的用于向对等端分发区块的第二角色。
[0041] 图23示出包含两个状态的账本世界状态。
[0042] 图24示出拥有有效的信用卡是不够的——其必须还被商家接受。
[0043] 图25示出公钥基础设施(PKI)的元素。
[0044] 图26示出描述被称为Mary Morris的一方的数字证书。
[0045] 图27示出其中Mary使用其私钥来对消息进行签名的示例。
[0046] 图28示出向不同参与者分配证书的证书机构。
[0047] 图29示出在根CA与一组中间CA之间建立信任链,只要针对这些中间CA中的每个CA的证书的颁发CA是根CA本身或者具有到根CA的信任链即可。
[0048] 图30示出使用CRL来检查证书仍然有效。
[0049] 图31示出访问级别和许可确定。
[0050] 图32示出数据对象和操作对象的概述。

具体实施方式

[0051] 下面关于图1至图32的描述充分说明了用于使得本领域技术人员能够实践它们的特定实施方式。其他实施方式可以合并结构、逻辑、过程和其他变化。一些实施方式的部分
和特征可以包括在其他实施方式的那些部分和特征中或者替换其他实施方式的那些部分
和特征。权利要求书中阐述的实施方式涵盖那些权利要求的所有可用等同方案。
[0052] 术语
[0053] 分布式账本技术(DLT):使得能够在参与网络的多个计算机之间复制、共享和同步数字数据的多种技术中的任意一种技术。分布式账本技术被设计成固有地抵抗对数字数据
的修改,一旦进行同步,所述数字数据被统称为“分布式账本”。分布式账本通常由对等网络
进行管理,该对等网络共同遵守用于验证新信息的协议。能够生成和维护分布式账本的系
统被称为分布式账本平台。“分布式账本平台”包括已知平台,诸如Aion、ArcBlock、
TM
Cardano 、Corda、Enigma、EOS、以太坊、 Fabric、 Iroha、
TM
Sawtooth、ICON、IOTA、Komodo、Lisk 、MultiChain、Neblio、NEM、NEO、NxT、
Qtum、Smilo、Stella、Straitis、Tezos、Wanchain、Waves和Zilliqa,加来自前述内容的派生
词以及其他平台。这些平台中的许多平台也是“区块链技术”或“区块链”平台,是分布式账
本技术平台的子集。
[0054] 智能合约:提供在分布式账本平台上进行的通用计算的计算机协议。智能合约交易可以是简单的,或者可以实现复杂的逻辑。由此产生的交易通常对账本参与者是透明的,
可追踪的且不可逆转的。
[0055] JSON:JavaScript对象记号是轻量级的、基于文本的、人类可读的数据交换格式。
[0056] SQL:结构化查询语言是用于访问和操纵关系数据库管理系统的标准语言。
[0057] 在浏览器之外执行JavaScript代码的免费的开源服务器环境。是构建在Chrome浏览器的JavaScript运行上的异步编程平台。关于
的更多信息可以在“关于 ”Node.js,Node.js基金会,https://nodejs.org/en/
about/处找到。
[0058] Fabric:企业级许可分布式账本平台,其为广泛的行业用例集提供模块化和多功能性。Fabric的架构包括身份提供者、通道、世界状态数据库以及用户和
系统链码。关于 Fabric的另外的细节可以在本文所附的附录A中获得。
[0059] 链码:在Fabric中,软件(a)限定一个或更多个资产,以及用于修改所述资产的交易指令;即,业务逻辑,或者(b)扩展或修改平台,包括规则和管理规则的执行的活动。链码
实施用于读取或改变键值对或其他状态数据库信息的规则。链码函数针对账本的当前状态
数据库来执行,并且通过交易提议启动。链码执行产生一组键值写入(写入集),所述写入可
以提交到网络并且应用于所有对等端上的账本。链码可以被认为等效于智能合约的与平台
无关的构思。
[0060] Apache 用于合并到 Fabric中的世界状态数据库的选项。当链码数据值被建模为JSON时,Apache 支持丰富查询。
索引和查询是本文描述的关系数据管理和组织系统的示例实施方式中使用的选项。关于
的另外的细节可以在本文所附的附录A中获得。
[0061] 概述
[0062] 关系模型的价值来自于在数据表示与读取和写入数据的程序之间建立独立性。除了鼓励可重用的用于数据管理的框架之外,关系数据库管理系统(RDBMS)还实施关于数据
写入的规则,该规则不会使一个程序的数据操纵破坏其他程序的用于定位和访问该数据的
能力。这些原则中的第一原则是宣布“排序依赖”为非法。如果一个程序依赖于以特定顺序
物理维护的数据,那么无视该要求的另一程序可能破坏第一原则。第二原则是防止“索引依
赖”。索引是用于提高一些操作的性能的数据的冗余存储,可能以其他操作为代价。虽然不
可能满足每个程序的性能偏好,但关系模型至少保证没有程序将在针对数据集的索引改变
的情况下中断。第三原则是防止“访问路径依赖”。在关系模型中,程序仅需要知道其想要读
取和写入什么数据,而无需关于数据如何被组织在存储装置中的附加信息。在RDBMS之前,
数据通常以分层结构来组织,随后可能被重新排列,不必要地破坏了程序的用于定位和与
该数据一起工作的能力。
[0063] 本文描述的关系数据管理和组织系统实现了这三个原则。但是应理解创建用于实现这三个原则的分布式账本的关系数据管理和组织系统所涉及的挑战,必须首先理解特定
于分布式账本平台的一些考虑。
[0064] 分布式账本技术在公众心目中与加密货币密切相关联,加密货币的使用是在2009年发明的。但是对等货币的创建也是对用于其他目的的分布式计算的全新方法的发明。正
在探索各种用途,以利用类似保证的数据可用性、不受集中控制或加密防篡改的功能。
[0065] 目前围绕分布式账本采用的能量使人联想到互联网的早期采用。存在关于数据管理的再体验或避免相同错误的可能性,所述错误在网站成熟时拖累网站。类似于早期的网
站,分布式账本的加密货币使用以相对简单的数据结构和用于管理所述数据结构的硬编码
的业务逻辑为特色。然而,随后的智能合约的发明为任意复杂的数据和规则开启了大门。
[0066] 类似供应链物流的企业用例正在将信息和逻辑放在分布式账本上,在量方面其与传统解决方案竞争并且不久将及极大地超过传统解决方案,但是不具有现有标准化数据管
理工具的益处。随着每个程序员设计其自身的存储,结果再次是数据与写入该数据的程序
(智能合约)紧密耦合。需要诸如本文描述的关系数据管理和组织系统来减少这种耦合。
[0067] 不幸的是,断开分布式账本中的连接比实现关系数据库时面临的情况更复杂。在其初始完全去中心化的形式中,分布式账本实际上依赖逻辑与数据之间的紧密联系来在参
与者之间创建共识和信任。所有参与者运行完全相同的逻辑,确认他们接收到完全相同的
结果。这导致针对那些分布式账本平台上的数据管理的一些重要影响。例如,影响数据到分
布式账本的写入的数据管理系统的任何部分位于管理所述数据的智能合约内并且在该智
能合约的控制下,从而本质上使所述数据成为智能合约本身的一部分。此外,作为智能合约
的一部分,数据被传播至网络中的所有参与者,使得所述参与者可以运行相同的数据创建
逻辑。
[0068] 然而,逻辑与数据之间的这种耦合也不会使关系模型的优点变得无关紧要,即使对于限制性的分布式账本平台也是如此。首先,可以配置允许通过集体协议来更新数据的
相同共识机制,使得参与者可以同意升级现有智能合约或者对现有智能合约进行添加。然
而,如果这些合约无法读取和使用现有的分布式账本数据,那么这些合约将是无用的。当
今,智能合约通常无法这样做,因此,这样的升级在生产分布式账本系统中不常见,不管其
有效性如何。
[0069] 即使在单独的智能合约程序中,随着合约范围和复杂性的增加,一致的用于存储的方法变得越来越重要。当今的电子货币和可交易资产的相对简单的规则正在为完全分布
式的基于账本的供应链和社交平台所替代,涉及许多开发者、可重用的组件和不断发展的
需求。那些开发者将期望可预测的用于数据存储的方法,就好像他们处理大型传统程序一
样,而关系模型提供了这样的可预测方法。
[0070] 关系模型的有效性针对纯读操作甚至更大,这是因为纯读操作不受共识管理,除了在一些平台中针对数据本身的访问许可。这导致其中出于新的原因值得努力使用现有数
据的更多情况。如果分布式账本上的数据是根据关系规则存储的,那么所述数据可以被在
分布式账本内部或外部运行的RDBMS系统有效地读取和处理,其目的超出了原始智能合约
程序员所设想的。
[0071] 并非分布式账本技术的每个实现方式都利用每个分布式账本技术特征或者被迫假设使用者在类似加密货币的公共网络中看到的相互不信任水平。特别是在企业环境中,
出于各种原因,部分采用实际上更为常见。常见情况包括使用分布式账本平台作为用于实
现类似加密防篡改和数据复制的功能的方便方式。企业还使用宽松的共识规则或集中式前
端来实施在其完全控制下的分布式账本网络,可能作为未来趋向更加分布式应用的第一
步。此外,具有高的信任级别的联盟为支持人员建立了分布式账本网络连同严格的智能合
约实施,但允许管理者和内部审核员直接根据其自身的权限来更新分布式账本数据。在这
些情况中的每种情况下,有些时候分布式账本数据可以完全类似于传统数据库进行管理,
不仅用于读取和写入,而且同样地用于只读操作。
[0072] 示例实施方式
[0073] 本文描述的关系数据管理和组织系统实现上面讨论的益处并且提供一组规范,所述一组规范可以使跨不同的分布式账本平台和编程语言的关系数据管理和组织系统的实
现方式标准化。本文描述的关系数据管理和组织还提供了SQL(结构化查询语言)标准方言
的子集,用于指导针对分布式账本的关系数据的管理和组织。本文描述的关系数据管理和
组织系统还被设计成用于跨各种平台和语言的实现方式。在示例实施方式中,关系数据管
理和组织系统在 Fabric分布式账本网络和 编程语言上实现,并
且具有勇于支持以 编写的用户程序的机制。然而,将理解的是,可以使用其他分
布式账本平台和编程语言,并且具有这样的平台和语言的优点和缺点。
[0074] 对关系数据管理和组织系统的描述将以旨在指导所有实现方式的一组规范、接口和核心组件开始。图1是示例实施方式中的关系数据管理和组织系统100的框图。图1所示的
关系数据管理和组织系统100的部分对所有实现方式是通用的,而其他部分是定制的但是
遵循一组通用规范。图1是示出这些组件和规范的适配组件图。贯穿该描述,为了便于描述,
关系数据管理和组织系统100也被称为“ELEMENT”。
[0075] 通用规范表示为具有《规范》定型以指示概念化要求的对象元素。规范是期望在关系数据管理和组织系统的所有实现方式中以通用方式实现的方面。《抽象》定型表示需要存
在但在每个实现中将以不同的方式实现的实际软件组件。示出的接口也是所有实现方式共
同的规范。
[0076] 语言特定软件开发工具包(SDK)组件102与用户应用集成并且将命令中继至关系数据管理和组织系统(ELEMENT)API 104。语言特定SDK规范102旨在创建跨不同用户编程语
言的共同体验。在支持的命令中,存在SQL的子集,其在本文被指定为ELEMENT SQL105。与来
自特定语言SDK 102的其他调用和来自ELEMENT用户接口(UI)106的输入一起,所接收到的
命令由依赖于ELEMENT数据定义语言(DDL)解析器110的ELEMENT控制台108进行解析、验证
和处理。ELEMENT UI 106处理针对管理任务和报告任务的直接人工交互。ELEMENT UI 106
是辅助用户构建有效输入查询并且以有组织的格式表示系统响应的图形网络平台。
[0077] 在示例实施方式中,仅DDL操作由ELEMENT控制台108经由ELEMENT DDL解析器110进行处理。数据操纵语言(DML)操作通过服务层接口114传递至分布式账本平台特定组件
112,并且由ELEMENT SQL DML解析器116进行解析以供分布式账本平台特定组件112处理。
上面没有描述的功能由一系列分布式账本平台特定组件112实现。服务层接口114充当
ELEMENT控制台108与作为到这些组件及其功能的入口点的分布式账本平台特定服务层118
之间的链接。除了可能的由用户的智能合约启动的操作之外,服务层接口114参与所有操
作。
[0078] 分布式账本平台特定服务层118形成关系数据管理和组织系统100的主要操作逻辑,并且负责完成所有的用户和数据管理操作。这样的操作在分布式账本平台特定服务层
118本身与具有Added ELEMENT特征120的分布式账本平台之间进行分割。确切的工作划分
取决于分布式账本平台的能力。该功能由下述三个子规范来提供:
[0079] 1.关系数据访问控制规范122规定关系数据管理和组织系统100的所有实现方式遵循的五级粗粒度访问控制模型。该规范记录用户角色以及它们如何影响对关系数据管理
和组织系统100的系统功能的访问,包括对数据的访问。访问控制在不同平台上将使用显著
不同的方法。该规范是记录共同方面的附录B。
[0080] 2.关于分布式账本的关系数据规范124限定针对支持的数据表示(JSON模式)和数据操作的要求。该规范在附录C中记录针对关系数据存储的要求。
[0081] 3.智能合约集成规范126规定可以从智能合约访问哪些关系数据功能。
[0082] 特定语言的SDK 102均提供用于从流行于分布式账本应用实施者的编程语言访问ELEMENT API 104的全部功能的接口。针对这些SDK的规范使关于函数名称、参数顺序和含
义、返回值和错误等的一致性最大化。下面描述使用Fabric和 实施的实现。
[0083] 在示例实施方式中,ELEMENT API 104是在关系数据管理和组织系统100内部用作用于调用数据库操作的公共入口点的接口。其由ELEMENT UI 106和所使用的实现中存在的
任何特定于语言的SDK 102两者调用。其以web接口的形式指定,有时被称为“REST API”。
ELEMENT API 104由ELEMENTDB控制台108实施并且在关系数据管理和组织系统100的所有
实现中重复使用。ELEMENT API 104的另外的细节在附录D中提供。
[0084] ELEMENT UI 106是允许用户手动操作由关系数据管理和组织系统100实施的数据库的用户接口组件。ELEMENT UI 106向用户提供用于下述的能力:添加用户和调整用户访
问级别;使用内置文本编辑器对可用数据库执行SQL查询;访问用户文档,包括查询示例和
ELEMENT‑特定SQL语言扩展的语法;以及查看提交的查询的状态信息并且查看从其执行已
经被成功完成的查询返回的数据。
[0085] ELEMENT控制台108和ELEMENT SQLDDL解析器110是存在于关系数据管理和组织系统100的所有实现中的核心组件。ELEMENT控制台108经由ELEMENT API 104(其可以是代表
性状态转移(REST)API)接受源自语言特定SDK 102或经由ELEMENT控制台108也为其服务的
ELEMENT UI 106直接来自用户的数据库命令。ELEMENT控制台108将这些命令转换成可以传
递至服务层接口114的形式,该服务层接口114链接至关系数据管理和组织系统100的分布
式账本平台特定组件112。
[0086] 在示例实施方式中,关系数据管理和组织系统100(104、106、108、110)的共同组件在 中作为web服务实现,这允许部署灵活性和在需要时进行水平扩展。
[0087] ELEMENT SQL 105,其包括典型的SQL操作以及一些ELEMENT‑特定的扩展,是用于以开发者最熟悉的方式描述RDBMS操作的语法。在示例实施方式中,用于关系数据管理和组
织系统100的SQL语法被设计用于与ISO/IEC 9075(当前为SQL:2016)的子集兼容。为了访问
管理和实施,ELEMENT SQL中的操作被分为DDL查询、DML写入查询和DML读取查询。
[0088] ELEMENT对SQL的扩展包括针对在分布式账本数据环境中工作的适配以及方便功能。这些扩展是ELEMENT特定的关键字,其可以与SQL语法结合使用以形成针对ELEMENT系统
的有意义的查询。示例实施方式中的扩展关键字包括:
[0089] 1.OPSTAT(操作广播状态)——该操作检查特定操作的交易是否在与所采用的特定分布式账本平台相关的程度上已向分布式账本中进展。对于关系数据管理和组织系统
100,针对DDL操作的OPSTAT是默认设置的;然而,OPSTAT可以在DML写操作的末尾添加以获
取该交易的更明确的状态。使用OPSTAT时期望三种可能的响应——成功、失败或超时。
[0090] 2.QUERYLEVEL——QUERYLEVEL特征专门与DML读操作(例如,SELECT)一起使用,以获取关于关系数据管理和组织系统100的特定记录的元数据信息。通过使用QUERYLEVEL可
以获得两个级别的信息——第一是关于记录的基本信息而第二是更深的查询,该查询提供
诸如记录创建日期、最后修改日期、被用户修改以及其他细节的粒度信息。
[0091] 3.BOOKMARK——该特征与在关系数据管理和组织系统100中由记录计数限定的页面中的表数据的检索有关。默认情况下,在对行计数限制的情况下执行的每个查询附带书
签值,该书签值充当对基于相同条件的下一个相同大小的数据页的参考。如果提供了
BOOKMARK关键字,则其将包括在查询结果中(仅适用于SELECT查询)。
[0092] 4.ELEMENT_COLUMN_DEFAULT——该关键字与UPDATE或INSERT SQL操作一起使用,以指示应当将默认值用于关系数据管理和组织系统100中的表列。默认值可以在创建表的
同时分配给列。没有配置默认值的列将不受该关键字的影响。下面附录E中的ELEMENT SQL
规范这些关键词中的每个关键词与SQL语法相结合的附加细节,以形成可以用于表示用于
由关系数据管理和组织系统100进行处理的查询和命令的SQL语法的变体。
[0093] 服务层接口114包括在用于分布式账本平台的关系数据管理和组织系统100的每个实现中将被支持的功能。针对服务层接口114的规范覆盖整个接口加可以在该服务层或
分布式账本平台本身上实现的功能子集。这些功能包括:
[0094] 数据库创建和删除
[0095] 表创建、改变和删除
[0096] 检索数据库对象元数据
[0097] DML操作,例如,插入和选择记录
[0098] 另外的DDL操作,诸如索引创建、改变和删除
[0099] 用户权限管理。
[0100] 注意,由于分布式账本数据历史的不变性,分布式账本上下文中的修改和删除将始终通过附加改变指示或删除指示来完成。关系数据管理和组织系统100还需要提供批量
交易支持,以覆盖至少记录级变化。
[0101] 在示例实施方式中,服务层接口114在 中实现并且被重用,而不管SDK语言或分布式账本平台目标如何。经由该接口接收到的请求的服务由分布式账本特定组件
112执行;其中,根据实现智能合约集成的要求,部分功能仅在分布式账本平台本身实现。
[0102] 具有添加的ELEMENT特征规范120的分布式账本平台描述了将直接在分布式账本平台上实现的功能,以便关系功能可以被该平台上的智能合约使用。类似平台本身,这些实
现方式在方法上将会很大不同。这些规范列出了仍将通用的内容,包括用于关系数据和模
式的通用的基于JSON的数据格式。规范被分为三种类别:分布式账本上的关系数据、访问控
制以及智能合约集成。
[0103] 1.分布式账本上的关系数据(RDODL)规范
[0104] 在指定关系数据管理和组织系统100中的关系数据和相关功能时使用五个熟悉的抽象。所述抽象为:数据库、表、字段、索引和记录。在可以针对不同的分布式账本平台实现
这些构思的方式上存在显著差异,但在每个平台上下述是正确的:
[0105] 1.五种元素类型中每种元素类型的每个实例将由以标准ELEMENT格式的独立JSON文档来表示。
[0106] 2.使用与其他分布式账本交易相同的方法和共识将这些文档写入分布式账本。
[0107] 3.对这些元素中的一个元素的每次修改或状态改变通过将JSON文档的完整更新版本附加至分布式账本来表示。
[0108] 在关系数据管理和组织系统100的设计中正式规定了针对五个对象的JSON模式限定和用于索引的最低要求。
[0109] 2.关系数据访问控制规范
[0110] 关系数据管理和组织系统100的实现方式支持粗粒度访问控制,该访问控制针对数据库级别处的个体分布式账本身份限定。授予五个访问级别的权限如下:
[0111] ‑超级管理者——数据库管理,诸如创建和删除加管理者访问级别的所有权限。
[0112] ‑管理者——对权限管理功能的访问加DDL访问级别的所有权限。
[0113] ‑DDL——对分类为DDL的功能的访问,包括(例如)更改表和索引的模式的功能加DML写入访问级别的所有权限。
[0114] ‑DML写入——对分类为DML写入的功能的访问,包括数据写入诸如插入加DML读取访问级别的权限。
[0115] ‑DML读取——对分类为DML读取的功能的访问。包括关系数据的选择查询、模式检索、统计信息的查看等。
[0116] 数据定义语言(DDL)是指改变关系数据的结构、组织或描述的操作。数据操纵语言(DML)是指涉及关系数据本身的操作。
[0117] 关系数据管理和组织系统100的实施基于与用于分布式账本操作的相同身份的访问,这使得能够进行智能合约集成,并且对于该要求,该关系数据具有与存储在分布式账本
上的其他数据等效的分布式账本特征。
[0118] 3.智能合约集成规范
[0119] 如上面提及的,关系数据管理和组织系统100的关键方面是直接从智能合约访问大部分关系数据功能的能力。对于智能合约集成,智能合约能够具有用于执行与针对语言
特定SDK 102指定的功能等效的功能,不包括DDL数据库操作。分布式账本针对这些调用例
如输入共识并且由此产生不可变记录的考虑等效于本地智能合约执行。此外,对这些功能
的调用应当尽可能在实现关系数据管理和组织系统100的分布式账本平台中的语言特定
SDK 102中描述的形式、命名和语义的程度上符合。诸如模式改变的DDL操作被排除在智能
合约集成之外,这是因为这些操作通常涉及对关系存储的大量的更新,使得在单个分布式
账本交易中执行所述更新将不受支持。
[0120] 将理解的是,具有添加的ELEMENT特征规范120的分布式账本平台描述了下述一组通用接口、语法和要求:无论实现方式如何,其使得能够使用对于非分布式账本程序员已经
熟悉的语法和语义在分布式账本上进行关系数据存储和操作;以及其在分布式账本平台上
是相同的,特别是对于关系数据管理和组织系统100的所有实现方式通用的使用SQL语法的
能力。存储是使用标准化的JSON数据格式实施的,该数据格式使未来跨分布式账本平台实
现方式的数据可移植性容易。一组所需的功能被跨平台标准化,因此可以将对分布式账本
平台的选择与对使用类似关系数据管理和组织系统100R的DODL平台的决策分开关注。这种
能力使得经由语言特定SDK 102、用户控制台和API或智能合约为一致的关系数据存储访问
成为可能。
[0121] Fabric上的关系数据管理和组织系统100
[0122] 在示例实施方式中,提供了使用 Fabric用于其分布式账本平台的针对 应用的软件开发工具包。
[0123] 图2提供了Fabric实现方式如何实现本文描述的关系数据管理和组织系统100的规范加附加功能的视觉概述。在示例实施方式中,Fabric上的关系数据管理和组织系统100
的RDODL实现涉及下述方面。关系数据管理和组织系统100的数据库利用Fabric的“通道”构
思。每次请求新的数据库时,关系数据管理和组织系统100的Fabric服务层使用Fabric SDK
(包括在分布式账本平台中)来创建Fabric通道。包括关系数据管理和组织系统100的功能
的系统链码已经存在于对等节点中并且变成可由新创建的通道访问。通道创建还在所有参
与的对等节点上自动地建立新的分布式账本和“世界状态”数据库。此外,脚本启动交易,从
而调用关系数据管理和组织系统100的系统链码,以在分布式账本上记录关于数据库的高
级别信息。所有后续的数据库写操作都涉及类似的交易,并且根据RDODL规范以JSON格式将
数据对象附加至分布式账本。每个这样的数据库信息到账本的附加也被每个对等端反映在
其世界状态数据库中。这使得每个数据对象的当前版本可快速用于读操作。
[0124] 除了关系数据管理和组织系统100的核心组件和规范以外,图2是其中是编程语言且 Fabric是所使用的分布式账本平台的实现中的关系数据管
理和组织系统的实现方式的框图。图2贯注于 的实现方式如何实现图1
中概述的规范连同一些附加功能。
[0125] 如图2所示, SDK组件200实现了语言特定SDK 102的用户语言特定功能并且使得开发者能够直接从其应用代码中与关系数据管理和组织系统100进行交互。在附
录F中提供为了与 应用一起使用而开发的 SDK组件200的版本的细
节。ELEMENTDB控制台108、ELEMENT API 104、ELEMENT UI 106和服务层接口114对于所有实
现方式是通用的,与图1相同。在ELEMENTDB控制台108、ELEMENT API 104、ELEMENT UI 106
和服务层接口114下方,ELEMENT FabricService 202实现针对所有平台操作的外观模式
(facade)。ELEMENT FabricService 202实现服务层接口114,服务层接口114充当用于API
层语分布式账本之间交互的中间人。ELEMENT FabricService 202的服务有助于执行RDBMS
相关的操作,如附录G中更详细描述的。ELEMENT SQL解析的实现由被称为Element_解析器
204的组件实现,该组件在Fabric实现中出现两次。首先,Element_解析器204作为
ELEMENTDB控制台108的依赖关系出现并且实现DDL解析器。这对于所有实现是通用的。其
次,Element_解析器204作为Element_链码206的依赖关系出现并且提供DML解析,这使得
DML SQL可在用户链码智能合约中受到支持。在附录H中提供针对Element_解析器204的规
范。
[0126] 通过其对分布式账本平台加ELEMENT特征规范的依赖关系来直接支持FabricService 202的为下述:用户向其注册并且记录访问权的身份提供者(例如,Fabric
证书机构208);以及针对某些索引能力而直接访问的世界状态数据库(例如,Fabric世界状
态数据库210);以及ELEMENT Fabric对等端镜像212—— Fabric 214中为
关系数据管理和组织系统100定制的核心组件。
[0127] Element_链码206是添加至ELEMENT Fabric对等端镜像212的另外创建的系统链码,其在Fabric上执行所有数据库相关的操作并且还具有对身份提供者(例如,证书机构
208)和世界状态数据库(例如,Fabric世界状态数据库210)的依赖关系。结合对等端本身中
的账本存储,这些使得ELEMENT Fabric对等端214能够实现与访问控制的关系数据。此外,
由于用户的智能合约可能调用系统链码,因此这也实现了智能合约集成。在附录I中提供针
对Element_链码206的规范。
[0128] 图3是示出针对关系数据管理和组织系统100的数据库创建中涉及的活动、组件和数据的框图。在数据方面,数据库创建涉及两个Fabric交易。第一为“配置交易”,其创建通
道并且限定哪些对等端将维护数据库的拷贝。第二为常规交易,其写入关于关系数据库本
身的元数据。
[0129] 图3是左侧所示的统一建模语言(UML)活动模型和叠加在ELEMENT Fabric服务层202(右侧)拓扑上的UML对象图以及托管这些对象的部署的Fabric网络的组合。图3示出了
左侧的操作序列以及在右侧的Fabric中要求系统在关系数据管理和组织系统100中创建新
的数据库期间和紧之后存在的相关数据。创建数据库利用Fabric的通道(分布式账本数据
隔离)创建机制加添加的功能。
[0130] 图3的左半部分的块是与数据库创建相关的组件,即Fabric服务202和Fabric对等端214。服务层在初始处理数据库创建请求时创建三个数据对象。如所示出的,准备Fabric
通道配置文件活动300创建供网络使用的《通道配置文件》通道.tx 302。具有创世块活动的
生成配置交易304创建包含创世块并启动通道的特殊Fabric交易《fabric配置tx》306。创世
块为提议的记录至分布式账本的第一条数据,其包含其初始配置。<数据库_名称>区块是创
世块本身。<数据库_名称>区块和通道被赋予与关系数据管理和组织系统100的数据库的名
称一致的名称。创建通道并且将授权的对等节点加入通道活动308根据《fabric配置tx》306
创建通道配置数据310。创建通道并且将授权对等节点加入通道活动308还创建账本313,该
账本包括创世块314和相应的空的世界状态数据库322。包含关系数据管理和组织系统100
的数据库的属性的数据表示的准备Fabric交易活动312创建Fabric分布式账本交易
《fabric tx》316,Fabric分布式账本交易《fabric tx》316包含表示关系模式和其他属性的
将管理要存储在关系数据管理和组织系统100的该数据库中的数据的JSON对象。具有初始
数据库模式的提交Fabric交易318将Fabric分布式账本交易《fabric tx》316合并至Fabric
区块320。最后,在324处,Fabric对等端214使用关系数据管理和组织系统100的数据库的属
性来自动地更新世界状态数据库322。
[0131] 通道是在Fabric分布式账本网络中共享数据的边界。区域326外部的对等节点不接收模式信息或数据。还示出了节点之间的网络连接。所述网络连接包括Fabric节点之间
的正常互连加HTTPS路径328,Fabric服务层内的Fabric SDK库(未示出)通过HTTPS路径328
与对等节点联系。应注意,Fabric SDK是由 Fabric提供的组件,并且作为
依赖关系包括在关系数据管理和组织系统100中的允许客户端程序在Fabric平台上启动基
本的分布式账本操作的Fabric服务中。
[0132] 通过其在Fabric网络中创建通道和处理交易的完整过程没有被建模,但是在这些步骤期间将上述对象传送至网络并且创建剩余的对象。首先,在创建通道时,获得三个项,
所述三个项在Fabric中针对该过程是正常的:
[0133] 1.来自config.tx的通道配置——排序服务使用其保留来自通道配置文件的信息,以确保通道数据尤其限于参与节点。
[0134] 2《. 账本》<数据库_名称>——创建针对通道/数据库的仅附加数据存储被并且将其复制到每个参与的对等节点。
[0135] 3《. 世界状态》<数据库_名称>——以更有效查询的形式提供对账本的伴随存储,其仅包含账本中针对每个项目的最新值。在关系数据管理和组织系统100中,该数据库可以
为 实例,其是针对Fabric的标准选择中之一。
[0136] 创建通道后,对包含数据库模式(关系数据属性)的JSON表示的正常Fabric交易进行处理。
[0137] 随后的关系数据库操作在进一步附加的Fabric交易中表示为JSON对象(除了明确排除针对其提交至账本的读取查询)。图4示出了DML写操作的执行。该过程创建JSON关系数
据对象,一旦被引入世界状态数据库,其可以由关系数据层100的系统链码使用,以响应查
询和其他请求。图5示出了这一点,描绘了由ELEMENT UI 106或由用户的应用经由语言特定
SDK 102和ELEMENT API 104请求的DML读取查询的执行。
[0138] 图4是示出用于将关系数据写入关系数据管理和组织系统100的现有数据库的操作的框图。左侧的泳道表示关系数据管理和组织系统100的两个参与组件——
FabricService和系统链码。每个泳道内的UML活动表示其执行的关键活动。粗体箭头按顺
序连接活动,而另外的箭头连接至受活动影响的数据对象。
[0139] 通过更新操作,限定通道中的Fabric对等节点402内的《账本》<数据库_名称>对象400与图3中创建的可以在每个对等节点中复制的账本相同。附加的《fabric区块》404已附
加在其中,其包含指定关系数据库操作的《fabric交易》406。该特定操作将在上游过程中从
用户接收,包括:包含创建《fabric tx》的期望操作的准备Fabric交易408;以及将包含该操
作的Fabric交易提交至对等节点,以在414处执行交易并且生成由此产生的数据,如位于图
4的左半部分的活动部分所示。该交易还包含该操作的结果,当该交易被处理为区块时,该
操作的结果将由关系数据管理和组织系统100的系统链码执行。在一些情况下,该执行还涉
及从世界状态数据库读取数据的链码。该流程未被示出,但是可以从图5中的DML读操作中
理解。
[0140] 由此产生的ELEMENT关系数据JSON 416包含表示新的或改变的表、记录、用户和数据库属性的对象。这些中的每一个具有标识受影响的数据的唯一密钥。在418处,Fabric网
络将该交易和由此产生的数据处理为Fabric区块,并且将该Fabric区块附加至账本400。除
了作为交易的一部分永久记录在账本400中以外,在422处,系统链码使用当前的关系数据
来更新世界状态数据库420,其中数据流向《世界状态》数据库420,与图3中创建的世界状态
数据库相同。此处,具有相同密钥的较旧条目被覆盖,其中,作为世界状态数据库的关系数
据仅包含关系数据管理和组织系统100的数据库的当前状态,而账本400保留其历史。在世
界状态数据库420中示出了一个这样的对象424,但实际上将有许多密钥和对象。
[0141] 图5具有与图4类似的前提,其中,所有组件和数据对象保持不变。唯一的区别是在处理DML读操作的同时数据对象所经历的活动和进程。除了服务层在DML读操作被成功执行
之后在500处接收到查询响应之外,Fabric服务组件中的活动部分与图4相当类似。
[0142] 在示例实施方式中,系统链码在502处针对世界状态数据库实例504执行查询以及返回相关的ELEMENT数据JSON流。系统链码进一步处理该数据,以产生查询结果500返回至
查询的启动者。在世界状态数据上发生读取,因此随后不会像更新场景那样对世界状态进
行修改。DML读取不访问对等账本400。然而,除非默认的“OPSTAT”选项被覆盖,否则Fabric
交易登入在其上进行交易的对等节点的账本上,以保留操作记录。在506处,如果选择了
“OPSTAT”选项,则Fabric网络将交易处理为区块并且将该区块附加至账本400。记载的交易
包含输入,该输入为表示查询的JSON而不是由此产生的记录。
[0143] 除了查询结果直接返回至智能合约以用于其进一步处理以外,根据用户链码(智能合约)启动的DML读操作与图5类似。
[0144] 为了实现所需的五个数据库访问许可级别,重新使用了两种Fabric机制。首先,由于数据库创建需要用于创建Fabric通道的先决条件能力,因此仅Fabric网络管理者有资格
获得该许可。对于其余四个访问级别,ELEMENT Fabric在Fabric现有的身份提供者功能的
基础上进行了移植。因此,在Fabric上实现ELEMENT Fabric关系数据访问控制涉及数据库
特定属性,所述数据库特定属性在将每个用户注册到身份提供者的同时附加至每个用户。
此外,与用户注册联接的属性与其针对该数据库的特定访问有关。随后,可以启动到
ELEMENT系统链码的交易,以将用户添加至数据库元数据。
[0145] 图6是示出了用于添加用于超级管理级别以下的访问的用户的关系数据访问控制的第一部分中涉及的组件和数据的框图。控制过程涉及两个步骤。第一是通过在600处准备
记载添加用户操作以创建添加用户操作602的Fabric交易在身份提供者诸如Fabric证书机
构中注册具有数据库特定属性的用户。第二是常规交易,其在608处通过使用请求实体的权
限以将新的用户访问级别的JSON表示604附加至身份提供者606中的用户身份卡来将用户
添加至数据库本身。
[0146] 类似图3,图6是层叠在正在执行的ELEMENT Fabric服务层和相关Fabric网络的拓扑结构上的UML对象模型。UML对象对模型左侧部分提及的Fabric服务组件和相关顺序活动
以及右侧相关数据的表示进行建模,用于将用户添加至关系数据管理和组织系统100。来自
图3的模型说明和操作前提适用于此处,其中,显著添加了身份提供者诸如Fabric证书机构
节点606,但是模型中仅显示受影响的部分。UML模型与服务层、Fabric对等节点和排序服务
节点连接,为它们提供有关分布式账本身份的信息。排序服务及其连接未在该模型中显示,
这是因为它们在该过程中没有特殊作用,超出了Fabric交易处理中的通常作用。应注意,排
序服务节点和身份提供者(例如,证书机构)可能同时为其他对等节点、通道、也可能关系数
据管理和组织系统100的数据库提供服务。
[0147] 图6中的数据对象是在向一个ELEMENT数据库添加新用户期间创建的。用户的添加建立在Fabric的现有的身份管理之上,类似于数据库本身如何建立在Fabric通道及其账本
上。事实上,最高的访问级别——超级管理者——是对Fabric管理者角色的精确重用。图6
涉及添加具有四个较低ELEMENT访问级别中之一的用户。该模型可以按照其参与过程的粗
略顺序分为三个部分:
[0148] 1.ELEMENT Fabric服务层节点
[0149] 2.身份提供者节点,例如证书提供者(CA)
[0150] 3.Element Fabric对等节点和排序服务节点
[0151] 该过程的初始部分涉及这些中的前两个:ELEMENT Fabric服务层安排身份提供者(例如,Fabric证书机构606)登记用户身份或定位相关身份(如果其已经存在),并且将
ELEMENT特权属性添加只该身份。注意,有可能但未示出多个身份提供者节点可能支持给定
的通道及其ELEMENT数据库。在这种情况下,除了指定涉及哪个权限之外,该过程基本上相
同。
[0152] 《用户》对象604是该身份在身份提供者(例如,证书机构606)中的表示,有时被称为“身份卡”。其可以使用自定义属性来进行扩展,并且关系数据管理和组织系统100通过将
表示身份访问权限级别的属性添加至ELEMENT数据库添加来利用这一点。该属性采用模型
中标记为用户访问级别属性604的JSON对象的形式。
[0153] 该过程的另一部分是用于记录分布式账本612中的访问级别的变化的相应的Fabric交易610。该交易610在服务层(包含添加用户操作JSON的《fabric tx》614)中进行准
备并且被添加至过程中首先将其通过一个对等节点的《账本》612,然后是排序服务,并且最
后在616处作为附加至账本612的区块的一部分返回至所有对等节点。
[0154] 账本612与在图3至图5中示出的相同。该模型贯注于包含添加用户操作JSON 614的新《Fabric区块》,但是该区块614实际上将被附加在图3的前提和配置区块(在该模型中
被排除)以及如图4和图5示出的用于关系操作的任意数目的区块之后。
[0155] 在限定用户访问级别之后,分布式账本特定组件在每个关系数据库操作期间读取用户访问级别,以确定该操作是否被授权。关系数据库操作以两个步骤进行。由身份提供者
对身份进行验证,并且对访问级别进行检查。仅在发现调用用户的访问级别适于调用该功
能的情况下,才准许对相应功能的访问,随后如上面关于图3描述的执行实际功能。
[0156] 在Fabric实现中实现与用户智能合约所需的集成是简单的。用户链码能够直接调用ELEMENT系统链码,这给予对除批量操作之外的所有DML功能的访问。
[0157] 然而,默认的Fabric设置不允许系统链码插件。主要的改变涉及使用允许部署ELEMENT系统链代码的构建标签来重建Fabric对等端。在此之后,对等端的基本配置文件需
要在编译的ELEMENT系统链码二进制文件的路径中进行修改。这允许Fabric对等端在重启
时读取并启动ELEMENT系统链码。
[0158] Fabric‑特定服务层接受来自通用控制台/解析器/API组件的数据库命令,并且通过调用如上所述的ELEMENT系统链码、身份提供者诸如Fabric证书机构和世界状态数据库
的组合将所述数据库命令转换为动作。
[0159] ELEMENT SDK主要包括用于从开发者的 应用调用通用控制台/解析器/API组件的包装函数(wrapper function)。具体地,ELEMENT SDK提供
用于下述的包装函数:创建与关系数据管理和组织系统100的连接;执行用于限定表和索引
的DDL操作;执行用于数据写入和查询的DML操作;将自定义智能合约添加至通道。
[0160] 图7是示出ELEMENT SDK与用户的应用702的交互以及它们都被托管在其中的执行环境的框图,该执行环境被建模为用户应用节点700。该节点700涵盖广
泛的潜在实现,受限于所需的 支持以及被配置成通过HTTPS经由其REST 
ELEMENT API 104与正在运行的ELEMENT控制台108的实例进行通信的能力,如图所示。
[0161] 深入至图7中的用户应用节点700, 中的用户应用702被建模为依赖于也安装的 ELEMENT SDK 704的部件。 包装函数接口706限定
了用户的应用代码702直接可用的函数。这些接口706通常符合关于图1描述的语言特定SDK
《规范》102。然而,它们在一些方面超出了规范,支持一些附加的Fabric特定特征。这通过在
SDK名称中包括“Fabric”反映在建模中。ELEMENT_SDK 704中的代码实现该接口,将SDK函数
调用转换为对ELEMENT API 104的调用。
[0162] 除了由ELEMENT规范所需的函数以外, 实现还包括经由ELEMENTDB控制台108或语言特定SDK 102部署智能合约(用户链码)并在所创建的数据库之
间保持物理分离(在物理对逻辑意义上)的能力。
[0163] 将理解, 实施方式提供了在数据库之间具有物理分离的分布式账本上的关系数据,以及Fabric上的最大限度地重用了Fabric平台的内置属性的关系数
据实现,从而改进了性能并且降低了平台改变将引入破坏性改变的可能性。程序员友好的
SDK还将分布式账本上的关系数据的结构与使用该数据的智能合约的部署统一起来。
[0164] 本领域技术人员将理解,不支持完整的ANSI SQL语言规范,也不支持存储过程本身。然而,如果需要,用户链码提供了类似的能力来耦合逻辑和关系数据。作为示例,图8和
图9示出了使用关系数据管理和组织系统100来实现SQL DML写入和读操作。本领域技术人
员将理解,本文中所描述的技术还可以用于实现其他SQL活动,以与存储在如本文中所描述
的分布式账本上实现的数据库中的数据交互。
[0165] 图8是示例实施方式中使用关系数据管理和组织系统对分布式账本的成功的SQL DML写操作的示例的逻辑流程图。如所示的,关系数据管理和组织系统100可以通过至少三
种方式接收SQL查询:在800处,用户可以将SQL查询输入至ELEMENT UI 106中;在802处,用
户应用可以经由ELEMENT SDK 200传递SQL查询;或者在804处,智能合约可以执行SQL查询。
在806处,将所接收到的SQL查询解析成DML写操作。然后在808处,关系数据管理和组织系统
100创建SQL操作的JSON表示并且合并任何包括的关系数据的JSON表示。然后由
操作处理JSON表示(ELEMENT SQL), 操作保留了分
布式账本的身份、隐私和共识条款。这样的操作包括在810处确认调用身份至少具有DML写
入权限。关系数据管理和组织系统100然后在812处根据需要从分布式账本平台检索数据以
执行关系操作并且在814处执行该操作并准备所得的新的或改变的记录的JSON表示。在816
处,将操作和更新的记录以适合于分布式账本平台的形式提交给分布式账本平台,以保留
任何改变的记录。然后在818处,分布式账本平台将操作和数据合并至其分布式账本中。此
外,如果请求,在820处,关系数据管理和组织系统100监视分布式账本网络以获得由分布式
账本接受的操作的进展。最后,在822处,关系数据管理和组织系统100通知调用者(UI 106、
用户应用200或用户智能合约)操作成功。对于每个新的SQL DML写操作,可以重复该过程。
[0166] 另一方面,图9是示例实施方式中使用关系数据管理和组织系统100从分布式账本中成功的SQL DML读操作的示例的逻辑流程图。如所示的,关系数据管理和组织系统100可
以通过至少三种方式接收SQL查询:在900处,用户可以将SQL查询输入至ELEMENT UI 106
中;在902处,用户应用可以经由ELEMENT SDK 200传递SQL查询;或者在904处,智能合约可
以执行SQL查询。在906处,将所接收到的SQL查询解析成DML读操作。然后在908处,关系数据
管理和组织系统100创建SQL操作的JSON表示。然后由 操作处理JSON表
示(ELEMENT SQL), 操作保留了分布式账本的身份、隐私和共识条款。这
样的操作包括在910处确认调用身份至少具有DML读取权限。关系数据管理和组织系统100
然后在912处根据需要从分布式账本平台检索数据以执行读操作并且在914处执行所请求
的操作并创建查询结果的JSON表示。除非有意抑制,否则在916处,关系数据管理和组织系
统100以适合于分布式账本平台的形式将操作的JSON表示记录至分布式账本平台以保留记
录。然后在918处,分布式账本平台将操作日志合并至其分布式账本中。最后,在920处,关系
数据管理和组织系统100将查询结果的JSON表示返回给调用者(UI 106、用户应用200或用
户智能合约)。对于每个新的SQL DML读操作,可以重复该过程。
[0167] 图10是示出在Fabric实现中成功执行数据定义语言(DDL)写入的框图。这样的操作修改或扩展现有关系数据管理和组织系统数据库的模式。图左侧部分的泳道表示负责
DDL操作的部件。每个通道内的活动特定于标记的部件,并且描述部件对过程的可能贡献。
与前面的图一样,该过程的流程由可能有因果连接的步骤之间的黑体箭头表示。另外,常规
箭头将活动连接至它们可能创建或修改的数据对象,这在右侧的对象模型(由数据表示)中
描绘。
[0168] DML写操作可以由ELEMENTDB_控制台108识别和处理。例如,在1000处,ELEMENTDB_控制台108可以接收SQL命令并且将其识别为DDL。SQL命令的处理可以包括在1002处由
Element SQLDDL解析器110解析以将操作的SQL描述转换成可以在分布式账本平台上处理
和表示的形式。在1004处,可以将转换后的形式由FabricService部件进一步处理成包含期
望操作的Fabric交易,该期望操作包括数据库属性(模式)1005的更新的JSON表示,所述数
据库属性(模式)1005可以作为数据存在于部署的Fabric服务层中。在1006处,
FabricService部件还可以使所得的Fabric交易通过网络连接提交至与关系数据管理和组
织系统数据库相关联的通道中的Fabric对等节点。然后,由Fabric网络进行的正常处理将
该交易合并至区块中,并且将该区块附加至账本1020中针对该通道的先前区块1007。在这
样的附加中暗含该区块将被相同地附加至通道中的其他对等节点。因为改变的关系数据属
性可以表示为一个键值对分布式账本数据,因此在1008处,Fabric的系统链码可以随后更
新世界状态数据库条目,因为使用该较新的关系数据库属性,覆盖本应当存储在同一键下
的先前属性。在存在由DDL操作指示的索引改变的情况下,关系管理和组织系统可以在实践
中通过直接修改世界状态数据库的索引例如在1010处的 实例的索引集合
1030来影响它们。索引集合1030包含为正在执行操作的关系数据管理和组织系统数据库限
定的索引。这些改变可以由FabricService请求,由世界状态数据库的索引实现接收,并且
随后在1012处应用于《世界状态》数据库,从而导致将更新的索引应用于涉及世界状态数据
库的随后查询操作。
[0169] 计算机实施方式
[0170] 图11是典型的通用计算机1100的框图,计算机1100可以被编程至适合于实现本文中所公开的关系数据管理和组织系统100的一个或更多个实施方式的专用计算机中。上面
描述的关系数据管理和组织系统100可以在任何通用处理部件诸如具有足够处理能力、存
储器资源和通信吞吐量能力以处理置于其上的必要工作负载的计算机上实现。计算机1100
包括处理器1102(其可以被称为中央处理器单元或CPU),处理器1102与包括以下的存储器
装置通信:辅助存储器1104、只读存储器(ROM)1106、随机存取存储器(RAM)1108、输入/输出
(I/O)装置1110以及网络连接装置1112。处理器1102可以被实现为一个或更多个CPU芯片或
者可以是一个或更多个专用集成电路(ASIC)的一部分。
[0171] 辅助存储器1104通常由一个或更多个磁盘驱动器或磁带驱动器组成,并且用于数据的非易失性存储,并且在RAM 1108未大到足以保存全部工作数据的情况下作为溢出数据
存储装置。辅助存储器1104可以用于存储下述程序:所述程序在被选择以执行时被加载至
RAM 1108中。ROM 1106用于存储在程序执行期间所读取的指令以及可能的数据。ROM 1106
是非易失性存储器装置,其相对于辅助存储器1104的较大存储容量通常具有较小的存储器
容量。RAM 1108用于存储易失性数据并且可能存储指令。对ROM 1106和RAM 1108两者的访
问通常比对辅助存储器1104的访问更快。
[0172] 本文中所描述的装置可以被配置成包括存储计算机可读指令的计算机可读非暂态介质和耦接至存储器的一个或更多个处理器,并且在执行计算机可读指令时配置计算机
1100以执行上面参照图1至图10所描述的方法步骤和操作。计算机可读非暂态介质包括所
有类型的计算机可读介质,包括磁存储介质、光存储介质、闪存介质和固态存储介质。
[0173] 还应当理解,包括一个或更多个计算机可执行指令的软件可以安装在符合本公开内容的消费者和/或生产者域内的一个或更多个服务器和/或一个或更多个路由器和/或一
个或更多个装置中并与其一起销售,所述一个或更多个计算机可执行指令有助于如上参照
本公开内容的任一步骤或所有步骤描述的处理和操作。可替选地,可以获得软件并且将其
加载至符合本公开内容的消费者和/或生产者域内的一个或更多个服务器和/或一个或更
多个路由器和/或一个或更多个装置中,包括通过物理介质或分配系统,包括例如从软件创
建者所拥有的服务器或从并非由软件创建者拥有但由软件创建者使用的服务器来获得软
件。例如,软件可以被存储在服务器上以通过因特网进行分配。
[0174] 此外,本领域技术人员将理解,本公开内容的应用中不限于说明书中阐述的或附图中示出的构造细节和部件布置。本文中的实施方式能够是其他实施方式,并且能够以各
种方式实践或执行。此外,将理解,本文中使用的措辞和术语是出于描述的目的并且不应当
被认为是限制性的。本文中使用的“包括”、“包含”或“具有”及其变型意在涵盖其后列出的
项及其等同物以及另外的项。除非另有限制,否则本文中的术语“连接”、“耦接”以及“安装”
及其变型被广泛使用,并且涵盖直接和间接的连接、耦接以及安装。另外,术语“连接”和“耦
接”及其变型不限于物理或机械连接或耦接。此外,诸如上、下、底部和顶部的术语是相对
的,并且用于帮助说明,而不是限制。
[0175] 根据所示出的实施方式采用的说明性装置、系统以及方法的组成要素可以至少部分地以数字电子电路、模拟电子电路或以计算机硬件、固件、软件或其组合实现。例如,这些
组成要素可以实现为计算机程序产品诸如有形地包含在信息载体或机器可读存储装置中
的计算机程序、程序代码或计算机指令,以由数据处理设备诸如可编程处理器、一台计算机
或多台计算机执行或控制上述的数据处理设备的操作。
[0176] 计算机程序可以以包括编译或解析语言的任何形式的编程语言编写,并且它可以以任何形式来部署,包括作为独立程序或作为模块、部件、子例程或适合在计算环境中使用
的其他单元。计算机程序可以被部署成在一台计算机上或者在一个站点处的或跨多个站点
分布并通过通信网络互连的多台计算机上执行。此外,本领域技术人员可以容易地将用于
实现本文中所描述的技术的功能程序、代码以及代码段解释为在本公开内容的范围内。与
说明性实施方式相关联的方法步骤可以通过由一个或更多个可编程处理器执行计算机程
序、代码或指令以执行功能(例如,通过对输入数据进行操作并且/或者生成输出)来执行。
例如,方法步骤也可以由专用逻辑电路例如FPGA(现场可编程门阵列)或ASIC(专用集成电
路)执行,并且设备可以被实现为上述的专用逻辑电路。
[0177] 结合本文中公开的实施方式描述的各种说明性逻辑块、模块以及电路可以通过以下来实现或执行:通用处理器、数字信号处理器(DSP)、ASIC、FPGA或其他可编程逻辑器件、
分立的门或晶体管逻辑、分立硬件部件或被设计成执行本文中所描述的功能的其任意组
合。通用处理器可以是微处理器,但是可替选地,处理器可以是任何常规的处理器、控制器、
微控制器或状态机。处理器也可以被实现为计算装置的组合,例如DSP和微处理器的组合、
多个微处理器、一个或更多个微处理器与DSP内核的结合、或者任何其他这样的配置。
[0178] 适用于执行计算机程序的处理器包括作为示例的通用微处理器和专用微处理器两者以及任何种类的数字计算机的任一个或更多个处理器。通常,处理器将从只读存储器
或随机存取存储器或从上述两者接收指令和数据。计算机的基本元件是用于执行指令的处
理器以及用于存储指令和数据的一个或更多个存储器器件。通常,计算机还将包括或可操
作地耦接至用于存储数据的一个或更多个大容量存储装置例如磁盘、磁光盘或光盘以从其
接收数据或向其传送数据或两者兼具。适用于包含计算机程序指令和数据的信息载体包括
所有形式的非易失性存储器,包括作为示例的半导体存储装置,例如电可编程只读存储器
或ROM(EPROM)、电可擦除可编程ROM(EEPROM)、闪存装置以及数据存储盘(例如,磁盘、内部
硬盘或可移动盘、磁光盘以及CD‑ROM和DVD‑ROM盘)。可以由专用逻辑电路补充处理器和存
储器或者处理器和存储器可以并入专用逻辑电路中。
[0179] 本领域技术人员理解,可以使用各种不同工艺和技术中的任何工艺和技术来表示信息和信号。例如,可以通过以上描述引用的数据、指令、命令、信息、信号、比特、符号和芯
片可以通过电压、电流、电磁波、磁场或粒子、光场或粒子或其中的任何组合来表示。
[0180] 本领域技术人员还理解,结合本文中公开的实施方式描述的各种说明性逻辑块、模块、电路和算法步骤可以实现为电子硬件、计算机软件或两者的组合。为了清楚地说明硬
件和软件的这种可互换性,上面已大体上在其功能方面描述了各种说明性部件、块、模块、
电路和步骤。将此功能实现为硬件还是软件取决于施加在整个系统上的特定应用和设计约
束。技术人员可以针对每个特定应用以不同方式实现所描述的功能,但这样的实现决策不
应被解释为导致脱离本公开内容的范围。软件模块可以驻留在随机存取存储器(RAM)、闪
存、ROM、EPROM、EEPROM、寄存器、硬盘、可移动磁盘、CD‑ROM或本领域已知的任何其他形式的
存储介质中。示例性存储介质耦接至处理器,使得处理器可以从存储介质读取信息和向存
储介质写入信息。在可替选实现方式中,存储介质可以集成至处理器中。换言之,处理器和
存储介质可以驻留在集成电路中或者实现为分立部件。
[0181] 如本文中使用的,“机器可读介质”是指能够临时地或永久地存储指令和数据的装置,并且可以包括但不限于:随机存取存储器(RAM)、只读存储器(ROM)、缓冲存储器、闪存、
光学介质、磁性介质、高速缓冲存储器、其他类型的存储装置(例如,可擦除可编程只读存储
器(EEPROM))和/或其任何合适的组合。术语“机器可读介质”应被视为包括能够存储处理器
指令的单个介质或多个介质(例如,集中式或分布式数据库,或相关联的高速缓存和服务
器)。术语“机器可读介质”还应被视为包括能够存储由一个或更多个处理器执行的指令的
任何介质或多种介质的组合,以使所述指令在由一个或更多个处理器执行时使一个或更多
个处理器执行本文中所描述的任一种或更多种方法。因此,“机器可读介质”是指单个存储
设备或装置,以及包括多个存储设备或装置的“基于云”的存储系统或存储网络。本文中使
用的术语“机器可读介质”不包括信号本身。
[0182] 除了所附权利要求书中所阐述的之外,上面呈现的描述和附图旨在仅作为示例并且不旨在以任何方式限制说明性实施方式。注意,上面已经描述的各种示例性实施方式的
各种元件的各种技术方面可以以多种其他方式组合,所有这些都被认为在本公开内容的范
围内。
[0183] 因此,尽管出于说明性目的公开了示例性实施方式,但是本领域技术人员将理解各种修改、添加和替换是可能的。因此,本公开内容不限于上面描述的实施方式,而是可以
在所附权利要求书的范围内以及它们的等同物的全部范围内进行修改。
[0184] 附录A
[0185] FABRIC概述
[0186] FABRIC模型
[0187] 编入 Fabric中的实现其全面但可定制的企业分布式账本解决方案的承诺的关键设计特性包括:
[0188] ·资产——资产定义使得几乎任何有货币价值的东西都能够通过网络交换,从食物到古董车到货币期货。
[0189] ·链码——链码执行从交易排序中分离出来,限制了跨节点类型的信任和验证的请求级别,并且优化了网络的可伸缩性和性能。
[0190] ·账本特征——不可变的共享账本为每个通道编码全部交易历史,并且包括像SQL一样的查询功能,用于有效的审计和纠纷解决。
[0191] ·隐私——通道和私有数据集合使私有和机密的多边交易成为可能,这通常是相互竞争的企业和受监管的行业在公共网络上交换资产所必需的。
[0192] ·安全与成员服务——许可成员提供了可信的分布式账本网络,在该网络上,参与者知道所有的交易都可以被授权的监管机构和审计人员检测和追踪。
[0193] ·共识——独特的共识方法使能够提供企业所需的灵活性和可伸缩性。
[0194] 资产
[0195] 资产范围可以从有形(房地产和硬件)到无形(合同和知识产权)。Fabric提供了使用链码交易修改资产的能力。
[0196] 资产在 Fabric中表示为键值对的集合,其中状态改变被记录为通道账本上的交易。资产可以用二进制和/或JSON形式表示。
[0197] 可以使用Hyperledger Composer工具在 Fabric应用中定义和使用资产。
[0198] 链码
[0199] 链码是在智能合约中定义一个或多个资产的软件,以及用于修改资产的交易指令;换言之,它是业务逻辑。链码强制执行读取或改变键值对或其他状态数据库信息的规
则。链码函数针对账本的当前状态数据库执行,并通过交易提议启动。链码执行会产生一组
键值写入(写入集),这些键值写入可以提交至网络并应用于所有对等端的账本。
[0200] 链码完全没有身份。一个链码也可以调用另一链码,但是交易身份始终保持不变,作为在整个调用链中提交交易的交易签名者。因此,在Fabric网络上,设置托管账户涉及添
加外部方。因此,负责托管的外部账户必须向其余参与者证明其中立性。
[0201] 部署链码是一个两步过程。由于用于链码的可执行二进制实际上并不存在于账本中,因此必须首先将它们安装在选择支持它的每个背书对等端上。接下来,整个通道必须通
过称为“链码实例化”的步骤就要执行的链码的确切版本和交易的背书策略达成一致。提交
实例化交易的用户必须通过“实例化策略”的验证,以确保它们根据联盟成立时的预定规则
获得批准。
[0202] 链码是可升级的。它们被分配了名称和版本。升级时,将分配新的版本,并且自动继承所有现有状态。
[0203] 账本特征
[0204] 账本是fabric中所有状态变换的有序的、防篡改的记录。状态变换是参与方提交的链码调用(“交易”)的结果。每个交易都会产生一组资产键值对,这些键值对在创建、更新
或删除时提交到账本。
[0205] 账本由在区块中存储不可变的、有序的记录的区块链(“链”)和维护当前fabric状态的状态数据库组成。每个通道有一个账本。每个对等端为它们是其成员的每个通道维护
一份账本的拷贝。
[0206] Fabric账本的一些特征:
[0207] ·使用基于键的查找、范围查询和组合键查询来查询和更新账本
[0208] ·使用丰富查询语言的只读查询(如果使用 作为状态数据库)
[0209] ·只读历史查询——查询一个键的账本历史,实现数据溯源场景
[0210] ·交易由在链码(读取集)中读取的键/值和在链码(写入集)中写入的键/值的版本组成
[0211] ·交易包含每个背书对等端的签名,并且提交给排序服务
[0212] ·交易被排序进区块,并且从排序服务“传送”至通道上的对等端
[0213] ·对等端根据背书策略验证交易并强制执行策略
[0214] ·在附加区块之前,执行版本检查,以确保被读取的资产状态自链码执行时间以来没有改变
[0215] ·一旦交易被验证并提交,就存在不可变性
[0216] ·通道的账本包含定义策略、访问控制列表和其他相关信息的配置区块
[0217] ·通道包含成员服务提供者实例,允许从不同的证书颁发机构派生出加密材料
[0218] 有关数据库、存储结构和“查询能力”的深入研究,请参阅账本主题。
[0219] 隐私
[0220] Fabric使用了基于每个通道的不可变账本,以及可以操纵和修改资产当前状态(即,更新键值对)的链码。账本存在于通道的范围内——它可以跨整个网
络共享(假设每个参与者都在一个公共通道上操作)——或者它可以私有化,以只包括特定
的一组参与者。
[0221] 在后一场景中,这些参与者将创建单独的通道,从而隔离/分离它们的交易和账本。为了解决想要弥合完全透明与隐私之间差距的场景,链码只能安装在需要访问资产状
态以执行读写的对等端上(换言之,如果链码没有安装在对等端上,它将无法与账本正确连
接)。
[0222] 当该通道上的组织子集需要对其交易数据保密时,使用私有数据集合(集合)将该数据分离至私有数据库中,在逻辑上与通道账本分开,仅可由授权的组织子集访问。
[0223] 因此,通道使更广泛的网络中的交易保持私有,而集合使通道上的组织子集之间的数据保持私有。
[0224] 为了进一步混淆数据,可以使用通用的加密算法诸如AES对链码内的值进行加密(部分或全部),然后将交易发送至排序服务,并向账本附加区块。一旦加密数据被写入至账
本,它只能由拥有对应密钥的用户解密,该密钥用于生成密码文本。有关链码加密的更多详
细信息,请参阅针对开发人员的链码主题。
[0225] 在Fabric中,私有状态是在背书阶段通过对等端执行私有交易来计算的,并且所得的私有状态由哈希和输入表示。因此,共识之后所有节点上的一致的哈希保证了私有交
易的参与节点始终同意私有状态。
[0226] Fabric还提供完整的数据隔离作为另一种隐私技术,具有“通道”的概念。Fabric通道可以被认为是分开的区块链,因为每个通道都维护其完全分开的账本实例,并在该通
道的参与节点之间共享。如果联盟主要关注双边交易,就像大多数金融工具的情况一样,通
道的数目会变得相当大:O(N^2),其中N是联盟中的参与者的数目。
[0227] 有关如何在区块链网络上实现隐私的更多详细信息,请参阅私有数据主题。
[0228] 安全与成员服务
[0229] Fabric支持所有参与者都具有已知身份的交易网络。公钥基础设施用于生成与组织、网络部件和最终用户或客户端应用相关的加密证书。因此,可以在更
广泛的网络和通道级别上操纵和管理数据访问控制。 Fabric的这种“许
可”概念,结合通道的存在和功能,有助于解决高度关注隐私和机密性的场景。
[0230] 请参阅成员服务提供者(MSP)主题,以更好地了解加密实现以及Fabric中使用的签名、验证、身份验证方法。
[0231] 共识
[0232] 在分布式账本技术中,共识最近已经成为在单个函数内特定算法的同义词。然而,共识不仅仅包括就交易顺序达成一致,而且这种差异在 Fabric中通过其
在整个交易流程——从提议和背书,到排序、验证和承诺——中的基本作用得到了突出体
现。简而言之,共识被定义为对包括区块的一组交易的正确性进行全圈验证。
[0233] Fabric在其共识模型中容忍而非消除非确定性。Fabric为智能合约提供完整的语言作为设计原则。Fabric链码可以用三种完整的语言运行时编写:Golang、 和
Java。这是通过采用执行‑排序‑验证共识设计实现的,使得区块链系统可以在开发人员继
续完善逻辑和实现的同时,承受由非确定性链码造成的不良交易。
[0234] 图12所示的“先执行后排序”设计意味着某种并发版本控制是必要的,否则,当多个交易试图并行修改相同的状态值时,后一交易将覆盖较早交易并且清除来自较早交易的
状态转移,而不是建立在较早交易的结果上。Fabric采用了从数据库设计中借用的多版本
并发控制(MVCC)技术。当执行智能合约时,链码引擎会跟踪正在查看(在读取集中)和更新
(在写入集中)的状态值。在验证阶段期间,其中区块内包含的每个交易都被验证并应用状
态转移,如果交易在其读取集中的状态值版本与当前版本不匹配,通常是因为它们已经被
区块中的较早交易更新,则该交易被标记为无效。
[0235] 这意味着如果一系列交易需要修改相同的状态值,则必须对它们进行监管,使得在单个区块中不会有超过一个交易。否则,由于并发修改,应用将观察到大量无效交易。
[0236] 存在围绕该限制进行编程的技术,诸如利用复合密钥功能为每个交易组装唯一密钥,同时有能力将针对相同底层状态变量的密钥组合在一起。
[0237] 当区块交易的排序和结果满足明确的策略标准检查时,最终达成共识。这些检查和平衡发生在交易的生命周期期间,并且包括使用背书策略来规定哪些特定成员必须背书
某个交易类,以及系统链码以确保这些策略得到强制执行和维护。在承诺之前,对等端将使
用这些系统链码来确保存在足够的背书,并且它们衍生于适当的实体。此外,在将包含交易
的任何区块附加至账本之前,将进行版本检查,在此期间对账本的当前状态达成一致或同
意。该最终检查提供对双花操作和可能危及数据完整性的其他威胁的保护,并且允许对非
静态变量执行函数。
[0238] 除了进行大量的背书、有效性和版本检查之外,还有在交易流程的所有方向上发生的正在进行的身份验证。访问控制列表在网络的分层层上实现(将服务排序到通道),并
且当交易提议通过不同的架构部件时,有效载荷被重复签名、验证和身份验证。综上所述,
共识不仅限于达成一致的一批交易排序;相反,它是作为在交易从提议到承诺的历程期间
发生的正在进行的验证的副产品而实现的总体特性。
[0239] 操作治理
[0240] 治理是围绕协议运行时的过程和策略,以确保联盟成员组织适当参与决策过程。
[0241] Fabric在架构的每一层都内置了许可治理。诸如创建新联盟、添加或驱逐成员、限定新通道、从通道中添加和驱逐参与者的操作都需要从适当的组织收集批准签名。总体策
略模型在整个系统中强制执行。
[0242] Fabric具有两个级别的许可和治理支持:联盟和通道。排序者管理有关联盟级别的策略和配置。每个Fabric区块链网络都从限定组织和联盟的创世区块配置中的排序者引
导程序开始。对等端管理有关通道级别的策略和配置。修改配置,诸如向联盟或通道添加新
成员组织,需要根据修改策略收集签名:现有成员的任一、所有或大多数。
[0243] Fabric架构本身允许分散的排序者实现。事实上,随着1.4版中引入基于Raft的排序者实现,不再需要将排序节点与集中式排序引擎配对。每个排序节点本身就是Raft对等
端,并且可以在当前领导者崩溃或无法访问的情况下参与领导者选举。这允许更分散的部
署,在该部署中,不止一个组织可以操作排序节点并且参与共识和提议区块。
[0244] 对等端
[0245] 区块链网络主要由一组对等节点(或简称为对等端)组成。对等端是网络的基本元素,因为它们托管账本和智能合约。账本不可变地记录由智能合约生成的所有交易(在
Fabric中,这些交易包含在链码中)。智能合约和账本分别用于将共享过
程和共享信息封装在网络中。对等端的这些方面使它们成为了解Fabric网络的良好起点。
[0246] 区块链网络的其他元素当然也很重要:账本和智能合约、排序者、策略、通道、应用、组织、身份和成员。本节贯注于对等端以及它们与Fabric网络中那些其他元素的关系。
[0247] 图13示出了由对等节点组成的区块链网络,对等节点中的每一个都可以托管账本的拷贝和智能合约的拷贝。在该示例中,网络N由对等端P1、P2和P3组成,对等端中的每一个
都维护它们自己的分布式账本L1的实例。P1、P2和P3使用相同的链码S1来访问它们的分布
式账本拷贝。
[0248] 可以创建、启动、停止、重新配置以及甚至删除对等端。它们公开了使管理员和应用能够与它们提供的服务进行交互的一组API。
[0249] 有关术语的单词
[0250] Fabric使用链码实现智能合约——只是访问账本的一段代码,用受支持的编程语言中的一种编写。
[0251] 账本和链码
[0252] 对等端托管账本和链码两者。更准确地,对等端实际上托管账本的实例和链码的实例。请注意,这在Fabric网络中提供了有意的冗余——它避免了单点故障。
[0253] 图14示出了托管账本实例和链码实例的对等端。在该示例中,P1托管账本L1的实例和链码S1的实例。单个对等端上可以托管有许多账本和链码。
[0254] 因为对等端是账本和链码的宿主,因此如果应用和管理员想要访问这些资源,他们必须与对等端交互。这就是为何对等端被认为是Fabric网络最基本的构建块的原因。当
首次创建对等端时,它既没有账本也没有链码。
[0255] 多个账本
[0256] 对等端能够托管不止一个账本,这很有帮助,因为它允许灵活的系统设计。最简单的配置是让对等端管理单个账本,但是在需要时让对等端托管两个或更多个账本是绝对合
适的。
[0257] 图15示出了托管多个账本的对等端。对等端托管一个或更多个账本,并且每个账本具有适用于它们的零个或更多个链码。在该示例中,可以看到对等端P1托管账本L1和L2。
账本L1使用链码S1访问。另一方面,账本L2可以使用链码S1和S2访问。
[0258] 尽管对等端完全有可能在不托管访问该账本的任何链码的情况下托管账本实例,但是以这种方式配置对等端很少有。绝大多数对等端上安装有至少一个链码,该链码可以
查询或更新对等端的账本实例。值得一提的是,无论用户是否安装了供外部应用使用的链
码,对等端也有始终存在的特殊系统链码。
[0259] 多个链码
[0260] 对等端拥有的账本的数目与可以访问该账本的链码的数目之间没有固定的关系。对等端可以有可供它使用的许多链码和许多账本。
[0261] 图16示出了托管多个链码的对等端的示例。每个账本可以具有访问它的许多链码。在该示例中,可以看到对等端P1托管账本L1和L2,其中,L1由链码S1和S2访问,而L2由S1
和S3访问。S1可以访问L1和L2两者。
[0262] 应用和对等端
[0263] 账本查询交互涉及应用与对等端之间的简单三步对话;账本更新交互涉及稍微多些,并且需要两个额外的步骤。
[0264] 应用在它们需要访问账本和链码时总是连接至对等端。Fabric软件开发工具包(SDK)使这对于程序员而言变得容易——其API使应用能够连接至对等端、调用链码以生成
交易、将交易提交至将被排序并提交至分布式账本的网络、并且在该过程完成时接收事件。
[0265] 通过对等连接,应用可以执行链码以查询或更新账本。账本查询交易的结果会立即返回,而账本更新涉及应用、对等端与排序者之间更复杂的交互。
[0266] 图17示出了与排序者一起确保账本在每个对等端上保持最新的对等端。在该示例中,应用A连接至P1并且调用链码S1来查询或更新账本L1。P1调用S1以生成包含查询结果或
提议的账本更新的提议响应。应用A接收提议响应,并且对于查询,该过程现已完成。对于更
新,A从所有响应中构建交易,A将其发送至O1进行排序。O1将来自整个网络的交易收集至区
块中,并且将这些分发给所有对等端,包括P1。P1验证交易,然后应用于L1。一旦L1更新,P1
生成事件,由A接收,以表示完成。
[0267] 对等端可以立即将查询结果返回给应用,这是因为满足查询所需的所有信息都在对等端的本地账本拷贝中。对等端从不咨询其他对等端以响应来自应用的查询。然而,应用
可以连接至一个或更多个对等端以发出查询;例如,在多个对等端之间证实结果,或者如果
怀疑信息可能已过时,则从不同的对等端检索更多最新的结果。在图中,可以看到账本查询
是简单的三步过程。
[0268] 更新交易以与查询交易相同的方式启动,但是具有两个额外的步骤。尽管账本更新应用也连接至对等端来调用链码,但是与账本查询应用不同,单个对等端此时无法执行
账本更新,这是因为其他对等端必须首先同意改变——这个过程称为共识。因此,对等端向
应用返回提议的更新——该对等端将在其他对等端事先同意的情况下应用该更新。第一个
额外的步骤——步骤四——要求应用向整个对等网络发送一组适当的匹配提议更新,作为
对其各自账本的承诺的交易。这是通过应用使用排序者将交易封装至区块中,并将它们分
发至整个对等网络来实现的,其中,它们可以在应用至每个对等端的本地账本拷贝之前进
行验证。由于这整个排序处理需要一些时间(秒)完成,因此异步通知应用,如步骤5所示。
[0269] 对等端和通道
[0270] 对等端经由通道——区块链网络中的一组部件可以通过其进行私密通信和交易的机制——彼此交互,并与应用交互。
[0271] 这些部件通常是对等节点、排序节点和应用,并且通过加入通道,它们同意协作以共同共享和管理与该通道相关联的账本的相同拷贝。从概念上讲,可以将通道视为类似于
朋友组。一个人可以有若干组朋友,其中每个组都有他们一起做的活动。这些组可能是完全
独立的(一组工作朋友与一组爱好朋友相比),或者他们之间可以有一些交叉。然而,每个组
都是自己的实体,具有某种“规则”。
[0272] 图18示出了允许一组特定的对等端和应用在区块链网络内彼此通信的通道。在该示例中,应用A可以使用通道C直接与对等端P1和P2通信。可以将通道视为特定应用与对等
端之间的通信路径。(为简单起见,排序者未在该图中示出,但是必须存在于正常运行的网
络中。)
[0273] 通道的存在方式与对等端不同——将通道视为由物理对等端的集合形成的逻辑结构更为合适。对等端提供用于访问和管理通道的控制点。
[0274] 对等端和组织
[0275] 区块链网络由组织的集合而非单个组织管理。对等端是构建这种分布式网络的核心,这是因为它们由这些组织拥有,并且是到这些组织的网络的连接点。
[0276] 图19示出了具有多个组织的区块链网络中的对等端。区块链网络是由不同组织拥有和贡献的对等端建立的。在该示例中,看到四个组织贡献了八个对等端来形成网络。通道
C连接网络N中的五个对等端——P1、P3、P5、P7和P8。由这些组织拥有的其他对等端尚未加
入该通道,但是通常至少加入了一个其他通道。由特定组织开发的应用将连接至它们自己
组织的对等端以及不同组织的对等端。同样,为简单起见,排序节点未在该图中示出。
[0277] 该网络由为其贡献资源的多个组织形成和管理。对等端是在本主题中讨论的资源,但是组织提供的资源不只是对等端。在此有一个原则在起作用——在没有组织将其个
体资源贡献给集体网络的情况下,网络实际上就不存在。此外,网络随着由这些协作组织提
供的资源而增长和缩小。
[0278] 除了排序服务之外,没有中心化资源——在上面的示例中,如果组织没有贡献它们的对等端,网络N将不存在。这反映了以下事实:除非且直到组织贡献形成网络的资源,否
则网络在任何意义上都不存在。此外,网络不依赖于任何单独组织——只要一个组织留下,
它就将继续存在,无论其他组织可能来来去去。这是网络去中心化意味着什么的核心。
[0279] 不同组织中的应用——如在上面的示例中——可能相同或可能不同。这是因为其应用如何处理它们的对等端的账本拷贝完全取决于组织。这意味着应用和表示逻辑两者可
能因组织而异,即使它们各自的对等端托管完全相同的账本数据也是如此。
[0280] 应用连接至其组织中的对等端,或连接至另一组织中的对等端,这取决于所需的账本交互的性质。对于账本查询交互,应用通常连接至其自己组织的对等端。对于账本更新
交互,应用需要连接至表示需要背书账本更新的每个组织的对等端。
[0281] 对等端和身份
[0282] 对等端具有经由来自特定证书颁发机构的数字证书分配给它们的身份。数字证书就像身份证一样,提供了有关对等端的很多可验证信息。网络中的每一个和每个对等端都
由其拥有组织中的管理员分配了数字证书。
[0283] 图20示出当对等端连接至通道时,其数字证书经由通道MSP标识其拥有组织。在该示例中,P1和P2具有由CA1颁发的身份。通道C根据其通道配置中的策略确定来自CA1的身份
应当使用ORG1.MSP与Org1相关联。类似地,P3和P4由ORG2.MSP标识为Org2的一部分。
[0284] 每当对等端使用通道连接至区块链网络时,通道配置中的策略使用对等端的身份来确定其权利。身份到组织的映射由称为成员服务提供者(MSP)的部件提供——它确定对
等端如何被分配至特定组织中的特定角色,并且因此获得对区块链资源的适当访问。此外,
对等端只能由单个组织拥有,并且因此与单个MSP相关联。MSP在区块链网络中提供个人身
份与特定组织角色之间的联系。
[0285] 对等端以及与区块链网络交互的所有事物都从其数字证书和MSP中获取其组织身份。对等端、应用、最终用户、管理员和排序者如果想要与区块链网络交互,则必须具有身份
和相关联的MSP。使用身份——主体——与区块链网络交互的每个实体都被赋予名称。
[0286] 对等端的物理位置并不重要——它可以驻留在云中,或者驻留在由组织之一拥有的数据中心中,或者驻留在本地机器上——与其相关联的身份将其标识为由特定组织拥
有。在上面的示例中,P3可以托管在Org1的数据中心,但是只要与之相关联的数字证书是由
CA2颁发的,则它就由Org2拥有。
[0287] 对等端和排序者
[0288] 应用和对等端彼此交互以确保每个对等端的账本保持一致的机制是由称为排序者的特殊节点调解的。
[0289] 更新交易与查询交易完全不同,这是因为单个对等端无法自行更新账本——更新需要网络中其他对等端的同意。对等端需要网络中的其他对等端批准账本更新,然后将其
应用于对等端的本地账本。该过程称为共识,它比简单的查询需要长得多的时间来完成。但
是当需要批准交易的所有对等端都这样做并且交易被提交至账本时,对等端将通知其连接
的应用账本已经更新。
[0290] 具体地,想要更新账本的应用涉及3阶段过程,这确保了区块链网络中的所有对等端保持它们的账本彼此一致。在第一阶段,应用与背书节点的子集一起工作,每个节点都为
应用提供对提议的账本更新的背书,但是不将提议的更新应用于其账本拷贝。在第二阶段,
将这些单独的背书收集在一起作为交易并且封装至区块中。在最后阶段,将这些区块分发
回每个对等端,其中,在将每个交易应用于该对等端的账本拷贝之前,每个节点都经过验
证。
[0291] 排序节点是该过程的核心。应用和对等端使用排序者来生成账本更新,这些更新可以一致地应用于分布式、复制的账本。
[0292] 阶段1:
[0293] 交易工作流的阶段1涉及应用与一组对等端之间的交互——它不涉及排序者。阶段1只涉及应用要求不同组织的背书节点同意提议的链码调用的结果。
[0294] 为了开始阶段1,应用生成交易提议,应用将该交易提议发送至所需的一组对等端中的每一个以供背书。然后,这些背书对等端中的每一个都使用交易提议独立地执行链码
以生成交易提议响应。其不会将该更新应用于账本,而是简单地对其进行签名并将其返回
给应用。一旦应用接收到足够数目的签名提议响应,交易流程的第一阶段就完成了。
[0295] 图21示出了由返回背书提议响应的对等端独立执行的交易提议。在该示例中,应用A1生成交易T1提议P,应用A1将交易T1提议P发送至通道C上的对等端P1和对等端P2两者。
P1使用交易T1提议P执行S1,生成交易T1响应R1,它与E1背书。独立地,P2使用交易T1提议P
执行S1,生成交易T1响应R2,它与E2背书。应用A1接收到针对交易T1的两个背书响应,即E1
和E2。
[0296] 最初,应用选择一组对等端来生成一组提议的账本更新。由应用选择的对等端取决于背书策略(针对链码限定),该策略限定了在提议的账本改变可以被网络接受之前需要
对其进行背书的一组组织。这是达成共识的字面意思——每个重要的组织都必须在提议的
账本改变被接受到任何对等端的账本之前对其进行背书。
[0297] 对等端通过添加其数字签名并使用其私钥签署整个有效载荷来背书提议响应。该背书随后可以用于证明该组织的对等端生成了特定响应。在上面的示例中,如果对等端P1
由组织Org1拥有,则背书E1对应于“账本L1上的交易T1响应R1已经由Org1的对等端P1提供”
的数字证明。
[0298] 当应用从足够的对等端接收到签名的提议响应时,阶段1结束。针对相同的交易提议,不同的对等端可以向应用返回不同的并且因此不一致的交易响应。这可能只是结果是
在具有不同状态的账本的不同对等端上在不同时间生成的,在这种情况下,应用可以简单
地请求更多最新的提议响应。不太可能,但是严重得多的是,结果可能不同,这是因为链码
是非确定的。非确定性是链码和账本的敌人,并且如果其发生,则表明提议的交易存在严重
问题,这是因为不一致的结果显然不能应用于账本。单独的对等端无法知道它们的交易结
果是非确定的——在可以检测到非确定性之前,必须将交易响应收集在一起进行比较。
[0299] 在阶段1结束时,应用可以随意丢弃不一致的交易响应,如果它愿意这样做的话,从而有效地提前终止交易工作流。如果应用尝试使用一组不一致的交易响应来更新账本,
其将被拒绝。
[0300] 阶段2:将交易排序并且封装至区块中
[0301] 交易工作流的第二阶段是封装阶段。排序者是该过程的关键——其从许多应用接收包含背书交易提议响应的交易,并且将交易排序至区块中。有关排序和封装阶段的更多
详细信息,请查看有关排序阶段的概念信息。
[0302] 阶段3:验证和提交
[0303] 在阶段2结束时,排序者负责收集提议的交易更新、对它们进行排序并且将它们封装至区块中以准备分发给对等端的简单但重要的过程。
[0304] 交易工作流的最后阶段涉及从排序者到对等端的区块的分发和随后验证,其中,它们可以应用于账本。具体地,在每个对等端处,区块内的每个交易都经过验证,以确保在
将其应用于账本之前,其已经得到所有相关组织的一致背书。失败的交易将保留以供审核,
但是不会应用于账本。
[0305] 图22示出了排序节点的第二角色,即向对等端分发区块。在该示例中,排序者O1将区块B2分发给对等端P1和对等端P2。对等端P1处理区块B2,致使新区块被添加至P1上的账
本L1。并行地,对等端P2处理区块B2,致使新区块被添加至P2上的账本L1。一旦该过程完成,
账本L1就会在对等端P1和P2上一致更新,并且每个对等端都可以通知连接的应用交易已经
处理。
[0306] 阶段3从排序者将区块分发给与其连接的所有对等端开始。对等端连接至通道上的排序者,使得当生成新区块时,将向连接至排序者的所有对等端发送新区块的拷贝。每个
对等端将独立地处理该区块,但是方式与通道上的每个其他对等端完全相同。这样,账本就
可以保持一致。此外,并非每个对等端都需要连接至排序者——对等端可以使用gossip协
议将区块级联至其他对等端,其他对等端也可以独立地处理它们。
[0307] 在接收到区块后,对等端将按照其在区块中出现的顺序处理每个交易。对于每个交易,每个对等端都将根据生成交易的链码的背书策略验证该交易是否已经得到所需组织
的背书。例如,一些交易可能只需要由单个组织背书,而另一些交易可能需要多次背书才能
被认为是有效的。该验证过程验证所有相关组织是否生成了相同的成果或结果。另请注意,
该验证与阶段1中的背书检查不同,在阶段1中的背书检查中,应用从背书对等端接收响应
并且决定发送提议交易。如果应用通过发送错误的交易违反了背书策略,对等端仍然能够
在阶段3的验证过程中拒绝该交易。
[0308] 如果交易已经被正确背书,则对等端将尝试将其应用于账本。为此,对等端必须执行账本一致性检查,以验证账本的当前状态与生成提议更新时账本的状态兼容。这可能并
不总是可能的,甚至当交易已经被完全背书。例如,另一交易可能已经更新了账本中的相同
资产,使得交易更新不再有效,并且因此无法再应用。通过这种方式,每个对等端的账本拷
贝在整个网络中保持一致,这是因为它们均遵循相同的验证规则。
[0309] 在对等端成功验证每个单独的交易之后,它会更新账本。失败的交易不应用于账本,但是它们会被保留用于审计目的,成功的交易也是如此。这意味着对等端区块与从排序
者接收到的区块几乎完全相同,除了区块中每个交易上的有效或无效指示符。
[0310] 阶段3不需要运行链码——这仅在阶段1期间进行,并且这很重要。这意味着链码只能在背书节点上可用,而不是在整个区块链网络中可用。这通常很有帮助,因为它使链码
的逻辑对背书组织保密。这与与通道中的每个对等端共享的链码的输出(交易提议响应)形
成对比,无论他们是否背书交易。这种背书对等端的专业化被设计成帮助可扩展性。
[0311] 最后,每次将区块提交至对等端的账本时,该对等端都会生成适当的事件。区块事件包括完整的区块内容,而区块交易事件仅包括摘要信息,诸如区块中的每个交易是否已
经被验证或失效。链码执行产生的链码事件此时也可以发布。应用可以注册这些事件类型,
使得在它们发生时通知它们。这些通知结束了交易工作流的第三和最后阶段。
[0312] 总而言之,阶段3会看到由排序者生成的区块一致地应用于账本。交易到区块的严格排序允许每个对等端验证交易更新是否跨区块链网络一致应用。
[0313] 排序者和共识
[0314] 该整个交易工作流程被称为共识,这是因为在由排序者调解的过程中,所有对等端都已就交易的顺序和内容达成一致。共识是多步过程,并且应用仅在过程完成时被通知
账本更新——这可能发生在不同对等端的略有不同的时间。
[0315] 因此,排序者可以被认为是从应用收集和分发提议的账本更新以供对等端验证并包括在账本中的节点。另一方面,对等端形成网络、托管链码和账本、处理交易提议和响应、
并且通过一致地对其应用交易更新来保持账本最新。
[0316] 世界状态
[0317] 世界状态是托管一组账本状态的当前值的缓存的数据库。世界状态使程序容易直接访问状态的当前值,而不必通过遍历整个交易日志来计算它。默认情况下,账本状态被表
示为键值对。世界状态可以频繁改变,这是因为可以创建、更新和删除状态。
[0318] 世界状态将业务对象的属性的当前值保存为唯一的账本状态。这很有用,因为程序通常需要对象的当前值;遍历整个区块链来计算对象的当前值会很麻烦——只需从世界
状态中直接获取它。
[0319] 图23示出了包含两个状态的账本世界状态。第一状态是:键=CAR1和值=奥迪。第二状态具有更复杂的值:键=CAR2和值={模型:宝马,颜色=红色,拥有者=Jane}。两个状
态都是版本0。
[0320] 账本状态记录有关特定业务对象的一组事实。上面的示例示出了针对两辆汽车CAR1和CAR2的账本状态,每个具有键和值。应用程序可以调用智能合约,该智能合约使用简
单的账本AP1来获取、放置和删除状态。请注意状态值如何可以是简单的(奥迪……)或复合
的(类型:宝马……)。通常查询世界状态以检索具有某些属性的对象,例如查找所有红色宝
马。
[0321] 世界状态实现为数据库。数据库针对有效存储和检索状态提供了一组丰富的操作符。 Fabric可以被配置成使用不同的世界状态数据库来解决不同类型状
态值的需求以及应用所需的访问模式,例如在复杂查询中。
[0322] 应用提交捕获世界状态改变的交易,并且这些交易最终被提交至账本区块链。Fabric SDK将应用与该共识机制的细节隔离开来;他们只是调用智能合
约,并且在交易被包括在区块链中时得到通知(无论是有效还是无效)。关键的设计点是,仅
由所需的一组背书组织签署的交易将致使世界状态的更新。如果交易没有由足够的背书者
签署,则它将不会致使世界状态的改变。
[0323] 状态具有版本号,并且在上面的图中,状态CAR1和CAR2处于它们的起始版本0。版本号供 Fabric内部使用,并且每次状态改变时都会增加。每当状态更新时
都会检查版本,以确保当前状态与背书时的版本匹配。这确保了世界状态按预期改变;没有
并发更新。
[0324] 最后,当首次创建账本时,世界状态是空的。因为表示世界状态有效改变的任何交易都记录在区块链上,这意味着可以随时从区块链重新生成世界状态。这可能非常方
便——例如,在创建对等端时会自动生成世界状态。此外,如果对等端发生异常故障,则在
接受交易之前,可以在对等端重启时重新生成世界状态。
[0325] 世界状态在物理上实现为数据库,以提供简单且有效的账本状态存储和检索。账本状态可以具有简单的或复合的值,并且为了适应这一点,世界状态数据库实现可能不同,
从而允许有效地实现这些值。针对世界状态数据库的选项目前包括LevelDB和
[0326] LevelDB是默认值,并且当账本状态是简单的键值对时特别合适。LevelDB数据库与网络节点紧密共存——其嵌入在同一操作系统进程内。
[0327] 当账本状态被构建为JSON文档时, 是特别合适的选择,这是因为支持业务交易中常见的更丰富的数据类型的丰富查询和更新。在实现方面,
在单独的操作系统进程中运行,但是对等节点与 实例之间仍
然存在1:1的关系。所有这些对于智能合约都是不可见的。
[0328] 在LevelDB和 中,看到了 Fabric的重要方面——它是可插拔的。世界状态数据库可以是关系数据存储、或图形存储、或时态数据库。这为可以
有效访问的账本状态的类型提供了极大的灵活性,从而使 Fabric能够解
决许多不同类型的问题。
[0329] 在 Fabric中,每个通道都有完全独立的账本。这意味着完全独立的区块链和完全独立的世界状态,包括命名空间。应用和智能合约可以在通道之间进行通
信,以便可以在它们之间访问账本信息。
[0330] 作为状态数据库
[0331] 是可选的替代外部状态数据库。 可以存储在链码中建模的任何二进制数据( 附件功能在内部用于非JSON二进制数据)。但是作为
JSON文档存储,当链码值(例如,资产)被建模为JSON数据时, 另外支持对链码
数据进行丰富的查询。
[0332] 支持核心链码操作,诸如获取和设置键(资产)以及基于键的查询。可以按范围查询键,并且可以对复合键进行建模以启用针对多个参数的等效查询。例如,拥
有者的复合键资产_id可以用于查询由某个实体拥有的所有资产。这些基于键的查询可以
用于针对账本的只读查询,以及更新账本的交易。
[0333] 如果将资产建模为JSON并且使用 还可以使用链码内的JSON查询语言对链码数据值执行复杂的丰富查询。这些类型的查询非常适合
了解账本上的内容。针对这些类型的查询的提议响应通常对客户端应用有用,但是通常不
会作为交易提交给排序服务。事实上,对于丰富查询,并不能保证结果集在链码执行与提交
时间之间是稳定的,并且因此丰富查询不适合用于更新交易,除非应用可以保证结果集在
链码执行时间与提交时间之间是稳定的,或可以处理随后交易中的潜在改变。例如,如果对
由Alice拥有的所有资产执行丰富查询并且将它们转移给Bob,则在链码执行时间与提交时
间之间的另一交易可能会将新资产分配给Alice,并且会错过这个“幻影”项目。
[0334] 作为单独的数据库进程与对等端一起运行,因此在设置、管理和操作方面还有其他注意事项。将链码资产数据建模为JSON是很好的做法,以便如果将来需要,
可以选择执行复杂的丰富查询。
[0335] 使用来自链码的
[0336] 链码查询
[0337] 大多数链码填充API可以与 状态数据库一起使用,例如获取状态、放置状态、按范围获取状态、通过部分复合键获取状态。另外,当在链码中使用
作为状态数据库和模型资产作为JSON时,可以通过使用获取查询结果API并且传递
查询字符串对状态数据库中的JSON执行丰富查询。查询字符串遵循CouchDB 
JSON查询语法。
[0338] 大理石02样本演示了使用来自链码的 查询。它包括按拥有者查询大理石()函数,该函数通过将拥有者id传递至链码中来演示参数化查询。然后,它使用JSON
查询语法查询与“大理石”的文档类型和拥有者id匹配的JSON文档的状态数据:
[0339] {“选择器”:{“文档类型”:“大理石”,“拥有者”:<拥有者_ID>}} 分页
[0340] Fabric支持对丰富查询和基于范围的查询的查询结果进行分页。支持分页的API允许使用页面大小和书签用于范围查询和丰富查询两者。为了支持有效分页,必须使用
Fabric分页API。具体地, 限制关键字将不会在 查询中得到遵
守,这是因为Fabric本身管理查询结果的分页并且隐式设置传递至 的页面大
小限制。
[0341] 如果使用分页查询API指定了页面大小
[0342] (使用分页按范围获取状态(),
[0343] 使用分页通过部分复合键获取状态(),和
[0344] 使用分页获取查询结果()),一组结果(受页面大小约束)将与书签一起返回至链码。书签可以从链码返回至调用客户端,调用客户端可以在后续查询中使用书签来接收下
一“页”结果。
[0345] 分页API仅用于只读交易,查询结果旨在支持客户端分页要求。对于需要读取和写入的交易,使用非分页链码查询API。在链码内,可以将结果集迭代至期望深度。
[0346] 无论是否使用分页API,所有链码查询都受core.yaml中的总查询限制(默认100000)约束。这是链码将迭代并返回至客户端的最大结果数,以避免意外或恶意的长时间
运行的查询。
[0347] 索引
[0348] 中的索引是必需的以使JSON查询高效,并且是带有排序的任何JSON查询所必需的。索引可以与链码一起封装在/META‑INF/statedb/couchdb/索引目录中。每
个索引都必须在其自己的文本文件中定义,其中扩展名为*.json,索引定义格式为JSON,遵
循CouchDB索引JSON语法。例如,为了支持上面的大理石查询,提供了文档类型和拥有者字
段的样本索引:
[0349] {“索引”:{“字段”:[“文档类型”,“拥有者”]},“ddoc”:“索引拥有者文档”,
[0350] “名称”:“索引拥有者”,“类型”:“json”}
[0351] 链码的META‑INF/statedb/couchdb/索引目录中的任何索引都将与链码封装以进行部署。当链码既安装在对等端上且在对等端的通道之一上实例化时,索引将自动部署至
对等端的通道和链码特定状态数据库(如果已经被配置成使用 )。如果先安装
链码,并且然后在通道上实例化链码,则索引将在链码实例化时间部署。如果链码已经在通
道上实例化,并且稍后在对等端上安装链码,则索引将在链码安装时间部署。
[0352] 在部署后,链码查询将自动使用索引。 可以基于查询中使用的字段自动地确定要使用的索引。可替选地,在选择器查询中,可以使用使用_索引关键字指定索
引。
[0353] 安装的链码的随后版本中可能存在相同的索引。为了改变索引,请使用相同的索引名称但是改变索引定义。在安装/实例化后,索引定义将重新部署至对等端的状态数据
库。
[0354] 如果已经有大量数据,并且稍后安装链码,则安装时的索引创建可能需要一些时间。类似地,如果已经有大量数据,并且实例化链码的随后版本,则索引创建可能需要一些
时间。避免在这些时间调用查询状态数据库的链码函数,这是因为链码查询可能会在索引
初始化时超时。在交易处理期间,当区块提交至账本时,索引将自动刷新。
[0355] 配置
[0356] 通过将状态数据库配置选项从goleveldb改变为 将启用为状态数据库。另外,couchDB地址需要被配置成指向对等端要使用的
如果 被配置有用户名和密码,则用户名和密码属性应当用管理员用户名和密
码填充。其他选项在couchDB配置部分中提供,并且在适当的位置进行了记录。对core.yaml
的改变将在重新启动对等端之后立即生效。
[0357] 还可以传入docker环境变量来覆盖core.yaml值,例如核心_账本_状态_状态数据库和核心_账本_状态_COUCHDB配置_COUCHDB地址。
[0358] 下面是core.yaml中的状态数据库部分:
[0359] 状态:
[0360] #状态数据库——选项是“goleveldb”、“CouchDB”
[0361] #goleveldb——存储在goleveldb中的默认状态数据库。
[0362] #CouchDB——在CouchDB中存储状态数据库
[0363] 状态数据库:goleveldb
[0364] #限制每个查询返回的记录数
[0365] 总查询限制:10000
[0366] couchDB配置:
[0367] #建议在与对等端相同的服务器上运行CouchDB,以及
[0368] #不要将CouchDB容器端口映射至docker‑compose中的服务器端口。
[0369] #否则,必须在之间的连接上提供适当的安全性
[0370] #CouchDB客户端(在对等端上)和服务器。
[0371] CouchDB地址:CouchDB:5984
[0372] #该用户名必须对CouchDB有读写权限
[0373] 用户名:
[0374] #密码建议作为环境变量传递
[0375] #在启动期间(例如,账本_COUCHDB配置_密码)。
[0376] #如果在此存储,则文件必须受到访问控制保护
[0377] #防止无意的用户发现密码。
[0378] 密码:
[0379] #CouchDB错误的重试次数
[0380] 最大重试:3
[0381] #对等端启动期间CouchDB错误的重试次数
[0382] 启动时的最大重试:10
[0383] #CouchDB请求超时(单位:持续时间,例如,20s)
[0384] 请求超时:35s
[0385] #限制每个CouchDB查询的记录数
[0386] #请注意,链码查询仅受总查询限制的约束。
[0387] #链码在内部可以执行多个CouchDB查询,
[0388] #每个大小为内部查询限制。
[0389] 内部查询限制:1000
[0390] #限制每个CouchDB批量更新批次的记录数
[0391] 最大批次更新大小:1000
[0392] #每N个区块之后的温暖索引。
[0393] #该选项会温暖已经存在的任何索引
[0394] #在每N个区块之后部署至CouchDB。
[0395] #值1将在每区块提交之后温暖索引,
[0396] #以确保快速选择器查询。
[0397] #增加该值可能提高对等端和CouchDB的写入效率,
[0398] #但是可能降低查询响应时间。
[0399] N个区块之后的温暖索引:1
[0400] 托管在 Fabric提供的docker容器中的 具有使用Docker Compose脚本通过COUCHDB_用户和COUCHDB_密码环境变量传入的环境变量设置
用户名和密码的能力。
[0401] 对于Fabric提供的docker图像之外的 安装,必须编辑该安装的本地.初始化文件以设置管理员用户名和密码。
[0402] Docker compose脚本仅在创建容器时设置用户名和密码。如果在创建容器之后要改变用户名或密码,则必须编辑本地.初始化文件。
[0403] 在每次对等端启动时读取 对等选项。
[0404] 身份
[0405] 区块链网络中的不同参与者包括对等端、排序者、客户端应用、管理员等。这些参与者中的每一个——能够消费服务的网络内部或外部的活动元素——都有封装在X.509数
字证书中的数字身份。这些身份确实很重要,这是因为它们确定了对资源的确切许可以及
对参与者在区块链网络中具有的信息的访问。
[0406] 数字身份还具有一些附加属性,Fabric使用这些属性来确定许可,并且它为身份和相关联属性的联合提供了特殊名称——主体。主体就像用户ID或组ID,但是更灵活一点,
这是因为它们可以包括参与者的身份的广泛属性,诸如参与者的组织、组织单位、角色或者
甚至参与者的具体身份。当谈论主体时,它们是决定其许可的属性。
[0407] 为了使身份可验证,它必须来自信任机构。成员服务提供者(MSP)是在Fabric中实现这一点的方式。更具体地,MSP是限定了治理该组织的有效身份的规则的部件。Fabric中
的默认MSP实现使用X.509证书作为身份,采用传统的公钥基础设施(PKI)分层模型(稍后将
详细介绍PKI)。
[0408] 说明身份使用的简单场景
[0409] 想象去超市买一些杂货。在结账时,看到写着只接受Visa、Mastercard和AMEX卡的标志。如果尝试使用不同的卡付款——称其为“ImagineCard”——无论该卡是否真实以及
账户中是否有足够的资金都没有关系。它不会被接受。
[0410] 图24示出拥有有效的信用卡是不够的——它还必须被商店接受!PKI和MSP以相同的方式一起工作——PKI提供身份列表,而MSP说明这些中的哪些是参与网络的给定组织的
成员。
[0411] PKI证书颁发机构和MSP提供了类似的功能组合。PKI就像卡提供者——它分发许多不同类型的可验证身份。另一方面,MSP就像由商店接受的卡提供者列表,确定哪些身份
是商店支付网络的信任成员(参与者)。MSP将可验证的身份转变为区块链网络的成员。
[0412] PKI
[0413] 公钥基础设施(PKI)是在网络中提供安全通信的互联网技术的集合。
[0414] 图25示出了公钥基础设施(PKI)的要素。PKI由证书颁发机构组成,所述证书颁发机构向各方(例如,服务的用户、服务提供者)颁发数字证书,然后使用它们在它们与其环境
交换的消息中对它们自己进行身份验证。CA的证书撤销列表(CRL)构成了对不再有效的证
书的参考。证书的撤销可能由于多种原因而发生。例如,证书可能会被撤销,这是因为与证
书相关联的加密私有材料已经暴露。
[0415] 虽然区块链网络不止是通信网络,但是它依赖于PKI标准以确保各个网络参与者之间的安全通信,并且确保发布在区块链上的消息得到正确验证。因此,了解PKI的基本要
点以及为什么MSP如此重要非常重要。
[0416] 对于PKI有四个关键要素:
[0417] ·数字证书
[0418] ·公钥和私钥
[0419] ·证书颁发机构
[0420] ·证书撤销列表
[0421] 数字证书
[0422] 数字证书是保存与证书持有者相关的一组属性的文件。最常见的证书类型是符合X.509标准的证书,该标准允许在其结构中对一方的识别细节进行编码。
[0423] 例如,密歇根州底特律Mitchell Cars制造部门的Mary Morris可以拥有以下数字证书,其主题属性为C=US、ST=密歇根州、L=底特律、O=Mitchell Cars、OU=制造、CN=
Mary Morris/UID=123456。Mary的证书类似于她的政府身份证——它提供了关于Mary的
信息,她可以使用这些信息来证明关于她的关键事实。
[0424] 图26示出了描述称为Mary Morris的一方的数字证书。Mary是证书的主题,并且突出显示的主题文本示出了关于Mary的关键事实。如可以看到的,该证书还保存更多信息。最
重要的是,Mary的公钥在她的证书中分发,而她的私有签名密钥不在。该签名密钥必须保持
私有。
[0425] 重要的是,Mary的所有属性都可以使用称为密码学(字面意思是“秘密编写”)的数学技术记录,使得篡改将使证书失效。密码学允许Mary向其他人出示她的证书以证明她的
身份,只要另一方信任证书颁发者,称为证书颁发机构(CA)即可。只要CA安全地保存某些加
密信息(意味着它自己的私有签名密钥),读取证书的任何人都可以确保关于Mary的信息没
有被篡改——它将始终具有Mary Morris的那些特定属性。将Mary的X.509证书想象成无法
改变的数字身份证。
[0426] 身份验证、公钥和私钥
[0427] 身份验证和消息完整性是安全通信中的重要概念。身份验证要求交换消息的各方确信创建特定消息的身份。消息具有“完整性”意味着在其传输期间不能被修改。例如,您可
能想要确保您正在与真正的Mary Morris而不是模仿者进行交流。或者,如果Mary向您发送
了消息,您可能想要确保它在传输期间没有被其他人篡改。
[0428] 传统的身份验证机制依赖于数字签名,顾名思义,数字签名允许一方对其消息进行数字签名。数字签名还提供对签名消息完整性的保证。
[0429] 从技术上讲,数字签名机制要求每一方持有两个加密连接的密钥:广泛可用并充当身份验证锚点的公钥;以及用于在消息上生成数字签名的私钥。数字签名消息的接收者
可以通过检查附加的签名在预期发送者的公钥下是否有效来验证接收消息的来源和完整
性。
[0430] 私钥与相应公钥之间的独特关系是使安全通信成为可能的加密魔法。密钥之间的独特数学关系使得私钥可以用于在消息上生成签名,只有相应的公钥可以匹配,并且只能
在同一消息上。
[0431] 在图27所示的示例中,Mary使用她的私钥对消息进行签名。看到签名消息的任何人都可以使用她的公钥验证签名。
[0432] 证书颁发机构
[0433] 参与者或节点能够经由通过由系统信任的机构为其颁发的数字身份参与区块链网络。在最常见的情况下,数字身份(或简称身份)具有符合X.509标准并由证书颁发机构
(CA)颁发的经过加密验证的数字证书的形式。
[0434] CA是互联网安全协议的常见部分,诸如:Symantec(原为Verisign)、GeoTrust、DigiCert、GoDaddy和Comodo等。
[0435] 图28示出了向不同参与者分发证书的证书颁发机构。这些证书由CA进行数字签名,并且将参与者与参与者的公钥(以及可选地与完整属性列表)绑定在一起。因此,如果信
任CA(并且知道其公钥),就可以通过验证CA在参与者证书上的签名来信任特定参与者绑定
至证书中包含的公钥,并且拥有包含的属性。
[0436] 证书可以广泛传播,这是因为它们既不包括参与者的私钥,也不包括CA的私钥。因此,它们可以用作用于验证来自不同参与者的消息的信任锚点。
[0437] CA也有证书,它们可以广泛使用。这允许由给定CA颁发的身份的消费者通过检查证书是否只能由对应私钥(CA)的持有者生成来验证它们。
[0438] 在区块链设置中,希望与网络交互的每个参与者都需要身份。在该设置中,可能会说一个或更多个CA可以用于从数字角度限定组织的成员。CA为组织的参与者提供具有可验
证的数字身份的基础。
[0439] 根CA、中间CA和信任链
[0440] CA有两种形式:根CA和中间CA。由于根CA(Symantec、Geotrust等)必须向互联网用户安全地分发数亿个证书,因此将该过程分散至所谓的中间CA中是有意义的。这些中间CA
具有由根CA或其他中间机构颁发的证书,从而允许为链中任何CA颁发的任何证书建立“信
任链”。这种回溯到根CA的能力不仅允许CA的功能扩展,同时仍然提供安全性——允许使用
证书的组织自信地使用中间CA——它限制了根CA的暴露,如果根CA受到损害,它会危及整
个信任链。另一方面,如果中间CA受到损害,将存在小得多的暴露。
[0441] 图29示出了在根CA与一组中间CA之间建立的信任链,只要这些中间CA中的每一个的证书的颁发CA是根CA本身或者具有到根CA的信任链。
[0442] 当涉及到跨多个组织颁发证书时,中间CA提供了巨大的灵活性,这在权限区块链系统(如Fabric)中非常有用。例如,不同的组织可以使用不同的根CA,或者使用具有不同的
中间CA的同一根CA——这确实取决于网络的需求。
[0443] Fabric CA
[0444] Fabric提供了内置的CA部件,以允许用户在形成的区块链网络中创建CA。该部件——称为Fabric CA——是能够管理具有X.509证书形式的Fabric参与者的数字身份的
私有根CA提供商。因为Fabric CA是针对Fabric的根CA需求的自定义CA,所以它本质上无法
为浏览器中的常规/自动使用提供SSL证书。然而,因为必须使用一些CA来管理身份(即使是
在测试环境中),所以可以使用Fabric CA来提供和管理证书。也可以——并且完全合
适——使用公共/商业根或中间CA来提供标识。
[0445] 证书撤销列表
[0446] 证书撤销列表(CRL)是对CA知道因某种原因而被撤销的证书的引用列表。在商店场景中,CRL就像被盗信用卡列表。
[0447] 当第三方想要验证另一方的身份时,它首先会检查颁发CA的CRL,以确保证书未被撤销。验证者不必检查CRL,但如果不检查,他们将冒接受受损的身份的风险。
[0448] 图30示出了使用CRL来检查证书仍然有效。如果冒充者尝试将受损的数字证书传递给验证方,则可以首先根据颁发CA的CRL对其进行检查,以确保它不会被列为不再有效。
[0449] 注意,被撤销的证书与即将到期的证书有很大不同。撤销的证书尚未过期——从每个其他衡量标准来看,它们都是完全有效的证书。
[0450] 参考:
[0451] 有关Fabric和 的上述信息取自以下链接中的公开来源:
[0452] https://hyperledger‑fabric.readthedocs.io/en/release‑1.4/fabric_model.html#
[0453] https://kaleido.io/enterprise‑blockchain‑protocols‑ethereum‑vs‑fa
[0454] https://hyperledger‑fabric.readthedocs.io/en/release‑1.4/peers/peers.html#applications‑and‑peers
[0455] https://hyperledger‑fabric.readthedocs.io/en/release‑1.4/ledger/ledger.html#world‑state‑database‑options
[0456] https://hyperledger‑fabric.readthedocs.io/en/release‑1.4/couchdb_as_state_database.html
[0457] https://hyperledger‑fabric.readthedocs.io/en/release‑1.4/identity/identity.html#identity
[0458] https://hyperledger‑fabric.readthedocs.io/en/release‑1.4/identity/identity.html#fabric‑ca
[0459] 附录B
[0460] 关系数据访问控制
[0461] 超级管理员:根权限
[0462] ELEMENT中所有其他活动的先决条件是创建数据库并授权至少一个身份以对该数据库执行操作。“超级管理员(Super Admin)”访问级别授予执行该操作的权限。
[0463] 因为数据库的实现方式将是高度特定于平台的,所以除了它的存在之外,不存在用于该权限级别的与平台无关的规范。
[0464] ELEMENT访问级别
[0465] ELEMENT系统中剩余的用户访问级别是基于每个数据库授予的。
[0466] 关系数据访问控制管理基于在ELEMENT上成功注册之后分配给分布式分类账身份的某些唯一属性。使用ELEMENT的所有分布式分类账身份都基于这些属性进行分类和验证。
基于用户在特定数据库上的身份,用户的分类确定了由ELEMENT授予的操作范围。
[0467] 图31示出了访问级别和权限确定。
[0468] ELEMENT中存在5个访问级别,并且下面讨论这些级别的相应权限。
[0469] 超级管理员
[0470] 如所讨论的,超级管理员是ELEMENT的根权限级别,并且具有包括对数据库的创建的所有操作的权限:
[0471] ‑创建/删除数据库
[0472] ‑指定/删除管理员用户到特定/多个数据库
[0473] ‑从特定/多个数据库中添加/删除用户
[0474] ‑查看整个网络中的所有用户和用户信息
[0475] ‑执行DDL操作
[0476] ‑执行DML读/写操作
[0477] 管理员
[0478] 管理员访问级别是在指定数据库内具有最高权限的用户。由超级管理员用户在ELEMENT数据库上指定/注册管理员。管理员访问级别的权限是:
[0479] ‑在指定数据库上添加/删除用户
[0480] ‑查看整个指定数据库中的所有用户和用户信息
[0481] ‑执行DDL操作
[0482] ‑执行DML读/写操作
[0483] 注意:管理员用户可以针对指定数据库添加/删除更多管理员。
[0484] DDL
[0485] 该访问级别允许用户执行某些DDL操作(有关更多细节,参见ELEMENT SQL规范)以及DML操作。但是,不允许从该访问级别及以下级别添加用户。
[0486] ‑执行DDL操作,例如——在指定数据库内创建/改变/删除ELEMENT表、模式和列(索引)。
[0487] ‑执行DML读/写操作
[0488] DML写
[0489] 该访问级别的用户可以执行某些DML功能,例如:
[0490] ‑在ELEMENT表上插入/更新/删除记录。
[0491] ‑诸如LIMIT和OPSTAT的ELEMENT SQL扩展可以与DML写操作结合使用。(参考ELEMENT SQL规范)
[0492] DML读
[0493] DML读访问级别是使用户能够读取数据的最基本的访问。该级别处的用户无权修改数据库的任何数据。在该访问级别处可以进行以下操作:
[0494] ‑从指定数据库中选择各种记录并按升序或降序排列数据。
[0495] ‑诸如BOOKMARK、QUERYLEVEL和LIMIT的ELEMENT SQL扩展可以与DML读操作结合使用。(参考ELEMENT SQL规范)
[0496] ‑查看指定数据库内的表和表细节。
[0497] 注意:对于管理员访问级别和管理员以下的所有访问级别,创建和删除数据库DDL操作被禁用。如果用户尝试执行这些操作中的任意一个,则ELEMENT系统应返回错误——
403:拒绝访问
[0498] 用户注册
[0499] ELEMENT系统(v1.0)具有仅限邀请的注册系统。注册过程不公开:仅超级管理员具有添加新用户以使用ELEMENT数据库的权限。随后,超级管理员可以分配数据库所有者(管
理员),他们可以进一步将其他用户添加至该特定数据库。ELEMENT用户必须从分布式分类
账网络上的现有身份池构建,这是因为ELEMENT操作是建立在分布式分类账网络功能之上
的。
[0500] 用户注册由*注册用户ELEMENT API处理,该*注册用户ELEMENT API也被指定为可经由ELEMENT用户接口访问,其中,超级管理员和管理员访问级别可以手动授予用户对数据
库的访问。
[0501] 端点:http://:3000/api/user/register
[0502] API的请求正文包含3个必需参数:
[0503] 1.用户名:会员的唯一/不存在的名称
[0504] 2.数据库_id:现有数据库的名称
[0505] 3.访问_级别:会员的访问权限,该字段可以具有以下允许值——“DDL”、“DML_WRITE”、“DML_READ”、“ADMIN”
[0506] 示例注册用户请求正文:
[0507] {
[0508] "用户名":"马修",
[0509] "数据库_id":"顾客",
[0510] "访问_级别":"DDL"
[0511] }
[0512] 一旦注册成功完成,(有关成功响应和可能的错误,参考ELEMENTTMAPI规范文档)需要ELEMENT实现方式来记录分布式分类账上的操作。该动作将用户信息添加至指定数据库
的元数据中。(数据库内的用户名保存在名为“用户”的数组中。)
[0513] 撤销用户
[0514] 超级管理员和管理员访问级别可以选择从特定数据库/多个数据库禁用特定用户。这使用户能够选择性地访问网络上的多个数据库。
[0515] 具有适当权限的访问级别可以通过使用撤销用户ELEMENT API来禁用用户。
[0516] 端点:http://:3000/api/user/revoke
[0517] API的请求正文包含2个必需参数:
[0518] 1.用户名:会员的确切名称
[0519] 2.数据库_id:会员所属的现有数据库的名称
[0520] 示例撤销用户请求正文:
[0521] {
[0522] "用户名":"马修",
[0523] "数据库_id":"顾客",
[0524] }
[0525] 一旦撤销请求被执行,revokeUser()函数就会通过invokeTransaction()函数被调用。revokeUser()函数从目标数据库中删除相关用户的元数据。(用户从数据库的“用
户”数组中被删除。)
[0526] 删除用户
[0527] 超级管理员访问级别具有从网络中完全删除用户的权限。这可以通过使用删除用户ELEMENT API来实现。
[0528] 当用户被删除时,相关元数据将从该身份所属的所有数据库中删除。除了元数据,用户在网络上的数字身份也被彻底清除。
[0529] 端点:http://:3000/api/user/delete
[0530] API的请求正文包含1个必需参数:
[0531] 1.用户名:会员的确切名称
[0532] 示例删除用户请求正文:
[0533] {
[0534] "用户名":"马修",
[0535] }
[0536] 附录C
[0537] 分布式分类账上的关系数据——高级别要求
[0538] 分布式分类账和合意
[0539] 关系数据必须可被智能合约访问。
[0540] 对关系数据的附加更新由合意机制管理,该合意机制等同于用于对常规分布式分类账数据的附加更新的合意机制。
[0541] 修改数据的关系数据操作必须记录至分布式分类账。修改模式的关系操作也必须记录至分布式分类账。
[0542] 如果可能,关系数据应存储在分布式分类账内,并且必须实现与分布式分类账数据相同级别的不变性和防篡改。
[0543] 如果可能,关系模式信息应存储在分布式分类账内。
[0544] 如果本地替代品可用,则不应将关系索引存储在分布式分类账内。
[0545] 模式和索引
[0546] 表模式支持单字段唯一主关键字。应支持表的当前状态的主关键字的非聚集索引。
[0547] 数据可见性
[0548] 除了规范“关系数据访问控制”中授权的身份之外,数据、模式和记录的操作在静止或传输期间以未加密的形式不可见。
[0549] 数据和操作表示
[0550] 关系数据和记录的关系数据操作在分布式分类账(或上述等同内容)上以指定格式表示为JSON。
[0551] 图32示出了数据和操作对象的概况。
[0552] ELEMENT关系数据对象
[0553] 附录D
[0554] ELEMENT API:定义
[0555] 由ELEMENT API支持的功能如下:
[0556] 数据库API:
[0557] 创建数据库
[0558] POST
[0559] https:///api/1.0/database/create
[0560] 权限:具有ADMIN或DDL访问级别的ElementTM管理员或已授权的ElementTM用户
[0561] 标题
[0562]
[0563] ·标题‑示例:
[0564] {
[0565] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[0566] "X‑ELEMENT‑用户名":"管理员",
[0567] "内容‑类型":"应用/json"
[0568] }
[0569] 请求正文
[0570]
[0571]
[0572] ·请求‑示例:
[0573] {
[0574] "数据库_id":"DB22"
[0575] }
[0576] 成功200
[0577] 字段 类型 描述正文 对象 成功响应
结果 字符串 成功结果
数据库_id 字符串 数据库ID
交易_id 字符串 交易ID
[0578] ·成功‑响应:
[0579] HTTP/1.1 200OK
[0580] {
[0581] "结果":"成功",
[0582] "数据库_id":"DB22",
[0583] "交易_id":"bc78e5dcee6f3c820f52ba4f8e06b59452e873efa7b63b7a54ff71a80410de4c"}
[0584] 删除数据库
[0585] POST
[0586] https:///api/1.0/database/drop
[0587] 权限:具有ADMIN或DDL访问级别的ElementTM管理员或已授权的ElementTM用户
[0588] 标题
[0589]
[0590] ·标题‑示例:
[0591] {
[0592] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[0593] "X‑ELEMENT‑用户名":"管理员",
[0594] "内容‑类型":"应用/json"
[0595] }
[0596] 请求正文
[0597] 字段 类型 描述正文 对象 删除数据库请求正文对象
数据库_id 字符串 数据库ID
[0598] ·请求‑示例:
[0599] {
[0600] "数据库_id":"DB22"
[0601] }
[0602] 成功200
[0603]字段 类型 描述
正文 对象 成功响应
结果 字符串 成功结果
数据库_id 字符串 数据库ID
交易_id 字符串 交易ID
[0604] ·成功‑响应:
[0605] HTTP/1.1 200OK
[0606] {
[0607] "结果":"成功",
[0608] "数据库_id":"DB22",
[0609] "交易_id":"bc78e5dcee6f3c820f52ba4f8e06b59452e873efa7b63b7a54ff71a80410de4c"}
[0610] 显示数据库
[0611] GET
[0612] https:///api/1.0/database/show
[0613] 权限:ElementTM管理员或任何已授权的ElementTM用户
[0614] 标题
[0615] 字段 类型 描述授权 字符串 具有授权的承载令牌
TM
X‑ELEMENT‑用户名 字符串 在Element 上注册的用户名
内容‑类型 字符串 应用/JSON
[0616] ·标题‑示例:
[0617] {
[0618] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[0619] "X‑ELEMENT‑用户名":"管理员",
[0620] "内容‑类型":"应用/json"
[0621] }
[0622] 成功200
[0623]字段 类型 描述
正文 对象 成功响应
查询_响应 对象 查询响应对象
数据库 数组 数据库ID的数组
交易_id 字符串 交易ID
[0624] ·成功‑响应:
[0625] HTTP/1.1 200OK
[0626] {
[0627] "查询_响应":{
[0628] "数据库":["db22","顾客","管理员","网络"],
[0629] "交易_id":"bc78e5dcee6f3c820f52ba4f8e06b59452e873efa7b63b7a54ff71a80410de4c"
[0630] }
[0631] }
[0632] 表API:
[0633] 创建表
[0634] POST
[0635] https:///api/1.0/table/create
[0636] 权限:具有DDL访问权的已授权的ElementTM用户
[0637] 标题
[0638]字段 类型 描述
授权 字符串 具有授权的承载令牌
TM
X‑ELEMENT‑用户名 字符串 在Element 上注册的用户名
内容‑类型 字符串 应用/JSON
[0639] ·标题‑示例:
[0640] {
[0641] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[0642] "X‑ELEMENT‑用户名":"爱丽丝",
[0643] "内容‑类型":"应用/json"
[0644] }
[0645] 请求正文
[0646]
[0647]
[0648] ·请求‑示例:
[0649]
[0650] 成功200
[0651]
[0652]
[0653] ·成功‑响应:
[0654] HTTP/1.1 200OK
[0655] {
[0656] "结果":"表创建",
[0657] "表_id":"tab_1",
[0658] "交易_id":"bc78e5dcee6f3c820f52ba4f8e06b59452e873efa7b63b7a54ff71a80410de4c"}
[0659] 更改表
[0660] POST
[0661] https:///api/1.0/table/alter
[0662] 权限:具有DDL访问权限的已授权的ElementTM用户
[0663] 标题
[0664] 字段 类型 描述授权 字符串 具有授权的承载令牌
TM
X‑ELEMENT‑用户名 字符串 在Element 上注册的用户名
内容‑类型 字符串 应用/JSON
[0665] ·标题‑示例:
[0666] {
[0667] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[0668] "X‑ELEMENT‑用户名":"卡梅隆",
[0669] "内容‑类型":"应用/json"}
[0670] 一般请求正文
[0671] ·一般请求‑示例:
[0672] 请求正文——添加列
[0673]
[0674] ·添加列请求‑示例:
[0675]
[0676]
[0677] 请求正文——删除列
[0678]字段 类型 描述
正文 对象 更改表——删除列请求正文对象
数据库_id 字符串 数据库ID
表_id 字符串 表ID
操作 字符串 DROP
列 数组 要删除的列名数组
[0679] ·删除列请求‑示例:
[0680] {
[0681] "数据库_id":"工厂"
[0682] "表_id":"员工"
[0683] "操作":"DROP",
[0684] "列":["姓氏","电子邮件"]
[0685] }
[0686] 请求正文——修改列
[0687]
[0688]
[0689] ·修改列请求‑示例:
[0690]
[0691] 请求正文——重命名列
[0692]
[0693]
[0694] ·重命名列请求‑示例:
[0695]
[0696] 删除表
[0697] POST
[0698] https:///api/1.0/table/drop
[0699] 权限:具有DDL访问权限的已授权的ElementTM用户
[0700] 标题
[0701] 字段 类型 描述授权 字符串 具有授权的承载令牌
TM
X‑ELEMENT‑用户名 字符串 在Element 上注册的用户名
内容‑类型 字符串 应用/JSON
[0702] ·标题‑示例:
[0703] {
[0704] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[0705] "X‑ELEMENT‑用户名":"贝瑞塔",
[0706] "内容‑类型":"应用/json"
[0707] }
[0708] 请求正文
[0709]字段 类型 描述
正文 对象 删除表请求正文对象
数据库_id 字符串 数据库ID
表_id 字符串 表ID
[0710] ·请求‑示例:
[0711] {
[0712] "表_id":"细节"
[0713] "数据库_id":"城市_db"
[0714] }
[0715] 成功200
[0716]字段 类型 描述
正文 对象 成功响应对象
结果 字符串 成功结果
表_id 字符串 表ID
交易_id 字符串 交易ID
[0717] ·成功‑响应:
[0718] HTTP/1.1 200OK
[0719] {
[0720] "结果":"表删除",
[0721] "表_id":"细节",
[0722] "交易_id":"bc78e5dcee6f3c820f52ba4f8e06b59452e873efa7b63b7a54ff71a80410de4c"}
[0723] 显示表
[0724] GET
[0725] https:///api/1.0/table/show
[0726] 权限:已授权的ElementTM用户
[0727] 标题
[0728] 字段 类型 描述授权 字符串 具有授权的承载令牌
TM
X‑ELEMENT‑用户名 字符串 在Element 上注册的用户名
内容‑类型 字符串 应用/JSON
[0729] ·标题‑示例:
[0730] {
[0731] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[0732] "X‑ELEMENT‑用户名":"贝瑞塔",
[0733] "内容‑类型":"应用/json"
[0734] }
[0735] 成功200
[0736]
[0737]
[0738] ·成功‑响应:
[0739]
[0740] 描述表
[0741] POST
[0742] https:///api/1.0/table/desc/:table_id
[0743] 权限:具有DDL访问权限的已授权的ElementTM用户
[0744] 标题
[0745]字段 类型 描述
授权 字符串 具有授权的承载令牌
TM
X‑ELEMENT‑用户名 字符串 在Element 上注册的用户名
内容‑类型 字符串 应用/JSON
[0746] ·标题‑示例:
[0747] {
[0748] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[0749] "X‑ELEMENT‑用户名":"贝瑞塔",
[0750] "内容‑类型":"应用/json"
[0751] }
[0752] 请求参数
[0753]字段 类型 描述
参数 对象 描述表请求参数对象
表_id 字符串 表ID
[0754] ·请求‑示例:
[0755] https:///api/1.0/table/desc/customers
[0756] 成功200
[0757] 字段 类型 描述正文 对象 成功响应对象
查询_响应 对象 查询响应对象
表 对象 表描述
交易_id 字符串 交易ID
[0758] ·成功‑响应:
[0759]
[0760]
[0761]
[0762] 记录API:
[0763] 插入记录
[0764] POST
[0765] https:///api/1.0/record/insert
[0766] 权限:具有DML_WRITE访问权限的已授权的ElementTM用户
[0767] 标题
[0768]
[0769] ·标题‑示例:
[0770] {
[0771] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[0772] "X‑ELEMENT‑用户名":"罗伯特"
[0773] "内容‑类型":"应用/json"
[0774] }
[0775] 请求正文
[0776] 字段 类型 描述正文 对象 插入记录请求正文对象
数据库_id 字符串 数据库Id
表_id 字符串 表Id
col1 字符串 值1
col2 字符串 值2
col3 字符串 值3
[0777] ·请求‑示例:
[0778] {
[0779] "数据库_id":"DB22",
[0780] "表_id":"tab967",
[0781] "col1":"值1",
[0782] "col2":"值2",
[0783] "col3":"值3"
[0784] }
[0785] 成功200
[0786]
[0787]
[0788] ·成功‑响应:
[0789] HTTP/1.1 200OK
[0790] {
[0791] "结果":"记录插入"
[0792] "交易_id":"bc78e5dcee6f3c820f52ba4f8e06b59452e873efa7b63b7a54ff71a80410de4c"}
[0793] 更新记录
[0794] POST
[0795] https:///api/1.0/record/update
[0796] 权限:具有DML_WRITE访问权限的已授权的ElementTM用户
[0797] 标题
[0798]
[0799] ·标题‑示例:
[0800] {
[0801] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[0802] "X‑ELEMENT‑用户名":"鲍勃"
[0803] "内容‑类型":"应用/json"
[0804] }
[0805] 请求正文
[0806] 字段 类型 描述正文 对象 更新记录请求正文对象
数据库_id 字符串 数据库Id
表_id 字符串 表Id
col1 字符串 值1
col2 字符串 值2
col3 字符串 值3
[0807] ·请求‑示例:
[0808] {
[0809] "数据库_id":"DB22",
[0810] "表_id":"tab967",
[0811] "col1":"值1",
[0812] "col2":"值2",
[0813] "col3":"值3"
[0814] }
[0815] 成功200
[0816]
[0817]
[0818] ·成功‑响应:
[0819] HTTP/1.1 200 OK
[0820] {
[0821] "结果":"记录更新",
[0822] "交易_id":"bc78e5dcee6f3c820f52ba4f8e06b59452e873efa7b63b7a54ff71a80410de4c"}
[0823] 删除记录
[0824] POST
[0825] https:///api/1.0/record/delete
[0826] 权限:具有DML_WRITE访问权限的已授权的ElementTM用户
[0827] 标题
[0828]
[0829] ·标题‑示例:
[0830] {
[0831] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[0832] "X‑ELEMENT‑用户名":"爱丽丝",
[0833] "内容‑类型":"应用/json"
[0834] }
[0835] 请求正文
[0836]字段 类型 描述
数据库_id 字符串 数据库Id
表_id 字符串 表名
记录_id 字符串 记录Id
[0837] ·请求‑示例:
[0838] {
[0839] "数据库_id":"DB1",
[0840] "表_id":"tab_1",
[0841] "记录_id":123
[0842] }
[0843] 成功200
[0844] 字段 类型 描述正文 对象 成功响应对象
结果 字符串 成功结果
交易_id 字符串 交易Id
[0845] ·成功‑响应:
[0846] HTTP/1.1 200OK
[0847] {
[0848] "结果":"记录删除",
[0849] "记录_id":123,
[0850] "交易_id":"bc78e5dcee6f3c820f52ba4f8e06b59452e873efa7b63b7a54ff71a80410de4c"}
[0851] 选择记录
[0852] POST
[0853] https:///api/1.0/record/select
[0854] 权限:具有DML_READ访问权限的已授权的ElementTM用户
[0855] 标题
[0856]字段 类型 描述
授权 字符串 具有授权的承载令牌
TM
X‑ELEMENT‑用户名 字符串 在Element 上注册的用户名
内容‑类型 字符串 应用/JSON
[0857] ·标题‑示例:
[0858] {
[0859] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[0860] "X‑ELEMENT‑用户名":"爱丽丝",
[0861] "内容‑类型":"应用/json"
[0862] }
[0863] 请求正文
[0864]
[0865]
[0866] ·请求‑示例:
[0867] {
[0868] "数据库_id":"城市_db",
[0869] "表_id":"细节",
[0870] "where":"代理人='墨菲',分公司='西维尔'",
[0871] "limit":150,
[0872] "以……顺序":"DESC",
[0873] "查询_级别":"INFO"
[0874] }
[0875] 成功200
[0876] 字段 类型 描述正文 对象 响应正文对象
查询_响应 字符串 查询响应对象
交易_id 字符串 交易Id
书签 字符串 当前页面的书签(用于分页)
[0877] ·成功‑响应:
[0878]
[0879] 用户API:
[0880] 注册用户
[0881] POST
[0882] https:///api/1.0/user/register
[0883] 权限:具有管理员访问级别的ElementTM管理员或已授权的ElementTM用户
[0884] 标题
[0885]
[0886] ·标题‑示例:
[0887] {
[0888] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[0889] "X‑ELEMENT‑用户名":"吉姆",
[0890] "内容‑类型":"应用/json"
[0891] }
[0892] 请求正文
[0893]
[0894] ·请求‑示例:
[0895] {
[0896] "用户名":"马修",
[0897] "数据库_id":"顾客",
[0898] "访问_级别":"DDL"
[0899] }
[0900] 成功200
[0901]
[0902]
[0903] ·成功‑响应:
[0904] HTTP/1.1 200OK
[0905] {
[0906] "结果":"用户注册",
[0907] "用户名":"马修",
[0908] "交易_id":"bc78e5dcee6f3c820f52ba4f8e06b59452e873efa7b63b7a54ff71a80410de4c"
[0909] }
[0910] 撤销用户
[0911] POST
[0912] https:///api/1.0/user/revoke
[0913] 权限:具有管理员访问级别的ElementTM管理员或已授权的ElementTM用户
[0914] 标题
[0915]
[0916] ·标题‑示例:
[0917] {
[0918] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[0919] "X‑ELEMENT‑用户名":"汤姆",
[0920] "内容‑类型":"应用/json"
[0921] }
[0922] 请求正文
[0923]字段类型描述
正文对象撤销用户请求正文对象
用户名字符串现有用户名
数据库_id字符串现有数据库Id
[0924] ·请求‑示例:
[0925] {
[0926] "数据库_id":"db1",
[0927] "用户名":"杰米"
[0928] }
[0929] 成功200
[0930]字段 类型 描述
正文 对象 成功响应对象
结果 字符串 成功结果
用户名 字符串 用户名
交易_id 字符串 交易Id
[0931] ·成功‑响应:
[0932] {
[0933] "结果":"用户撤销",
[0934] "用户名":"杰米",
[0935] "交易_id":"bc78e5dcee6f3c820f52ba4f8e06b59452e873efa7b63b7a54ff71a80410de4c"
[0936] }
[0937] 删除用户
[0938] POST
[0939] https:///api/1.0/user/delete
[0940] 权限:具有管理员访问级别的ElementTM管理员或已授权的ElementTM用户
[0941] 标题
[0942]
[0943] ·标题‑示例:
[0944] {
[0945] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[0946] "X‑ELEMENT‑用户名":"汤姆",
[0947] "内容‑类型":"应用/json"
[0948] }
[0949] 请求正文
[0950]
[0951]
[0952] ·请求‑示例:
[0953] {
[0954] "用户名":"杰米"
[0955] }
[0956] 成功200
[0957] 字段 类型 描述正文 对象 成功响应对象
结果 字符串 成功结果
用户名 字符串 用户名
交易_id 字符串 交易Id
[0958] ·成功‑响应:
[0959] {
[0960] "结果":"用户删除",
[0961] "用户名":"杰米",
[0962] "交易_id":"bc78e5dcee6f3c820f52ba4f8e06b59452e873efa7b63b7a54ff71a80410de4c"
[0963] }
[0964] 索引API:
[0965] 创建索引
[0966] POST
[0967] https:///api/1.0/index/create
[0968] 权限:具有DML_WRITE访问权限的已授权的ElementTM用户
[0969] 标题
[0970] 字段 类型 描述授权 字符串 具有授权的承载令牌
TM
X‑ELEMENT‑用户名 字符串 在Element 上注册的用户名
内容‑类型 字符串 应用/JSON
[0971] ·标题‑示例:
[0972] {
[0973] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[0974] "X‑ELEMENT‑用户名":"爱丽丝",
[0975] "内容‑类型":"应用/json"
[0976] }
[0977] 请求正文
[0978]字段 类型 描述
正文 对象 创建表请求正文对象
数据库_id 字符串 现有数据库Id
表_id 字符串 现有表名
索引_名称 字符串 索引名称(唯一标识符)
索引_字段 字符串 要索引的字段的名称
[0979] ·请求‑示例:
[0980] {
[0981] "数据库_id":"城市_db",
[0982] "表_id":"细节",
[0983] "索引_名称":"detailsIdCityInd",
[0984] "索引_字段":["id","城市"]
[0985] }
[0986] 成功200
[0987] 字段 类型 描述正文 对象 成功响应对象
结果 字符串 成功结果
索引_名称 字符串 索引名称
交易_id 字符串 交易Id
[0988] ·成功‑响应:
[0989] HTTP/1.1 200OK
[0990] {
[0991] "结果":"索引创建",
[0992] "索引_名称":"detailsIdCityInd",
[0993] "交易_id":"bc78e5dcee6f3c820f52ba4f8e06b59452e873efa7b63b7a54ff71a80410de4c"
[0994] }
[0995] 删除索引
[0996] POST
[0997] https:///api/1.0/index/delete
[0998] 权限:具有DML_WRITE访问权限的已授权的ElementTM用户
[0999] 标题
[1000]
[1001]
[1002] ·标题‑示例:
[1003] {
[1004] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[1005] "X‑ELEMENT‑用户名":"爱丽丝",
[1006] "内容‑类型":"应用/json"
[1007] }
[1008] 请求正文
[1009]Field Type Description
正文 对象 创建表请求正文对象
数据库_id 字符串 现有数据库Id
表_id 字符串 现有表名
索引_名称 字符串 索引名称(唯一标识符)
[1010] ·请求‑示例:
[1011] {
[1012] "数据库_id":"城市_db",
[1013] "表_id":"细节",
[1014] "索引_名称":"detailsIdCityInd"
[1015] }
[1016] 成功200
[1017]字段 类型 描述
正文 对象 成功响应对象
结果 字符串 成功结果
索引_名称 字符串 索引名称
交易_id 字符串 交易Id
[1018] ·成功‑响应:
[1019] HTTP/1.1 200OK
[1020] {
[1021] "结果":"索引删除",
[1022] "索引_名称":"detailsIdCityInd",
[1023] "交易_id":"bc78e5dcee6f3c820f52ba4f8e06b59452e873efa7b63b7a54ff71a80410de4c"}
[1024] 批量交易API:
[1025] 插入批量记录
[1026] POST
[1027] https:///api/1.0/record/bulk/insert
[1028] 权限:具有DML_WRITE访问权限的已授权的ElementTM用户
[1029] 标题
[1030]
[1031]
[1032] ·标题‑示例:
[1033] {
[1034] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[1035] "X‑ELEMENT‑用户名":"罗伯特"
[1036] "内容‑类型":"应用/json"
[1037] }
[1038] 请求正文
[1039]字段 类型 描述
正文 对象 批量插入记录请求正文对象
数据库_id 字符串 数据库Id
表_id 字符串 表Id
记录 数组 一组要插入的记录数组
[1040] ·请求‑示例:
[1041]
[1042]
[1043] 成功200
[1044]
[1045]
[1046] ·成功‑响应:
[1047] HTTP/1.1 200 OK
[1048] {
[1049] "结果":"记录插入"
[1050] "交易_id":"bc78e5dcee6f3c820f52ba4f8e06b59452e873efa7b63b7a54ff71a80410de4c"
[1051] }
[1052] 更新批量记录
[1053] POST
[1054] https:///api/1.0/record/bulk/update
[1055] 权限:具有DML_WRITE访问权限的已授权的ElementTM用户
[1056] 标题
[1057]
[1058] ·标题‑示例:
[1059] {
[1060] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[1061] "X‑ELEMENT‑用户名":"罗伯特"
[1062] "内容‑类型":"应用/json"
[1063] }
[1064] 请求正文
[1065]
[1066] ·请求‑示例:
[1067]
[1068] 成功200
[1069]
[1070]
[1071] ·成功‑响应:
[1072] HTTP/1.1 200OK
[1073] {
[1074] "结果":"记录更新"
[1075] "交易_id":"bc78e5dcee6f3c820f52ba4f8e06b59452e873efa7b63b7a54ff71a80410de4c"
[1076] }
[1077] 删除批量记录
[1078] POST
[1079] https:///api/1.0/record/bulk/delete
[1080] 权限:具有DML_WRITE访问权限的已授权的ElementTM用户
[1081] 标题
[1082]
[1083] ·标题‑示例:
[1084] {
[1085] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[1086] "X‑ELEMENT‑用户名":"罗伯特"
[1087] "内容‑类型":"应用/json"
[1088] }
[1089] 请求正文
[1090]
[1091] ·请求‑示例:
[1092] {
[1093] "数据库_id":"DB22",
[1094] "表_id":"",
[1095] "where":"列2='002'"
[1096] }
[1097] 成功200
[1098]字段 类型 描述
正文 对象 成功响应对象
结果 字符串 成功结果
交易_id 字符串 交易Id
[1099] ·成功‑响应:
[1100] HTTP/1.1 200OK
[1101] {
[1102] "结果":"记录删除"
[1103] "交易_id":"bc78e5dcee6f3c820f52ba4f8e06b59452e873efa7b63b7a54ff71a80410de4c"}
[1104] SQL查询API:
[1105] 执行SQL查询
[1106] POST
[1107] https:///api/1.0/query
[1108] 权限:基于ADMIN、DDL、DML_WRITE和DML_READ中的查询的具有访问级别的已授权TM
的Element 用户
[1109] 标题
[1110] 字段 类型 描述授权 字符串 具有授权的承载令牌
TM
X‑ELEMENT‑用户名 字符串 在Element 上注册的用户名
内容‑类型 字符串 应用/JSON
[1111] ·标题‑示例:
[1112] {
[1113] "授权":"承载eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ",
[1114] "X‑ELEMENT‑用户名":"管理员",
[1115] "内容‑类型":"应用/json"
[1116] }
[1117] 请求正文——创建和删除数据库查询
[1118]字段 类型 描述
正文 对象 删除数据库查询请求正文对象
查询 字符串 删除数据库查询
[1119] 请求正文——所有其他查询
[1120] 字段 类型 描述正文 对象 创建表查询请求正文对象
数据库_id 字符串 现有数据库Id
查询 字符串 创建表查询
[1121] ·请求‑示例:
[1122] {
[1123] "数据库_id":"组织",
[1124] "查询":"DELETE FROM Reports WHERE status='Rejected'LIMIT 50OPSTAT"
[1125] }
[1126] 成功响应——创建数据库查询
[1127]字段 类型 描述
正文 对象 成功响应对象
查询_响应 字符串 查询结果
数据库_id 字符串 数据库Id
交易_id 字符串 交易Id
[1128] 成功响应——删除数据库查询
[1129]字段 类型 描述
正文 对象 成功响应对象
查询_响应 字符串 查询结果
数据库_id 字符串 数据库Id
交易_id 字符串 交易Id
[1130] 成功响应——创建表查询
[1131]字段 类型 描述
正文 对象 成功响应对象
查询_响应 字符串 查询结果
表_id 字符串 表Id
交易_id 字符串 交易Id
[1132] 成功响应——更改表查询
[1133] 字段 类型 描述正文 对象 成功响应对象
查询_响应 字符串 查询结果
表_id 字符串 表Id
交易_id 字符串 交易Id
[1134] 成功响应——删除表查询
[1135] 字段 类型 描述正文 对象 成功响应对象
查询_响应 字符串 查询结果
表_id 字符串 表Id
交易_id 字符串 交易Id
[1136] 成功响应——插入记录查询
[1137] 字段 类型 描述正文 对象 成功响应对象
查询_响应 字符串 查询响应
受影响的行 数目 插入的记录
记录_id 数组 包含插入的记录Id的数组
交易_id 字符串 交易Id
[1138] 成功响应——更新记录查询
[1139] 字段 类型 描述正文 对象 成功响应对象
查询_响应 字符串 查询响应
受影响的行 数目 更新的记录的数目
记录_id 数组 记录Id的数组
交易_id 字符串 交易Id
[1140] 成功响应——删除记录查询
[1141]字段 类型 描述
正文 对象 成功响应对象
查询_响应 字符串 查询响应
受影响的行 数目 删除的记录的数目
记录_id 数组 记录Id的数组
交易_id 字符串 交易Id
[1142] 成功响应——选择记录查询
[1143] 字段 类型 描述正文 对象 成功响应对象
查询_响应 字符串 查询响应
记录 对象 获取的记录对象
书签 字符串 当前页面的书签(用于分页)
交易_id 字符串 交易Id
[1144] 成功响应——批量插入记录查询
[1145]
[1146]
[1147] 成功响应——显示表查询
[1148] 字段 类型 描述正文 对象 成功响应对象
查询_响应 字符串 查询响应
表 数组 表的数组
交易_id 字符串 交易Id
[1149] 成功响应——显示数据库查询
[1150]字段 类型 描述
正文 对象 成功响应对象
查询_响应 字符串 查询响应
数据库 数组 数据库的数组
交易_id 字符串 交易Id
[1151] 成功响应——描述表查询
[1152]
[1153]
[1154] ·成功‑响应:
[1155]
[1156] 附录E
[1157] ELEMENT SQL:高级别要求
[1158] SQL查询输入路径
[1159] ELEMENT 1.0实现方式接受来自三个来源的ELEMENT SQL查询,如下表所示:
[1160]
[1161] ELEMENT中支持的SQL概念
[1162] 本规范的其余部分中隐含这样一个事实,即ELEMENT实现方式支持许多常见SQL构造的等效项,包括:
[1163]
[1164]
[1165] 数据类型
[1166] ELEMENT中的数据类型——背景
[1167] ELEMENT系统中的记录与特定表相关联。每个单元格值都属于一种数据类型,该数据类型由其ELEMENT表中定义的列指定。
[1168] 在ELEMENT SQL中,预定义的数据类型的名称是保留关键字。数据类型的灵感来自现有SQL类型;然而,ELEMENT系统由与以前的SQL实现方式不同的本机精度和范围指标组
成。
[1169] 所有ELEMENT预定义的数据类型本质上都是原子的,即为其值不由其他数据类型的值组成的数据类型。
[1170] ELEMENT系统目前支持3种预定义的数据类型:
[1171] 1.数字
[1172] ELEMENT系统的“数字”数据类型支持所有操作数字类型。它是熟悉的SQL数据类型例如NUMERIC类型、INTEGER类型和DECIMAL类型的组合,也支持十进制值的精度。
[1173] “NUMBER”是数据类型,也是关键字,在构造SQL查询时表示任意数值。数字的最大长度或精度正好是16位,包括小数部分的规模或位数。
[1174] 范围:
[1175] ‑9999999999999998至9999999999999998
[1176] 考虑以下示例以确定数字数据类型的可接受范围。
[1177] INSERT INTO顾客(顾客Id)VALUES(‑9999999999999998)
[1178] INSERT INTO顾客(顾客Id)VALUES(17458909.98754397)
[1179] INSERT INTO顾客(顾客Id)VALUES(9999999999999999)
[1180] INSERT INTO顾客(顾客Id)VALUES(1367778390.99984778666658)
[1181] 2.字符串
[1182] ELEMENT系统的字符串数据类型支持所有与字符串相关的值。它是可变长度字符串类型的组合,并且类似于SQL中的TEXT数据类型。
[1183] 字符串数据类型由“STRING”关键字表示,它接受所有可变长度字符串。ELEMENT v1.0不支持固定长度字符串。STRING数据类型的ELEMENT实现方式定义范围没有设置硬限
制,但存在物理限制,该物理限制由各种因素例如操作硬件、连接性和分布式分类账平台配
置定义。
[1184] ELEMENT查询的输入STRING值是UTF‑8编码。如CESU‑8和修改的UTF‑8的可替选编码不被视为有效的UTF‑8。
[1185] 3.布尔
[1186] 布尔数据类型的值为真或假。
[1187] 未知数的真值有时由空值表示。
[1188] 如果布尔列具有启用的空值,则null表示未知的真值。
[1189] 排版约定
[1190] 本文档由巴科斯‑诺尔表格(BNF)的简单变型的文本描述组成,其包括以下排版和语法约定:
[1191]
[1192]
[1193] ELEMENT元素的SQL语法词汇表
[1194] 来自标准SQL的关键字
[1195] ELEMENT 1.0支持SQL语言的子集,包括以下标准关键字,以及将在规范中稍后描述的一些特定于ELEMENT的关键字:
[1196]
[1197]
[1198] 注意:ELEMENT系统也支持*符号,它表示ELEMENT表的所有记录/列。
[1199] NULL关键字
[1200] NULL用作关键字和值。
[1201] Null在以下方面与其他值不同:
[1202] 通过对记录使用数据类型“null”,null值可以用于显示某些字段的空白或无值。可以使用NULL作为关键字,与NOT运算符一起用作检查空记录的验证。NULL也可以用于将列
的默认值设置为null。
[1203] null的值不“等于”任何其他值,类似地它“不等于”任何其他值——不知道null是否等于任何其他给定值。没有任何有意义的数据值可以表示为null。
[1204] 标识符
[1205] ELEMENT v1.0仅支持英语作为本地语言,未来版本将提供对国际化(i18n)的支持。ELEMENT中定义了两种类型的标识符:
[1206] 数据库_名称标识符匹配该正则表达式:
[1207] /^(?=.{1,50}$)([a‑zA‑Z0‑9]+(‑[a‑zA‑Z0‑9]+)*)$/
[1208] 标识符是与以下正则表达式匹配的字符串:
[1209] /^(?=.{1,50}$)([a‑zA‑Z0‑9]+((‑|_)[a‑zA‑Z0‑9]+)*)$/
[1210] 所有标识符具有50个字符的最大长度。
[1211] 标识符用于以下上下文:
[1212] 表_名::=标识符
[1213] 列_名e::=标识符
[1214] 旧_列_名::=标识符
[1215] 新_列_名::=标识符
[1216] ELEMENT系统限制标识符以包括默认关键字和保留关键字的名称。
[1217] 数据类型和值
[1218] ELEMENT v1.0支持3种预定义的数据类型:如前所述,字符串、数字和布尔值。
[1219] 数据_类型::=[NUMBER|STRING|BOOLEAN]
[1220] 值::=
[1221] <值>(对应于选定的数据类型)——请参考Element中的数据类型部分。
[1222] 比较运算符
[1223] 顾名思义,ELEMENT SQL中的比较运算符允许两个值的比较。它将字符串或数字等同于诸如等于值、大于值或小于值的关系。
[1224] 比较运算符列表:
[1225]
[1226]
[1227] 比较_运算符::=
[1228] [<|>|<>|!=|>=|<=|=]
[1229] 组合表达式
[1230] ELEMENT SQL支持使用通常与WHERE子句一起使用的条件关键字来评估两个或更多个情境数据或选择。逻辑与一些比较运算符一起形成了ELEMENT系统中的组合运算符。下
面提到了支持的组合运算符:
[1231] ALL
[1232] ALL运算符通过将值与由子查询返回的值列表或一组值进行比较来查询数据。
[1233] all_表达式::=列_名比较_运算符ALL({子查询|<值>,<值>,...})
[1234] ANY
[1235] ANY运算符将值与由子查询返回的值列表或一组值进行比较。
[1236] any_表达式::=列_名比较_运算符ANY({子查询|<值>,<值>,...})
[1237] IN
[1238] IN运算符在WHERE子句内使用来检查值是否与值列表中的任意值匹配。
[1239] in_表达式::=列_名IN({子查询|<值>,<值>,…})
[1240] AND、OR和NOT关键字是ELEMENT SQL的逻辑运算符。这些关键字主要用于连接或反转SQL语句中的条件,特别是在WHERE子句中。逻辑运算符的语法将结合其他SQL命令进行进
一步说明。
[1241] 模式匹配
[1242] ELEMENT SQL支持基于正则表达式的字符串模式匹配。模式可以使用LIKE运算符通过表列中存在的记录值来匹配。LIKE运算符用作类似于“等于”(=)运算符来匹配字符串
模式。存在两个通配符通常与LIKE运算符结合使用:
[1243] %——百分号代表零、一个或多个字符
[1244] _——下划线代表单个字符
[1245] 注意:还支持星号(*)和问号(?)。
[1246] like_子句::=列_名LIKE‘<模式>’
[1247] 模式::=
[1248] {<字符>|<通配符>}[<字符>|<通配符>][<字符>|<通配符>}...
[1249] 通配符::=
[1250] {%|_|$|*|?}
[1251] 子查询
[1252] 子查询是嵌套在较大SQL查询中的SQL查询,通常嵌入在WHERE子句中。
[1253] 子查询可以嵌套在SELECT、INSERT、UPDATE或DELETE语句内或另一子查询内。它通常添加在另一SQLSELECT语句的WHERE子句内。比较运算符例如>、<或=以及组合运算符例
如IN、ANY或ALL可以与子查询一起使用。
[1254] 子查询也称为内部查询或内部选择,而包含子查询的语句也称为外部查询或外部选择。
[1255] 子查询规则
[1256] ‑子查询在主查询执行之前执行。
[1257] ‑子查询结果作为主查询的输入进行处理。
[1258] ‑子查询括在括号中,但对于INSERT,子查询被视为常规SELECT语句。
[1259] ‑子查询放在比较运算符的右侧。
[1260] ‑子查询无法在内部操作相应的结果,因此不能将ORDER BY子句添加至子查询中。ORDERBY子句可以在主SELECT语句中使用,这将是最后一个子句。
[1261] ‑应基于受子查询影响的行数使用SQL运算符。
[1262] ‑如果子查询向主查询返回null值,则在WHERE子句中使用某些组合运算符时,主查询将不会返回任何行。
[1263] ‑不能在子查询中使用特定于ELEMENT的关键字和扩展名。
[1264] 子查询类型
[1265] ‑单行子查询:返回零或一行。
[1266] ‑多行子查询:返回一行或更多行。
[1267] ‑多列子查询:返回一列或更多列。
[1268] ‑嵌套子查询:子查询放在另一子查询内。
[1269] 子查询::=
[1270] SELECT{*|<列_名>|<列_名>,<列_名>,...}
[1271] FROM<表_名>
[1272] WHERE搜索_条件
[1273] [LIMIT<值>]
[1274] 搜索_条件::=
[1275] 搜索_子句[{AND|OR}搜索_子句[{AND|OR}
[1276] 搜索_子句]...]
[1277] 搜索_子句::=
[1278] [NOT]{比较_子句|比较_子句|between_子句|like_子句}
[1279] 比较_子句::=
[1280] <列_名>比较_运算符{<值>|NULL}
[1281] 比较_子句::=
[1282] {all_表达式|any_表达式|in_表达式}
[1283] between_子句::=
[1284] {(<值>[NOT]BETWEEN<值>AND<值>)}
[1285] DDL命令
[1286] 数据定义语言(DDL)是用于创建和修改数据库中数据库对象结构的计算机语言。ELEMENT SQL中支持的数据库对象包括模式、表和索引。使用所描述的语法,ELEMENT实现方
式支持以下DDLSQL语句。
[1287] 如高级别要求所述,针对调用,DDLSQL语句可以由智能合约支持。
[1288] 创建数据库
[1289] 在系统中创建新数据库。
[1290] 创建_数据库_语句::=
[1291] CREATE DATABASE数据库_名称[;]
[1292] 数据库_名称::=标识符
[1293] 要创建的数据库名称
[1294] 创建表
[1295] 在当前数据库中创建新表。表可以具有多个列,其中每个列定义由名称、数据类型和可选的列定义组成。
[1296] 创建_表_语句::=
[1297] CREATE TABLE表_名
[1298] ({列_定义},...)[;]
[1299] 列_定义::=
[1300] 列_名<数据_类型>[DEFAULT|NULL|NOT NULL|PRIMARY KEY][;]
[1301] 表_名::=标识符
[1302] 要创建的表的名称
[1303] 列_名::=标识符
[1304] 列的名称
[1305] 更改表
[1306] 修改现有表的属性、列或约束。
[1307] 注意:ALTER TABLE的ELEMENT SQL语法一次不支持多于一个的操作。在该语法中,动作关键字显示了用户可用的所有ELEMENT支持的ALTER表查询变型。
[1308] 改变_表_语句::=
[1309] ALTER TABLE表_名{动作}
[1310] 动作::=
[1311] {
[1312] ADD列_名<数据_类型>[DEFAULT]<值>|
[1313] DROP列_名|
[1314] ALTER列_名TYPE<数据_类型>(仅适用于表没有记录的情况)|
[1315] RENAME COLUMN旧_列_名TO新_列_名
[1316] }[;]
[1317] 表_名::=标识符
[1318] 要改变的表的名称
[1319] 列_名::=标识符
[1320] 要改变的表的名称
[1321] 旧_列_名::=标识符
[1322] 要重命名的列的名称
[1323] 新_列_名::=标识符
[1324] 在改变之后列的新名称
[1325] 删除表
[1326] 从当前数据库中删除表。
[1327] 删除_表_语句::=
[1328] DROP TABLE表_名[;]
[1329] 表_名::=标识符
[1330] 要删除的表的名称
[1331] 删除数据库
[1332] 从ELEMENT系统中删除数据库。
[1333] *注意:数据库上的数据被清除,但数据库不会从网络中硬删除。数据库名称,即使在使用DROP数据库操作之后,也是唯一的并且不可以重复使用。
[1334] 删除_数据库_语句::=
[1335] DROP DATABASE数据库_名[;]
[1336] 数据库_名::=标识符
[1337] 要清除的数据库的名称
[1338] 显示表
[1339] 列出用户具有访问权限的表。该命令可以用于列出当前/指定数据库的表。
[1340] 输出返回表列表,按表名按字典顺序排列。
[1341] 显示_表_语句::=
[1342] SHOW TABLES[;]
[1343] 显示数据库
[1344] 列出用户在整个帐户中具有访问权限的数据库,包括将在分布式分类账平台上可见的已删除数据库。
[1345] 输出返回数据库列表,按数据库名称按字典顺序排列。
[1346] 显示_数据库_语句::=
[1347] SHOW DATABASES[;]
[1348] 描述表
[1349] 描述表中的列或当前值。DESCRIBE查询返回所选定表的所有细节和元数据。
[1350] 描述_表_语句::=
[1351] DESC[RIBE][TABLE]表_名[;]
[1352] 表_名::=标识符
[1353] 将为其返回描述的表的名称
[1354] DML(写)命令
[1355] 数据操作语言(DML)是计算机编程语言,该计算机编程语言用于在数据库中添加(插入)、删除和修改(更新)数据。DML通常是更广泛的数据库语言例如SQL的子语言,其中
DML包括该语言中的一些运算符,就像在此的情况。以下是DMLSQL写命令,它们可能会改变
数据的当前状态,并且由ELEMENT实现方式支持。
[1356] INSERT记录
[1357] 通过向表中插入一行或更多行来更新表。可以明确指定插入表中每一列的值。
[1358] 插入_语句::=
[1359] INSERT INTO表_名[列_名,列_名,...]
[1360] [选择_语句|子查询]
[1361] VALUES{DEFAULT|NULL|<值>,<值>,...}
[1362] [OPSTAT][;]
[1363] 表_名::=标识符
[1364] 将添加数据的表的名称
[1365] 列_名::=标识符
[1366] 将添加数据的列的名称
[1367] 注意:INSERT的值是强制性的,并且至少有一个字段(主关键字字段)将具有确定的值。其余的值——如果未填充——将被ELEMENT系统视为NULL。
[1368] DELETE记录
[1369] 从表中删除数据。使用WHERE子句删除特定数据。
[1370] 删除_语句::=
[1371] DELETE FROM表_名
[1372] WHERE搜索_条件
[1373] [LIMIT|OPSTAT][;]
[1374] 表_名::=标识符
[1375] 将从其中删除记录的表的名称
[1376] UPDATE记录
[1377] 利用新值更新目标表中的指定行。
[1378] 更新_语句::=
[1379] UPDATE表_名
[1380] SET赋值
[1381] [WHERE搜索_条件][;]
[1382] [LIMIT|OPSTAT][;]
[1383] 赋值::=
[1384] {(列_名=<值>|NULL,
[1385] [列_名=<值>|NULL],…)}
[1386] 表_名::=标识符
[1387] 要修改的表的名称
[1388] 列_名::=标识符
[1389] 用于比较或搜索特定数据的列的名称
[1390] DML(读)命令
[1391] 数据的只读选择有时被区分为单独的数据查询语言(DQL)的一部分,但它密切相关,有时也被视为DML的组成部分。ELEMENT实现方式支持以下SQLDML读取命令,其中语法描
述如下。
[1392] SELECT
[1393] 选择_语句::=
[1394] SELECT[*|列_名|列_名,列_名...]
[1395] FROM表_名
[1396] WHERE搜索_条件
[1397] [ORDER BY列_名ASC|DSC]
[1398] [LIMIT<值>]
[1399] [QUERYLEVEL{INFO|SYSTEM}]|[BOOKMARK<值>][;]
[1400] 表_名::=标识符
[1401] 从其中读取数据的表的名称
[1402] 列_名::=标识符
[1403] 从中检索数据或根据结果排序的列的名称
[1404] 注意:ORDER BY操作只可以在索引列上进行。
[1405] SQL的ELEMENT扩展
[1406] ELEMENT 1.0实现方式还支持以下关键字作为标准SQL的扩展。
[1407] 1.OPSTAT
[1408] OPSTAT是对操作已经并入分类帐中的指示进行跟踪的请求。
[1409] 当OPSTAT添加至从控制台或SDK调用的SQLDML写查询的结束时,调用者将在预配置超时结束时接收到三个响应之一。3个可能的响应是:
[1410] I.SUCCESS:成功响应意味着在平台相关程度上,SQL操作成功地更新并且数据已被并入分布式分类账中。
[1411] II.FAILURE:失败状态表示SQL命令没有成功地执行,并且分类账上的数据从未更新过。
[1412] III.TIMEOUT:当SQL命令超过预先配置的超时期限时,用户将返回TIMEOUT响应。目前没有确认查询结果已经并入分类帐中。
[1413] OPSTAT也适用于所有DDL操作,无论是否添加至查询与否。对于直接从智能合约运行的查询,如果被包括OPSTAT将被忽略,而是替代地返回常规查询响应。这是因为ELEMENT
操作是更大交易(智能合约的调用)内的步骤,因此,除了作为整个智能合约交易的成功执
行的一部分之外,操作的成功或失败没有被定义。
[1414] OPSTAT的语法规则:
[1415] ‑OPSTAT用于有效查询的结束处,这意味着在OPSTAT关键字之后不可以出现任何操作或子句。
[1416] ‑OPSTAT关键字仅用于SELECT、UPDATE、INSERT和DELETE操作。
[1417] 示例:
[1418] INSERT INTO示例_表[('ABC','DEF',123,假)]OPSTAT
[1419] DELETE FROM任务WHERE状态='拒绝'LIMIT 50OPSTAT
[1420] 2.LIMIT
[1421] LIMIT关键字类似于传统的SQL LIMIT操作以及一些特定于ELEMENT的规则。LIMIT限制由查询返回的最大行数。
[1422] LIMIT的语法规则:
[1423] ‑LIMIT与SELECT、UPDATE和DELETE操作一起使用。
[1424] ‑LIMIT在OPSTAT关键字之前用于UPDATE和DELETE查询。
[1425] ‑在SELECT查询中,LIMIT用于BOOKMARK或QUERY_LEVEL关键字之前。
[1426] 示例:
[1427] SELECT联系人_id,姓_氏,名_字FROM联系人WHERE城市='维也纳'ORDER BY姓_氏ASC LIMIT 400QUERYLEVEL SYSTEM BOOKMARK tldg213sd45sa7fd
[1428] DELETE FROM任务WHERE状态='拒绝'LIMIT 50OPSTAT
[1429] 3.QUERYLEVEL
[1430] QUERYLEVEL功能提供有关所选定记录的元数据信息。用户在执行具有SELECT查询的QUERYLEVEL命令之后,接收到查询响应中的信息。
[1431] 该功能存在两个信息级别:
[1432] 1.INFO:这是ELEMENT设置的默认信息级别。在此级别处,用户被提供有列名称及其各自的值。
[1433] 2.SYSTEM:SYS或系统QUERYLEVEL提供有关所选定记录的详细信息。详细的元数据包括诸如以下字段:
[1434] a.创建的日期
[1435] b.最后修改的日期
[1436] c.由……创建
[1437] d.唯一id:记录id、表id
[1438] e.版本细节
[1439] QUERYLEVEL的语法规则:
[1440] ‑QUERYLEVEL用于读操作,即仅用于SELECT查询。
[1441] ‑其用于LIMIT关键字之前并且位于查询的末尾处。
[1442] ‑QUERYLEVEL的位置可以与BOOKMARK关键字互换。
[1443] 示例:
[1444] SELECT*FROM数据WHERE城市='老挝'LIMIT 70BOOKMARK nw1e83ge6ds43uia QUERYLEVEL INFO
[1445] SELECT id FROM数据WHERE城市='纽瓦克市'QUERYLEVEL SYSTEM BOOKMARK erttnkel63ze9fs02vfe
[1446] 4.书签
[1447] BOOKMARK查询用于ELEMENT表数据的分页。使用LIMIT关键字和Bookmark设置表的页面大小。默认情况下,所有页面都具有指定的唯一标记,用户可以通过使用BOOKMARK查询
访问该标记。查询返回包含BOOKMARK和查询响应的对象。使用获得的BOOKMARK,用户可以查
看/访问后续页面上的数据。
[1448] 书签的语法规则:
[1449] ‑BOOKMARK关键字仅用于SELECT查询。
[1450] ‑BOOKMARK在查询结束时使用;因此它在LIMIT关键字之后使用。
[1451] ‑BOOKMARK的位置可以与QUERYLEVEL关键字互换。
[1452] 示例:
[1453]
[1454]
[1455] 具有书签的查询响应
[1456] 5.批量插入记录
[1457] ELEMENT支持使用BULK INSERT功能将记录多次插入到ELEMENT表。
[1458] BULK INSERT操作功能非常类似于DELETE和UPDATE查询,其中多行受到影响/修改。因此,这些操作的后续查询响应中的“受影响的行数”(ELEMENT API规范中的更多细
节——参见附录D)字段可以是任意数字“n”。尽管已经针对优化操作设置了ELEMENT特定限
制。
[1459] 相反,INSERT命令仅处理单个行,因此INSERT查询响应中的“受影响的行数”值固定为1。
[1460] 示例:
[1461]
[1462]
[1463] 批量插入的查询响应
[1464] 附录F
[1465] ELEMENT SDK功能文档
[1466] 介绍
[1467] Element的特定于语言的SDK是使得开发人员能够直接从其应用代码与ELEMENTTM系统进行交互的工具。本文档详细介绍了为与 应用一起使用而开发的SDK的版
本。
[1468] SDK(称为“ELEMENT_SDK”)相当简单,其包括:构造函数,用于配置它以供特定用户和ELEMENT数据库使用;以及接受SQL语句参数的函数。数据库操作本身使用SQL
参数的语法调用。有关细节,参见附录E。
[1469] 在Element_Chaincode中重用
[1470] 在Fabric实现方式中, 也是用于扩展分布式分类账平台(经由“系统链码”)的公认语言。因此,有机会在Fabric平台中部署的Element_Chaincode中重用
ELEMENT_SDK上的工作。因此,ELEMENT_SDK已经变成了两个相似的软件包。第一
个用作SDK,如ELEMENT规范中所示。该软件包的第二个版本作为Element_Chaincode部件的
一部分进行部署,该部件将ELEMENT功能添加至Fabric对等节点。这使得executeQuery()
函数可用于“用户链码”智能合约,从而允许他们按照ELEMENT规范的要求使用SQL。
[1471]
[1472]
[1473]
[1474] 附录G
[1475] Fabric服务层接口规范
[1476] 介绍
[1477] Fabric服务实现了ELEMENT 1.0规范中的特定于平台的服务层抽象部件,并且实现了服务层接口,该服务层接口作为API层与分布式分类账平台之间交互的中间人。它的服
务有助于执行RDBMS相关操作。
[1478] 本附录详细介绍了Fabric服务,并且其功能签名(不包括如批量更新的少数特定于Fabric的功能)可以作为服务层接口的规范。
[1479] 先决条件
[1480] 利用ElementTM控制台部署Fabric服务需要满足以下先决条件:
[1481] 应安装Node 8.x。
[1482] Fabric设置应正确配置。
[1483] 服务和方法
[1484]
[1485]
[1486]
[1487]
[1488]
[1489]
[1490]
[1491]
[1492]
[1493]
[1494]
[1495]
[1496] Fabric服务
[1497] 这些服务是特定于Fabric分布式分类账平台的服务。以下是这些服务及其方法:
[1498]
[1499]
[1500]
[1501]
[1502] 附录H
[1503] ELEMENTTM解析器:介绍
[1504] ELEMENT解析器是ELEMENTTM的部件,它以下列方式处理查询字符串:
[1505] ·检查查询的语法是否有效
[1506] ·返回已解析的抽象语法树
[1507] ·如果查询无效则返回错误
[1508] ·检查标识符如数据库ID、表ID和列名是否遵循Element SQL规范中提到的指定语法
[1509] ·结合特定于Element的关键字处理各种现有SQL关键字,称为ELEMENT SQLTM
[1510] 解析器是在“pg‑parser‑native”之上实现的,“pg‑parser‑native”使用C库,该C库使用实际的PostgreSQL服务器源来解析SQL查询并返回内部PostgreSQL解析树。
[1511] 解析器通过将SQL查询解析成可以由ELEMENT作为本机分布式分类账数据提交到分布式分类账的对象,提供了处理关系数据的便捷方法。ELEMENT的解析SQL的能力使开发
人员能够使用已经普遍理解的语法来操作分布式分类账上的关系数据。
[1512] ELEMENTTM解析器:高级别要求
[1513] 为了确保在ELEMENT Fabric实现方式中成功使用解析器,需要满足以下要求:
[1514] ·Element系统链码应该启动并运行
[1515] ·需要部署Element控制台
[1516] ·解析器应作为 模块安装在Element控制台中
[1517] ·其也应该存在于安装了系统链码的所有Fabric对等点中。这确保系统链码能够在本地访问解析器。
[1518] 解析器功能的分离
[1519] 实现的ELEMENT解析器是单个的统一部件。然而,解析器功能基于要满足的ELEMENT规范的一部分分为2部分。具体地为DDL部分和DML部分。
[1520] 用户查询/输入的DDL解析在ELEMENT控制台内执行,DDL解析器是其中的一个组成部分。控制台在DDLParser的帮助下管理所有数据库结构修改请求。如果不进行大量修改,
就不可能在Fabric网络本身内完全利用DDL功能,因此在Fabric‑NodeJS实现方式中无法访
问这些功能。
[1521] 分布式分类账平台内需要对输入查询进行DML解析,并且添加了ELEMENT功能。对于该NodeJS/Fabric实现方式,DML解析器从ELEMENT系统链码运行,因此可被智能合约(用
户链码)访问。
[1522] 输入类型
[1523] Element解析器以字符串格式获取查询输入,并且使用存在于解析器中的名为“parseQuery”的函数调用。查询遵循Postgres SQL的查询规范。详细规范可以在
TM TM
ELEMENT 1.0 ELEMENT SQL 文档中找到。查询以添加的特定于Element的关键字为特点,
这提供了更好的数据处理。
[1524] ELEMENTTM解析器的组成
[1525] 解析器由4类功能组成,这些功能按照与用户访问级别相同的方式进行分类。下表:总结了这些功能:
[1526]
[1527]
[1528]
[1529]
[1530]
[1531]
[1532]
[1533]
[1534]
[1535] 在ELEMENTTM系统链码中的解析
[1536] ElementTM系统链码中的解析包括以下步骤:
[1537] 1.解析器被系统链码中存在的“执行查询”函数使用。系统链码。利用DML查询调用该函数之后,解析器将查询解析成AST对象。
[1538] 2.根据ElementTMDML操作的业务规则验证对象。无效的对象会导致错误。
[1539] 3.然后,经验证的AST对象被转换为一个对象,该对象包含特定于ElementTM系统链码中存在的功能的关键字,所述关键字基于查询所针对的操作。
[1540] 4.这使ElementTM系统链码能够进一步处理输入数据并处理所有DML操作。
[1541] 在ELEMENTTM控制台中的解析
[1542] ElementTM控制台中的解析遵循以下过程:
[1543] 1.ElementTM控制台中存在的“执行查询”功能在调用时使用解析器来解析输入查询。
[1544] 2.一旦解析器根据ElementTMDDL和DML操作的业务规则进行验证,它就会返回具有对象的控制台,该对象包含特定于控制台本身中存在的功能的关键字。
[1545] 3.控制台然后基于查询功能处理查询。如果是DDL,则调用控制台的函数,如果是DML,则调用系统链码。
[1546] 错误处理
[1547] 解析器通过在其自身端部验证输入查询来避免不必要的ELEMENTTM函数调用。不遵TM
守ELEMENT 的业务规则的数据会导致错误。错误包含与无效规则相关的错误消息和错误代
码。这也为调试查询和处理客户端错误的系统方式提供了便利。
[1548] Element解析器中的错误:
[1549]
[1550]
[1551]
[1552] 参考
[1553] [1]https://www.npmjs.com/package/pg‑query‑native
[1554] [2]https://github.com/lfittl/libpg_query
[1555] 附录I
[1556] 介绍
[1557] Element链码是ELEMENTTM的基本部件,用于在Fabric上执行所有与数据库相关的操作。使用Element链码在分布式分类账上处理查询形式的用户输入。Element链码依赖于
身份提供者和世界状态数据库来实现某些功能。
[1558] Element链码作为系统链码部署并作为对等进程的一部分运行。与用户链码不同,系统链码不是使用来自SDK或CLI的提议安装和实例化,而是在启动时由对等方注册和部
署。默认情况下不启用该功能,而是需要单独构建对等点。
[1559] 系统链码可以使用Go插件静态或动态地链接至对等点。然而,更好的方法是将系统链码作为插件加载,以避免出现在对其进行改变时需要重新构建的情况。对等点只需构
建一次即能够加载插件。
[1560] 链码上的每个操作都作为交易来处理,而一些操作需要作为一组交易来处理。链码将操作作为单个交易处理,并使用回滚机制来模拟交易,以防它们被批量处理。
[1561] 链码上的每个操作都遵循类似的流程,而其实现方式可能有所不同。作为主要步骤,对输入执行一般检查,如果有任何差异,则请求将被返回并且其影响将不会显示在分类
账上。其次,仅当调用实体具有对该操作的过程(由身份提供者处理)的适当访问权限时才
会转发请求。
[1562] 使用其证书检查每个调用实体的访问权限。在注册时,与该数据库相关的适当属性被添加至其证书。对于每个后续请求,执行检查。只有当实体对该操作具有访问权限时,
相关请求才会被处理,并且该实体将被授予执行该操作的权限。
[1563] 链码上的操作大致可以分为数据定义语言(DDL)和数据操作语言(DML)。链码经由另一链码限制DDL操作访问,因为DDL操作不在链码处解析。因此,在每个请求开始时,
ELEMENT系统使用交易提议来检查调用是否直接对链码进行。如果交易来自另一来源,则阻
止访问任何链码操作(DDL)。
[1564] 对于DML操作,查询可以直接作为输入发送。然后将每个查询发送至解析器,并且基于来自解析器的响应调用相应的操作。有关链码的每个方面的实现方式的另外的详细的
信息在下面的部分中给出。
[1565] 先决条件
[1566] 注册和部署Element链码必须满足以下先决条件:
[1567] ·Fabric网络应该正在运行。
[1568] ·需要使用名为“pluginsenabled”的构建标记构建对等点。
[1569] 部署
[1570] 与用户链码不同,系统链码不使用来自SDK或CLI的提议安装和实例化。它在启动时由对等方注册和部署。默认情况下不启用该功能,而是需要使用名为“pluginsenabled”
的构建标记构建对等点。
[1571] 系统链码可以以两种方式链接至对等点:
[1572] 1.静态——对于静态,为了将链码构建为对等进程的一部分,方法是让链码实现`SelfDescribingSysCC`接口[1]并在对等启动文件[2]中注册它的实例。接下来需要使用该
修改后的代码构建哪个对等点。
[1573] 2.动态——最好将系统链码作为插件加载。这样,每次对链码进行改变时,都无需重新构建对等点。对等点需要构建一次才能启用插件。
[1574] a.部署步骤——
[1575] i.用go写系统链码
[1576] ii.使用‑buildmode=plugin构建标志编译该go插件以产生共享对象(.so)库文件。
[1577] go build‑buildmode=plugin‑o.so.go
[1578] iii.构建对等点以启用加载GO插件:
[1579] DOCKER_DYNAMIC_LINK=真GO_TAGS+="pluginsenabled"制作对等物件
[1580] 注意——请记住在与Fabric版本的go版本相同的go版本上构建go插件。
[1581] iv.使用形成的物件图像启动网络。
[1582] v.将插件文件和.so文件复制在物件对等方中。
[1583] vi.在对等方的配置文件(core.yaml)中添加系统链码及其信息。
[1584] vii.重新启动对等方。
[1585] 参考
[1586] 1.https://github.com/hyperledger/fabric/blob/release‑1.3/core/scc/sysccapi.go#L78
[1587] 2.https://github.com/hyperledger/fabric/blob/release‑1.3/peer/node/start.go#L549
[1588] 方法
[1589] Init()
[1590] Init在链码注册期间被调用。该方法用于加载用于所有其他方法中的配置和初始化全局变量。
[1591] New()
[1592] 该方法必须存在于每个动态链接的系统链码中,因为该方法返回链码接口的实现方式。链码接口封装了所有方法,并且将它们转发为对等进程的一部分执行。
[1593] Invoke()
[1594] 该方法用于在链码上进行交易。这用作链码的API与Fabric对等点之间的单点联系。调用实体调用invoke方法来处理链码的任何其他方法。在检查调用实体是否具有适当
的访问权限并且输入被正确地表述为字符串化JSON之后,请求被中继到调用打算调用的相
应方法。
[1595] CreateDatabase()
[1596] 该方法在数据库创建开始时调用。通过为该特定数据库生成适当的元数据来处理请求。链码的所有其他方法都使用该元数据。
[1597] DropDatabaseMeta()
[1598] 调用该方法来启动数据库的删除,作为用户的批量操作进行处理。该方法标志着该过程的开始并返回该数据库中存在的所有表的列表。随后进行特定调用以删除表的元数
据及其所有记录。
[1599] DropDatabaseCommit()
[1600] 该方法用作批量中所有请求成功地处理之后删除数据库的最后调用。
[1601] RegisterUser()
[1602] 该方法用于将新用户添加至数据库,并且在向证书添加属性之后进行。
[1603] 只有具有管理员权限的用户才被允许添加其他用户,因此在检查调用实体的适当访问权限之后,请求中给出的用户身份将添加至数据库元数据。
[1604] DeleteUser()
[1605] 该方法用于从数据库中删除用户,并且在从证书中删除属性之后执行该操作。
[1606] 只有具有管理员权限的用户才被允许删除其他用户,因此在检查调用实体的适当访问权限之后,请求中给出的用户从数据库元数据中删除。
[1607] CreateTable()
[1608] 该方法用于创建新表并将其添加至现有数据库。首先,执行检查以验证当前数据库未处于空闲状态。随后,ELEMENT系统检查数据库中是否已存在表。随着这些验证,如果输
入数据一致,则形成表元数据并将其添加至分类帐中。表信息也被添加至数据库元数据。表
元数据用于验证对该表执行的所有操作。
[1609] DropTableMeta()
[1610] 调用该方法启动删除表,为用户进行批量操作处理。该方法标记进程的开始并设置DDL标志以限制对该表的其他操作。
[1611] DropTableRecords()
[1612] 该方法用于删除该表的记录。这将对指定的表记录递归地运行删除操作。对一批记录执行删除,而批的大小是可配置的。这样做是为了防止超出交易的时间限制。
[1613] DropTableCommit()
[1614] 该方法作为批量中所有请求成功地处理之后删除表的最后调用。调用实体发出调用以标记该过程的完成。所有中间交易ID都存储在分类帐中,以便用户可以返回单个交易
ID。随后,该表的元数据被删除,并且表名可以在未来的操作中重新用于创建新表。
[1615] AlterTableMeta()
[1616] 调用该方法以启动对表结构的修改。它作为批量操作进行处理。该方法标记进程的开始并设置DDL标志以限制对该表的其他操作。使用请求Element系统中给出的输入制定
更新模板,该更新模板将用于更新该表的所有记录。该更新模板在响应中返回。
[1617] AlterTableRecords()
[1618] 该方法用于修改该表的记录。这将修改表中存在的所有记录。对一批记录执行改变,而批的大小是可配置的。这样做是为了防止超出交易的时间限制。
[1619] AlterTableCommit()
[1620] 该方法作为在批量中的所有请求成功地处理之后修改表的最后调用。调用实体发出调用以标记该过程的完成。所有中间交易ID都存储在分类帐中,以便用户可以返回单个
交易ID。随后,可以再次在该表上提出请求。
[1621] InsertRecord()
[1622] 该方法用于向表中添加记录。添加至表的每个记录必须遵守创建表时设置的规则。因此,在每个请求中,首先检查是否可以基于表元数据中的约束添加列值。该方法存在
两个变体,一个是调用实体可能传递列,另一个是省略列名。两个变体的处理类似,并且在
省略列名的情况下仅从表元数据中选取列名。如果记录通过所有检查和验证,则将其添加
至具有设置为记录ID的主关键字值的分类帐。
[1623] UpdateRecord()
[1624] 该方法用于更新表的现有列的值。对记录所做的每次更新仍必须遵守表元数据中设置的约束。因此,在每次请求时,都会从分类帐中选取先前的记录数据,并且对记录进行
预期的改变。如果记录通过了所有检查和验证,则它会在具有不变的记录ID的分类帐中更
新。
[1625] 注意——在更新记录时无法更新主关键字值。
[1626] DeleteRecord()
[1627] 该方法用于从表中删除先前存在的记录。如果该记录存在且该表不在任何DDL过程下,则该记录将从分类帐中删除。一旦交易提交,就会看到它的效果。
[1628] CreateIndex()
[1629] 如果调用实体想要在现有列上添加索引,则使用该方法。首先,检查请求是否可以对给定的列执行索引。随后需要在状态数据库中添加哪些索引。该功能在Fabric中并不固
有地存在,因此需要在状态数据库上发出单独的请求,以便为给定的列添加索引。
[1630] DeleteIndex()
[1631] 如果调用实体想要删除现有列上的索引,则使用该方法。首先,检查请求是否可以对给定的列执行索引。随后从状态数据库中删除先前创建的索引。
[1632] SelectQueryWithPagination()
[1633] 该方法用于在状态数据库上执行给定的查询。结果基于预期的查询级别返回给调用实体。该方法仅执行读操作,并且因此对分类账没有影响。如果调用实体未指定限制,则
采用默认限制以防止超时运行交易。
[1634] BulkInsertRecord()
[1635] 该方法用于批量执行插入操作。对所有记录执行插入操作,如果其中任意一条记录失败,则返回批量而不影响分类帐。只有当列值满足表元数据中设置的约束时,才应添加
所有插入的记录。
[1636] BulkUpdateRecord()
[1637] 该方法用于批量执行更新操作。在对状态数据库执行查询之后得到的批量中的所有记录执行更新操作。如果其中任意一个失败,则返回批量而不影响分类帐。所有更新的记
录都应遵守表元数据中设置的约束。
[1638] BulkDeleteRecord()
[1639] 该方法用于批量执行删除操作。递归地,在对状态数据库执行查询之后得到的批量中的所有记录执行删除操作。如果其中任意一个失败,则对分类帐没有影响。
[1640] RollbackTransaction()
[1641] 一些操作需要作为一组交易处理,这些交易对于调用实体将显示为单个交易。如果其中任何一个未处理,则需要还原所有先前的交易。因此,在每个方法中,都会对回滚的
元数据进行策划,并且该方法用于利用给定的交易ID还原任意先前的交易。
[1642] DeleteTransactionMeta()
[1643] 一些操作需要作为一组交易处理,这些交易对于调用实体将显示为单个交易。如果其中任何一个未处理,则需要还原所有先前的交易。因此,在每个方法中,都会对回滚的
元数据进行策划。如果所有交易均已经成功地处理,则该方法用于删除给定交易ID的元数
据。
[1644] ExecuteQuery()
[1645] 该方法用于在链码处执行DML查询。请求中的查询被发送至解析器,来自解析器的输出用于处理相应的方法。在检查调用实体对该方法的访问之后,请求被中继到适当的方
法。
[1646] ShowDatabases()
[1647] 该方法用于列出任何调用实体可以访问的所有数据库。所有数据库都在调用实体的证书中提到,因此我们使用调用实体的证书来获取所有数据库的名称并返回它们。
[1648] ShowTables()
[1649] 该方法用于列出数据库中存在的所有表。数据库元数据中提到了所有表,因此我们获取数据库元数据并返回所有表的列表。
[1650] DescTable()
[1651] 该方法用于获取创建表时设置的所有约束。表元数据包含所有列的约束。因此,当发出请求时,则在删除内部信息之后返回表元数据。