本文适合于熟悉开源区块链技术 Hyperledger Fabric,以及希望更高效地使用华为云区块链服务的读者。当然,也希望任何对区块链技术有兴趣的读者能从本文中受益。
2018 年 2 月 1 日,华为云发布企业级区块链开放平台区块链服务 BCS(Blockchain Service),是基于开源区块链技术 Hyperledger Fabric 和华为在分布式并行计算、数据管理、安全加密等核心技术领域多年积累基础上推出的企业级区块链云服务产品,旨在帮助各行业、企业在华为云上快速、高效的搭建企业级区块链行业方案和应用。
然而搭建区块链平台并不是目的,华为 BCS 服务的初衷是让客户更简单、更高效地使用区块链。本文要介绍的 RESTFUL 链码调用 API 即是 BCS 服务提供的易于客户端与区块链服务集成的 API。在详细讲解之前,我们先对链代码做一下简单介绍,便于没有 Fabric 知识背景的读者理解。
我们知道区块链是一种由区块串联而成的链式结构,每一个区块上都记录着账户数据,这些数据一经写入是不可篡改的。那么数据是如何写入的呢?如果让拥有写入权限的用户都能随意写入数据的话,区块链也就失去了存在的意义,因此链代码概念的引入意义重大。链代码又被称之为智能合约,顾名思义就是向区块链写入数据的预先约定好的代码。它是一段逻辑,这个逻辑可以是简单的限制和约束,也可以是非常复杂的业务相关的逻辑,根据用户的输入,进行逻辑的运算,最终得出向区块链写入的数据集合,然后将数据写入到区块链上去。如果这样描述过于抽象的话,我们以一个账户转账的例子来进行说明。
如上图所示,图中右边的区块链记录着原始账户的余额,a 为 100 元,b 为 200 元。图中左边客户端应用程序发起一笔转账交易:a 向 b 转 x 元。这笔交易不会直接写入区块链,而是先经过中间的链代码进行智能合约的运算,检查 a 的账户里是否有足够的余额,然后才允许转账交易的进行,将最终的 a、b 账户的余额写入到最新的区块链中。
我们可以看到,上述交易过程以及链代码的作用非常浅显易懂,但实际上由我们的应用程序向链代码发起调用的过程还是有些复杂的工作要做的。因为区块链的调用请求不同于普通的 RPC 远程调用,客户端在一次链码调用过程中需要做的工作如下:
将链代码的调用信息如通道 ID、链码 ID、调用参数、调用者信息等进行打包
将打包好的二进制内容使用用户私钥进行签名
根据链码的背书策略不同,可能需要向多个组织的节点上的链码发起调用
由此可见,这个调用过程如果让客户端开发人员自己来实现是不太现实的,因此需要借助 SDK 的帮助来实现。目前根据客户端的语言不同,SDK 也有各种不同的语言版本,例如 golang 语言就有 fabric-sdk-go 的实现,javascript 也有 nodejs 版本的 SDK 实现。我们先来看一下使用 SDK 需要的配置文件以及使用 SDK 进行调用的示例代码片段:
上图是一个 200 行的 SDK 配置文件片段
这是一个 nodejs 版本的 SDK 使用示例,我们从中可以看到客户端应用直接使用 SDK 的弊端:
配置文件书写复杂
虽然华为云已经提供了 SDK 配置文件下载功能,对于首次使用 SDK 的开发人员来说成本仍然很高。
SDK 语言相关,并且学习成本高
虽然很多语言都提供了 Fabric SDK,但是学习起来仍然有一定学习成本,并且不同语言的类库名称,方法名称调用方式都各不相同,切换不同语言时的学习成本成倍增加。
SDK 过于厚重
应用程序在使用 SDK 的时候需要将 SDK 类库引入,虽然不用开发语言的 SDK 打包后大小各不相同,但对于一些薄客户端(比如安卓或者 IOS 手机应用)来说仍然显得十分厚重。
至此,我们回到本文的重点:华为云为了方便开发者调用区块链服务,在服务端提供了 RESTFUL 的 API 以克服上述直接使用 SDK 方式的不足:
如上面架构图所示,华为云区块链服务直接暴露 RESTful 形式的 API 供开发者使用,在服务端的 RESTful 封装了对 SDK 的调用。用户如果需要发起链码调用只需要如下步骤:
准备链代码调用所需要的参数
channelId: 通道 ID
chaincodeId: 链码 ID
chaincodeVersion: 链码版本号
userId: 用户 ID
orgId: 组织 ID
opmethod: 链码调用类型,是 invoke(修改)还是 query(查询)
args: 链码参数, 例如:"[“invoke”,“a”,“b”,“1”]"
以上参数都是用户调用链码必须要准备的参数,用户需要将这些参数按照下面格式进行组织:
这些参数会直接作为 RESTful 请求的 HTTP BODY 进行发送。
使用证书对参数进行签名
用户可以从华为云官网获取自己创建的区块链服务的用户证书和私钥,使用私钥对上面步骤 1 中的参数进行签名。签名的方法各语言版本均有实现,在此不做累述。椭圆曲线签名结果为一串哈希值,将这个哈希值放入 HTTP 头部的制定字段 x-bcs-signature-sign 中。
将构造好的 HTTP 请求进行发送
各语言版本均对 RESTful 调用有成熟的支持,在此也不再累述,在此只给出一个实际的 RESTful HTTP 请求的内容供大家参考:
以上三个简单步骤就是使用华为区块链服务的 RESTful API 进行链代码调用的全部过程。可以看到整个流程非常简单,没有引入新的 SDK,调用方式是绝大多数程序员非常熟悉的 RESTful 方式,对于用户来说使用起来没有任何负担。
如果读者作为区块链智能合约的调用者,看到此处可以说已经足够了解华为云区块链 RESTful API 的使用方法了。 但还有用户也许有会对我们的 RESTful 服务感到好奇,想了解为何可以把复杂的链码调用变得如此简单,那么下面的内容可以作为扩展阅读,我们将简单阐述 RESTful 服务的内部机制。
之前我们提到应用程序与区块链代码交互步骤中,客户端所做的工作除了包装方法调用参数之外,最重要的一项工作就是进行签名,签名可以保证交易不会被其他人冒充。那么 RESTFUL 调用同样也存在这个问题,RESTFUL 是基于 HTTP 协议的,更为通用,因此在安全上我们更要做好充足的工作以保证其不可被冒充,下图阐述了华为 RESTFUL 链码调用的机理:
如图所示,华为云利用开源区块链已有的 MSP 功能所提供的安全架构,使用和 SDK 类似的方式对交易进行保障,RESTful 服务逻辑概括如下:
1)当客户端发起 RESTful 链码调用时,首先使用用户的私钥对整个 RESTful 方法体进行签名,将签名的结果放到 HEADER 的 x-bcs-signature-sign 字段中。
2)RESTful 服务端接收到请求后,会使用用户的公钥对请求进行验签。
3)验签通过后,RESTful 服务内部封装了原生 SDK 调用,根据原始请求重新构造 SDK 调用参数,并提供 SDK 所需的配置文件及私钥信息使用原生 SDK 进行链代码调用。
至此,相信读者已经对华为区块链服务的 RESTFUL 链码调用 API 机制有了深刻的了解,那么这种调用方法和普通的 SDK 方式相比优势何在呢,归纳总结如下:
使用简单方便,由华为云区块链服务封装 SDK 的复杂性。
由于绝大多数语言都已经拥有很成熟的 RESTFUL 调用类库,调用 RESTFUL 基本没有学习成本。
不用引入 SDK 类库,适合更轻量的客户端,例如手机端。
本文转载自 华为云产品与解决方案 公众号。
原文链接:https://mp.weixin.qq.com/s/wSKtWZ05H8FAa--syXpidA
评论