写点什么

华为云区块链服务 (BCS)RESTFUL 链码调用 API 原理详解

  • 2020-03-25
  • 本文字数:3372 字

    阅读完需:约 11 分钟

华为云区块链服务(BCS)RESTFUL链码调用API原理详解

本文适合于熟悉开源区块链技术 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”]"


以上参数都是用户调用链码必须要准备的参数,用户需要将这些参数按照下面格式进行组织:


{  "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",}
复制代码


这些参数会直接作为 RESTful 请求的 HTTP BODY 进行发送。

使用证书对参数进行签名

用户可以从华为云官网获取自己创建的区块链服务的用户证书和私钥,使用私钥对上面步骤 1 中的参数进行签名。签名的方法各语言版本均有实现,在此不做累述。椭圆曲线签名结果为一串哈希值,将这个哈希值放入 HTTP 头部的制定字段 x-bcs-signature-sign 中。

将构造好的 HTTP 请求进行发送

各语言版本均对 RESTful 调用有成熟的支持,在此也不再累述,在此只给出一个实际的 RESTful HTTP 请求的内容供大家参考:


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----- MIIDBzCCAq2gAwIBAgIQEXPZlMsReamxVtVNnKwCCzAKBggqhkjOPQQDAjCCAQQx DjAMBgNVBAYTBUNISU5BMRAwDgYDVQQIEwdCRUlKSU5HMRAwMwUQYD14eH+jTTBLMA4GA1Ud DwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMCsGA1UdIwQkMCKAIFBXQ5TC4acFeTlT JuDZg62XkXCdnOfvbejSeKI2TXoIMAoGCCqGSM49BAMCA0gAMEUCIQCadHIKl0Mk Yn0WZizyDZYR4rT2q0nzjFaiW+YfV5FBjAIgNalKUe3rIwXJvXORV4ZXurEua2Ag QmhcjRnVwPTjpTE= -----END CERTIFICATE----- "}
复制代码


以上三个简单步骤就是使用华为区块链服务的 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


2020-03-25 16:281940

评论

发布
暂无评论
发现更多内容

CentOS环境下Redis的安装和配置

Empty

redis

【解析】通证经济的分类及用途

CECBC

模块五作业

沐风

20 k8s之持久性存储卷

穿过生命散发芬芳

k8s 11月日更

聊聊你眼中的spring的事务是怎么样的?

卢卡多多

spring事务管理 11月日更

一些关于原宇宙的思考

Simon

元宇宙 Metaverse

和12岁小同志搞创客开发:手撕代码,做一款亮度可调节灯

不脱发的程序猿

少儿编程 DIY 智能硬件 创客开发 Arduino

.NET6新东西--struct优化

喵叔

11月日更

如何用JavaScript实现add(1)(2)(3)

空城机

JavaScript 11月日更

requests-html库初识 + 无资料解BUG之 I/O error : encoder error,Python爬虫第30例

梦想橡皮擦

11月日更

区块链是什么

Rayjun

区块链

SAP OData 编程指南

汪子熙

API SAP OData 11月日更

模块四作业

覃飞

JavaScript 数组方法 slice() 的 5 个示例

devpoint

slice JavaScrip 11月日更

DDD是软件设计思维方式的转变

Bruce Talk

领域驱动设计 DDD

财经大课:通货膨胀的逻辑

石云升

学习笔记 财经思维 11月日更

区块链新闻编辑部成立,看区块链如何助力新闻传播?

CECBC

世界女性科技群落(一):一面喑哑、一面高亢的非洲鼓

脑极体

模块四作业:千万级学生管理系统的考试试卷存储方案

dean

架构实战营

Vue进阶(贰零壹):JS合并两个数组方法详解

No Silver Bullet

Vue 数组 11月日更

使用 Java connector 消费 ABAP 系统的函数

汪子熙

Java SAP abap 11月日更

模块四作业

doublechun

「架构实战营」

模块五作业

bob

「架构实战营」

kafka常用命令

williamcai

kafka

30分钟学习go语言

坚果

Go 语言 11月日更

Apache Pulsar 与 Kafka 性能比较:延迟性(测试方法)

Apache Pulsar

大数据 kafka 分布式 云原生 Apache Pulsar

工作三原则

ok绷

Go语言学习查缺补漏ing Day2

Regan Yue

Go 语言 11月日更

十分钟搞懂WebAssembly

俞凡

Wasm

区块链,不是元宇宙的全部

CECBC

架构训练营 - 模块 4 作业

焦龙

架构实战营

华为云区块链服务(BCS)RESTFUL链码调用API原理详解_云原生_华为云产品与解决方案_InfoQ精选文章