本文适合于熟悉开源区块链技术Hyperledger Fabric,以及希望更高效地使用华为云区块链服务的读者。当然,也欢迎任何对区块链技术有兴趣的读者阅读本文,相信读者们都能从中受益。

2018年2月1日 华为云发布企业级区块链开放平台区块链服务BCS(Blockchain Service),是基于开源区块链技术和华为在分布式并行计算、数据管理、安全加密等核心技术领域多年积累基础上推出的企业级区块链云服务产品,旨在帮助各行业、企业在华为云上快速、高效的搭建企业级区块链行业方案和应用。

如前所述,搭建区块链不是目的,关键是要方便应用更高效地使用区块链。本文要介绍的RESTFUL链码调用API即是华为云区块链为此目的而开发的,在详细介绍API之前,先对链代码做一下简单介绍,便于没有Fabric知识背景的读者理解。

我们知道区块链是一种由区块串联而成的链式结构,每一个区块上都记录着账户数据,这些数据一经写入是不可篡改的。那么数据是如何写入的呢?如果让拥有写入权限的用户都能随意写入数据的话,区块链也就失去了存在的意义,因此链代码概念的引入意义重大。链代码又被称之为智能合约,顾名思义就是向区块链写入数据的预先约定好的代码。它是一段逻辑,这个逻辑可以是简单的限制和约束,也可以是非常复杂的业务相关的逻辑,根据用户的输入,进行逻辑的运算,最终得出向区块链写入的数据集合,然后将数据写入到区块链上去。如果这样描述过于抽象的话,我们以一个账户转账的例子来进行说明。
区块链中的RESTFUL链码调用API原理详解_第1张图片
如上图所示,图中右边的区块链记录着原始账户的余额,a为100元,b为200元。图中左边客户端应用程序发起一笔转账交易:a向b转x元。这笔交易不会直接写入区块链,而是先经过中间的链代码进行智能合约的运算,检查a的账户里是否有足够的余额,然后才允许转账交易的进行,将最终的a、b账户的余额写入到最新的区块链中。
整个交易过程以及链代码的作用其实非常浅显易懂,但其实我们的应用程序向链代码发起调用的过程还是有些复杂的。因为区块链的调用请求不同于普通的RPC远程调用,客户端需要有如下的事情:

