阅读 282

区块链笔记:掌握超级账本开发后,我总结出7条学习心得

image

本着“以教带学,Learning by Doing”的想法,我于上周加入了HiBlock区块链技术布道群(入群请添加微信:baobaotalk_com)。这个群可不太好混,群规要求每个成员必需每周有输出,连续两次交白卷就要被踢出群。

在这样的压力之下,我决定开一个新坑:区块链周周记,记录下每周区块链的学习成果和爬坑经验。作为系列的新篇章,我选择从超级账本的Fabric开始。

1

为什么选择超级账本作为起点?

我在之前的文章中(https://www.jianshu.com/p/26baef7b2ac4)曾说过会从超级账本入手开始区块链的学习和实践,同时也给出了个人的理由。但作为一篇布道类文章,单单个人喜好是没有说服力的。

在Fabric(http://hyperledger-fabric.readthedocs.io/en/latest/whatis.html)的文档中,它强调了自己面向企业应用而生的理由:

  • 企业希望跟身份确定的人做生意,而非像公链那样完全匿名的对手方

  • 并非人人都可加入的商业网络

  • 交易的私密性,比如,对于不同的渠道或经销商,他们各自拿到的折扣不一样,这些信息必须是私密的,相互隔离。

  • 性能和交易确认的时延

可以看得出,相比起公链激进的做法,以Fabric为代表的联盟链要温和的多,并且也容易为企业所接受。加上其给出的若干限制,技术上的落地也相对容易很多。

2

Fabric中的主要组件

关于区块链本身的理论和介绍,目前已经烂大街了,在此也就是不再赘述。在本节,让我们来看看Fabric是如何通过主要组件完成技术落地的。

从大的方面讲,Fabric的主要组件大致可划分成这几个部分:

  • 分布式账本,解决数据共享问题,让所有参与方拥有共同的交易历史。

  • 智能合约,解决应用与账本的交互问题,包括查询和更新。

  • 共识机制,解决数据同步问题,基于Endorsement Policy实现交易的传播。

  • 成员服务,解决参与方身份问题,只有可信成员之间才能完成交易。

3

分布式账本

Fabric的分布式账本状态由两部分组成:世界状态(World State)和区块链。前者代表账本的当前状态,变更和查询频繁,往往以数据库形式实现;后者则用来捕获前者的每次变更,作为交易的变更记录,无法修改且极少查询,常常实现为文件形式。

对于世界状态的DB载体,当前版本有两个选择:内置的LevelDB和外置的CouchDB,如果想要获得更灵活的查询能力,选择后者。由此大家应该可以猜出:世界状态中保存的数据是以KV对的形式存在。

对于区块链来讲,它以Block的hash链组成,每个Block包含一组有序的交易。这个顺序是交易顺序,非常关键。

除了这两个组件,Fabric还引入了一个独特的设计:Channel,用来解决不同组织间的账本共享问题。假如组织A同时与组织B和组织C做生意,并且组织B和组织C是竞争对手,那么通过建立不同的Channel可以实现A和B,A和C分别共享各自的账本。利用Channel,很好地解决了常见的B2B场景。

Channel抽象出了业务参与方的沟通,可视为业务网络的子网,实现了交易的相互隔离和业务私密性。

4

智能合约

Fabric的智能合约以“链码(Chaincode)”的形式存在,外部客户端利用它来完成对世界状态的更改。与以太坊不同,链码支持使用通用编程语言来书写,当前版本支持Go和Node.js,但从Fabric Java SDK(地址:

https://github.com/hyperledger/fabric-sdk-java/blob/master/src/main/java/org/hyperledger/fabric/sdk/TransactionRequest.java)的源码中可以看出,离支持Java应该也不远了:

public enum Type {
   JAVA,
   GO_LANG,
   NODE
}
复制代码

对于初学者需要注意的是:链码 != Fabric SDK。前者运行于Fabric环境,执行业务逻辑。后者则由被客户端程序用来与链码完成交互。打个类似的比方:

  • 将Fabric环境视为Tomcat这样的容器。

  • 链码则可视为运行于其中的Servlet。

  • Fabric SDK则类似HttpClient这样的类库被Java客户端利用发起请求,实现于Servlet的交互。

由此可知,链码本身实际上是一个应用,其生命周期可分为:package、install、instantiate、upgrade。同样,链码可以绑定任意任意数量的Channel,并独立运行。

关于链码的教程,文档已经给出了详细的说明(地址:http://hyperledger-fabric.readthedocs.io/en/latest/chaincode.html),在此就不再啰嗦。

5

共识机制

Fabric中有三类节点:

  • Client,代表最终用户向endorser提交事务调用(Transaction Invocation),向ordering service广播事务提议(Transaction Proposal)。

  • Peer,提交事务,维护世界状态和账本副本(区块链)。其中,有一类特殊的Peer是Endorser。

  • Orderer,提供节点间的通信服务,保证消息的交付和顺序,典型如Kafka队列。

整个事务流程(地址:http://hyperledger-fabric.readthedocs.io/en/latest/txflow.html)在文档中有介绍:

  • client发起事务提议。

  • endorser peer验证并执行。

  • client检查事务提议的响应。

  • 若endorsement policy满足,client将endorsement打包进事务,提交给ordering service。消息包括:endorser签名、读写集和channel id。

  • 事务被orderer提交给channel上所有的peer,它们会检查并提交事务。

  • 账本更新。

从上面的流程可以看出,Fabric的共识机制建立在endorsement policy之上,它可以通过命令行参数进行配置,并不需要Channel的所有Peer参与。

6

成员服务

成员服务负责参与方的身份许可和验证,它建立于数字证书和信任链基础之上。所谓成员,既可以是组织(Org),也可以是组织部门(OU)。Fabric的成员服务配置可以出现在两处:Local(节点)和Channel(Channel级)。

从开发角度来讲,引入成员服务带来的作用就是:如果应用(Client和Chaincode)要参与到区块链网络中,则需要相应签名和证书。

7

Fabric的开发套路

老实讲,从上面的简单介绍已经看出,Fabric的开发并不简单,它至少涉及:

  • Client,提供UI、链码交互以及其他辅助功能。

  • 链码,负责执行业务逻辑。

  • 业务网络,定义参与方、Channel和Endorsement Policy。

  • 成员管理,定义组织及其成员映射,这涉及到一系列证书的发放。

  • 应用部署,将上面的各部分部署到Fabric环境。

这还不算完,如何测试也是一个大麻烦,相比起简单的CRUD应用,光搭建Fabric的环境就让人生畏。假如你对自己的要求更高点,想要实现一个持续集成环境,该怎么办?

此外,开发之后的运维成本也不会低,除了Fabric本身的基础设施,链码的平滑升级也对开发和运维提出了高标准。

鉴于这些麻烦的事情,假如你没有办法说服业务合作方也同样部署一套Fabric,我觉得完全没有必要去基于它来开发应用。单组织内的区块链应用,我个人认为是一个伪命题,没有存在的价值。

关于示例教程,Fabric的文档已经给出了范例(地址:http://hyperledger-fabric.readthedocs.io/en/latest/tutorials.html),各位可以仔细阅读。

为了降低区块链应用的开发难度,超级账本项目又引入了Composer(地址:https://hyperledger.github.io/composer/latest/)。其目的在于加速应用的开发和部署,目前已经支持Fabric,当前处于孵化阶段。它建立在诸多框架和工具之上:

  • node.js + angular,帮助开发者完成全栈区块链解决方案的开发。

  • yeoman,利用其模板功能快速搭建应用框架。

  • 一套开发环境,实现应用的打包部署以及暴露成Restful Service。

看起来很不错!对于一个初学者来讲,写这篇文章真不容易!如文章存在错误,不要客气,只管指出,:)。接下来给出一个Composer的例子。

8

Fabric应用-Composer框架

按照最开始的写作计划,我打算讲讲两种开发模式:直接使用Fabric API和利用Composer框架(地址:https://hyperledger.github.io/composer/latest/index.html)。可在通读完Composer的文档(地址:https://hyperledger.github.io/composer/latest/introduction/introduction.html)之后,我立即取消了原定计划,直接介绍Composer。

选择工具A而不是B一般情况下理由都很直接:简单易上手。以我个人为例,在翻完Fabric的文档之后,虽然对于Fabric的架构和组件了然于胸,但对于如何开发,其实还是很模糊的。

为什么会这样?有两个原因:

  • 文档本身给出的开发范例(fabric-samples)缺乏一个系统性的介绍。所谓系统性,说白了就是教科书性质的介绍,由一个简单的例子开始,层层递进,最终让读者全盘掌握。就当前的文档来说,这一任务显然没有达到。

  • 缺乏聚焦,正如这篇Composer幻灯片(第四页)(地址:https://www.slideshare.net/SimonStone8/introduction-to-hyperledger-composer)介绍的,有太多东西要操心了,对于真正需要关心的东西(业务逻辑)反而没有突出。

Composer恰好非常好的弥补了Fabric文档中这两个缺陷,从其文档构成可以很明显的看出来:

  • 给出Composer的整体性介绍

  • 手把手教会大家如何完成安装

  • 给出一个Hello World级别的例子

  • 如何进行单元测试

  • 如何部署到真实的Fabric环境

这种方式是我最喜欢的,对于开发者来讲,他能很快建立起整体印象,并且树立起信心。

当然,文档好并不足以吸引开发者成为粉丝。让其成为开发首选的理由只有一个:对开发者友好。

Composer的开发者友好性表现在以下几个方面。

1. 良好的抽象

Chaincode是Fabric开发的核心,但看过了例子(地址:https://hyperledger-fabric.readthedocs.io/en/release-1.1/chaincode4ade.html)之后,说真的,很容易让开发者打退堂鼓。因为太底层了!让人有一种回到用Servlet开发Java Web应用的感觉。

Composer在这一点上做得很好,它的Runtime内置了通用的Chaincode。使用它开发根本不会感到Chaincode的存在。而且整个过程几乎跟你开发一个普通的CRUD Web应用无异!在开发者看来,他就是在写普通的JavaScript函数。

这篇文章(地址:https://blog.selman.org/2017/07/08/getting-started-with-blockchain-development/)给出了两种方式(Chaincode和Composer)的开发范例,在结尾处提到两者的代码行差异:

This ±10x reduction in the number of lines of code when Go and Composer solutions are compared is fairly consistent across several samples.

2. 统一的工程化体验

实际的开发不是书上的简单例子,而且涉及多人,如果没有良好的开发规范,很难产生好的结果。从Fabric文档中,你无法看出一个区块链应用的项目工程应该是什么样子,只能看到一个个零散的代码文件。显然无法满足工程上的要求。

就一个Fabric区块链项目来讲,它包含:

  • 存储于账本上的Asset

  • 操作Asset的Chaincode

  • 访问Chaincode的Client App

  • 应用相关的权限和成员

Composer非常完美地给出了解决方案,将整个开发过程分成3部分,每一部分都有对应的命令行工具,提供统一的开发体验:

Business Network,业务逻辑,其中包括以下组件:

  • asset model,存储于账本上的Asset,其过程跟设计数据库的表没什么两样。

  • transaction function,对应Chaincode中的各个方法,但对于开发者来讲完全透明。

  • acl文件,权限定义。

  • query,命名查询,供transaction function调用。

Rest Server

  • 将发布到Fabric的Business Network暴露成Restful API,供外部调用,完全语言中立。

Client App

  • 严格来讲,这一步并非必要,因为既然上面已经有了语言中立的API,理论上可以用任何框架来开发相应的Client APP。但Composer提供了一个基于Angular的模板帮助加速这一过程。

怎么样,这个过程是不是非常眼熟?通过开发框架固化的开发过程可以让开发人员更快的上手,并且统一在相同的“big picture”之下。并且,上述的各个组件对于有经验的开发者并不陌生,有助于快速理解。

大家可以在文档中的这个例子(地址:https://hyperledger.github.io/composer/latest/tutorials/developer-tutorial)中看到完整的过程。

3. 内建测试的支持

即便是水平再烂的开发,他也希望能验证一下自己写的东西才好意思交出去。然而,对于Fabric应用来讲,这可不是件容易的事情,因为部署太繁琐了。

Composer再次拯救了开发!

Composer内置的runtime为测试提供了良好的支持,由于良好的抽象,这个runtime既可以是实际的Fabric,也可以是一个内置的Node.js进程。而后者则是为测试而生的。更好的是,这一切完全对开发者透明,开发的上层代码完全不需要改动。

对于上进心更强,想要实现自动化测试的同学,这里有一个例子(地址:https://github.com/hyperledger/composer-sample-networks/blob/master/packages/bond-network/test/Bond.js)可以参考。

4. 便捷的CLI工具

相比起Fabric零散的命令集合,Composer提供了便捷的CLI,统一了开发、管理和运营任务。开发者可以利用它方便的实现:

  • 应用打包和部署

  • 应用脚手架生成

  • 环境管理

让开发更加聚焦于手头的任务,而不是为了准备工作而分散太多精力。

前面说了Composer的那么多好处,接下来说说Composer的局限性。就目前的文档来看,我没有看到如何用它来开发System Chaincode的例子。而且,我怀疑当前的版本并不支持。因此,假如你像要开发的System Chaincode,Composer可能并不能满足你的需要。而这一任务应该算不上一个大众型任务。

或许你会奇怪,为什么我没有展示一个实际的例子来证明我说的这些好处。这只能怪Composer的文档写得太好了,基本是傻瓜式教程,按照它的步骤,基本不会出现什么问题。既然是这样,干嘛还要花时间在这个上面呢?

说到底,本文的目的只有一个:用Composer来开发未来的Fabric应用,不要再自虐了!同时,最新一期的Thoughtworks雷达(地址:https://assets.thoughtworks.com/assets/technology-radar-vol-18-cn.pdf)也将其列为“TRIAL”并给出了下面的评语:

... However, the programming abstraction of chaincode is relatively low level given it manipulates the state of the ledger directly. Moreover, it always takes a lot of time to set up infrastructure before writing the first line of blockchain code. Hyperledger Composer, which builds on top of Fabric, accelerates the process of turning ideas into software. Composer provides DSLs to model business assets, define access control and build a business network. By using Composer you could quickly validate your idea through a browser without setting up any infrastructure.

最后,请大家记住:即使Composer降低了开发的门槛,但还是要记得认真学习Fabric文档哟!

本文作者:HiBlock区块链技术布道群-胡键

原文发布于简书

5月23日(本周三)20:00-21:30,胡键老师将分享《快速入门超级账本开发》,通过一个案例展示HyperLedger Fabric开发全过程,同时介绍Fabric的主要架构和相关组件。

线上免费,识别下图二维码即可报名。

image

以下是我们的社区介绍,欢迎各种合作、交流、学习:)

image

文章分类
阅读