1,将链代码的调用信息如通道ID、链码ID、调用参数、调用者信息等进行打包,
2,将打包好的二进制内容使用用户私钥进行签名
3,根据链码的背书策略不同,可能需要向多个组织的节点上的链码发起调用
区块链中的RESTFUL链码调用API原理详解_第2张图片
由此可见,这个调用过程如果让客户端自己来实现是不太现实的,因此需要借助SDK的帮助来实现。目前根据客户端的语言不同,SDK也有各种不同的语言版本,例如golang语言就有fabric-sdk-go的实现,javascript也有nodejs版本的SDK实现。我们先来看一下使用SDK需要的配置文件以及使用SDK进行调用的示例代码片段:
区块链中的RESTFUL链码调用API原理详解_第3张图片
上图是一个200行的SDK配置文件片段
区块链中的RESTFUL链码调用API原理详解_第4张图片
这是一个nodejs版本的SDK使用示例。由此我们可以看出客户端应用直接使用SDK的弊端:
1,配置文件书写复杂 虽然华为云已经提供了SDK配置文件下载功能,对于首次使用SDK的开发人员来说成本仍然很高。
2,SDK语言相关,并且学习成本高 虽然很多语言都提供了Fabric SDK,但是学习起来仍然有一定学习成本,并且不同语言的类库名称,方法名称调用方式都各不相同,切换不同语言时的学习成本成倍增加。
3,SDK过于厚重 应用程序在使用SDK的时候需要将SDK类库引入,虽然不用开发语言的SDK打包后大小各不相同,但对于一些薄客户端(比如安卓或者IOS手机应用)来说仍然显得十分厚重。
华为云为了方便开发者使用区块链服务,在服务端提供了RESTFUL的API以克服上述直接使用SDK方式的不足:
区块链中的RESTFUL链码调用API原理详解_第5张图片
如上面架构图所示,华为云区块链服务直接暴露RESTFUL形式的API供开发者使用,在服务端封装了对SDK的调用。因为华为云替用户管理着区块链的组织结构以及各种证书,所以天然具备了所需要的SDK的配置文件,不需要用户自己手动生成。在此给出一个RESTFUL链码调用请求的Header和Body的示例供读者参考:
HEADER:
x-bcs-signature-sign: 1f8b08000000000000ff14cbb11503510c02b081d260c098bfff6279d74bb90a5ca7384e3cae9b5825af7cb076b65e039be41da8e8b1e38700d599fa4aee37d6c159a94355ada783dbb4d66e17e967db39cef36bcd0b5adc8be3e178698ef9070000ffff
BODY:
{
“channelId”: “testchannel”,
“chaincodeId”: “zmmcode”,
“chaincodeVersion”: “1.0”,
“userId”: “User1”,
“orgId”: “7258adda1803f4137eff4813e7aba323018200c5”,
“opmethod”: “invoke”,
“args”: “[“invoke”,“a”,“b”,“1”]”,
“timestamp”: “2018-10-31T17:28:16+08:00”,
“cert”: “-----BEGIN CERTIFICATE-----\nMIIDBzCCAq2gAwIBAgIQEXPZlMsReamxVtVNnKwCCzAKBggqhkjOPQQDAjCCAQQx\nDjAMBgNVBAYTBUNISU5BMRAwDgYDVQQIEwdCRUlKSU5HMRAwMwUQYD14eH+jTTBLMA4GA1Ud\nDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMCsGA1UdIwQkMCKAIFBXQ5TC4acFeTlT\nJuDZg62XkXCdnOfvbejSeKI2TXoIMAoGCCqGSM49BAMCA0gAMEUCIQCadHIKl0Mk\nYn0WZizyDZYR4rT2q0nzjFaiW+YfV5FBjAIgNalKUe3rIwXJvXORV4ZXurEua2Ag\nQmhcjRnVwPTjpTE=\n-----END CERTIFICATE-----\n”
}
看到这里,读者可能会对上面Header中的签名以及Body中的cert证书信息有所疑惑。请不要着急,在此先介绍一下华为云区块链RESTFUL接口的实现原理,读者自然就能解除心中疑虑。
区块链中的RESTFUL链码调用API原理详解_第6张图片
根据前文我们已经了解区块链的调用和普通RPC的远程调用最主要的区别在于需要有用户签名用于证明交易是指定用户所发起的,那么RESTFUL调用也不可避免这个问题。因此我们在使用华为云区块链RESTFUL接口时仍然需要使用用户私钥对整个请求消息体进行签名如图中所示,签名的结果放到HEADER中指定名称下。这个签名在服务端会使用用户的公钥进行验证,验证通过交易才能继续。

在某些情况下,用户的公私钥对并不是华为云区块链服务管理的,而是用户使用组织私钥自行签发的,这个时候服务端就缺少这个用户的公私钥,此时就需要在请求消息体中使用cert字段上传用户公钥,服务端使用用户上传的公钥验证HEADER中的签名是否是私钥对消息体的合法签名。这时问题就来了,任何一个伪造者都可以自己制作一个非对称的公私钥对,然后对一个非法的消息体进行私钥签名,并把公钥放到消息体中以通过服务端的验签。为了避免这个漏洞,服务端在验签之前会对用户上传的公钥进行合法性验证,如上图。因为用户上传的公钥实际上是一个证书,该证书包含了用户公钥以及组织私钥对该证书的签名,而伪造者缺少组织私钥无法伪造签名,这样服务端就能判定用户上传证书的合法性。

当服务端使用合法的用户证书验证请求HEADER中的签名是用户私钥的签名后,服务端就可以真正发起区块链链码的调用了,这里服务端使用SDK的方式与客户端直接使用SDK的方式并无不同,只不过如果客户端证书是自行签发的,那么服务端是没有用户私钥的,这个时候就会使用组织的admin证书发起区块链链码的调用。
至此,RESTFUL的调用机制读者也清楚了,那么RESTFUL调用的优点也就很容易理解:

1.使用简单方便,由华为云区块链服务封装SDK的复杂性。

  1. 由于绝大多数语言都已经拥有很成熟的RESTFUL调用类库,调用RESTFUL基本没有学习成本。
  2. 不用引入SDK类库,适合更轻量的客户端。
    以上就是对华为云区块链RESTFUL链代码调用API的原理的详细讲述,目前RESTFUL接口还处于公测阶段,欢迎读者到华为云进行免费体验并提出宝贵意见。

参考资料:API参考


来源:CSDN
原文:https://blog.csdn.net/weixin_43682574/article/details/85077234
版权声明:本文为博主原创文章,转载请附上博文链接!