超级账本fabric项目试玩




最近跟着这本书学习区块链相关入门知识,

区块链技术指南pdf下载:https://legacy.gitbook.com/download/pdf/book/yeasy/blockchain_guide

该pdf已出版纸质书,《区块链原理、设计与应用》:https://item.jd.com/12159265.html

总体来说这本书对想了解区块链技术的初学者非常有价值,可以了解到区块链相关技术的来龙去脉、基本原理、知识体系、相关开源项目等等。看完超级账本项目fabric之后,感觉其整体框架跟同为分布式系统的OpenStack、k8s也比较类似(当然只是从框架来看,从底层实现来讲还是有很大差异的),主要差异在于其数据存储方式上,共识机制方面,OpenStack、k8s都是以传统数据库或etcd作为基础的,类似区块链中共识算法的多个提案者+一个确认者的场景。都是由多个服务构成,比如nova服务有nova-api、nova-compute、nova-scheduler、nova-conductor等服务,k8s有kublet、kube-apiserver、kube-proxy、kube-scheduler等服务,而fabric则有peer、ca、order这几个服务,他们也都有对应的客户端(命令行、sdk)用来发送请求给服务端。

fabric具体能干啥就不提了,还是看书吧,我还是从已知的IaaS、PaaS等云计算技术来对比,总体来说它可以用高级编程语言编写链码,然后上传到fabric区块链网络的某个节点里(具体来说是某个peer节点的docker容器里,我这里还有个疑问没有找到答案,一个链码只能跑在一个peer节点的一个容器里面吗?我理解应该是可以跑在多个peer节点的,从而实现分布式应用,不然就没有意义了),链码可以实现各种各样的功能(实现智能合约、账本管理等),链码用到的持久化数据都在区块链的块里存储,区块相当于是一个分布式数据库(或者专业名词叫分布式账本),从而实现应用的分布式、高可用、高可靠,以及数据的不可篡改,相比较而言,利用IaaS、PaaS等云计算技术也可以实现类似的功能或架构,尤其是k8s的微服务架构,也能支持分布式应用,但其数据却通常还是集中式存储的,并且容易篡改(当然其适用场景也不是为了解决这个问题,我这里只是随意对比下),也可以用分布式数据库来存数据,但仍然不像区块链那样,数据是用链表+区块来存储的。

要说fabric和k8s唯一的关联,我理解就是他们都是把链码或者说应用跑在docker里面的。fabric通过gRPC协议调用链码接口(接口比较固定),而k8s的服务则一般是通过HTTP RestFul API来调用服务(当然也有其他服务使用其他协议,如tcp或者专有协议)。

代码跑在哪里、数据存在哪里其实都不是关键,关键是怎么样让代码跑的愉快,跑的稳定,跑的没压力,还有就是让数据存的可靠,存的准确,存的安全。去中心化的问题,也是相对的,如果你的应用跑在全世界各地,数据也做到分布式存储到世界各地,我理解这也算是去中心化的。

不胡扯了,下面讲下怎么搭fabric测试环境,我这也是现学现卖,跟着官网文档学的,跑了一个example。我这里用的是fabric-1.1版本,操作系统是CentOS-7.2 x86_64。

环境准备:https://hyperledger-fabric.readthedocs.io/en/release-1.1/prereqs.html

主要是两个部分,一个是golang环境,一个是docker环境,docker包含docker daemon和docker-compose两部分。

安装比较简单,yum install golang docker docker-compose,完事儿,其他依赖如curl一般操作系统都是自带有的,当然下面还要用到git clone代码,也可以提前装上。

docker最好配置下国内的镜像源,否则下镜像要等死。修改docker daemon的配置,之后重启docker服务,systemctl restart docker。

上面的几个registry-mirrors不保证可用,最好自己找好用的替换。

之后就是下载代码了,需要下载两个项目,一个是fabric本身,一个是fabric-example,当然我是为了跑example示例才下载的第二个,如果你想手工搭fabric环境,可以不用下载第二个。

再之后就是准备fabric可执行文件了,脚本在fabric项目目录下的scripts目录下:

fabric/scripts/bootstrap.sh,直接cd到这个目录下,./bootstrap.sh执行就好了,因为我们已经checkout到1.1版本的release分支了,默认就是跑的1.1版本。

相关可执行文件会下载到scripts目录下的bin目录(get-docker-images.sh是代码库自带的,其他几个二进制文件是新下载的):

看下bootstrap脚本,可以看到是用curl命令下载的文件,每个文件几十M,国外网站比较慢,建议加上代理或者找国内的镜像(我是挂的代理)。

之后还要把这几个可执行文件所在目录加到PATH环境变量里(后面部署环境跑example要用到,具体来说是byfn.sh里面要用),让它们在任何目录下都可以被调用,当然也可以加上软链接,或者直接copy到/usr/local/bin之类的默认已加入环境变量的路径下,我这里是用的添加环境变量方式:export PATH=$PATH:/root/fabric/scripts/bin/

之后就是参考官方上手文档跑example了:https://hyperledger-fabric.readthedocs.io/en/release-1.1/build_network.html

文档里说是执行3步(文档里面有-m参数,看了下byfn.sh,里面已经没用这个参数了,不过貌似不影响执行,被忽略了):

每一步都有一堆输出,参考官网文档就行了,这里不贴了。

主要就是启动了一坨docker容器(在执行./byfn.sh up命令过程中通过docker ps -a命令查看):

通过镜像名就可以看出来容器跑的什么服务。

仔细看下byfn.sh就可以分析出fabric是怎么部署的(至少开发测试环境可以这么部署):

部署环境主要就是跑了这句: IMAGE_TAG=$IMAGETAG docker-compose -f $COMPOSE_FILE up -d 2>&1

然后就是在cli那个容器里跑example: docker exec cli scripts/script.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT

跑example过程中会有一坨日志在屏幕上输出。

因此部署环境就是通过docker-compose -f $COMPOSE_FILE up -d来搞定的,IMAGETAG可以通过byfn.sh的-i命令指定,默认是latest。COMPOSE_FILE可以通过-f命令指定,默认是docker-compose-cli.yaml,我们看下这个yaml文件:

可以看出里面定义了一个容器网络,networks: byfn,几个volumes与容器名称相同,在base/docker-compose-base.yaml文件里面有用到,6个service包含1个order节点、4个peer节点、一个cli节点(依赖其他5个service,这个容易理解,客户端必须要等服务端启动才能执行命令),每个service各包含一个容器实例,容器名称与service名称一样(就是上面贴出来的docker ps -a命令的看到的容器列表)。

除了cli这个service之外,其它几个都继续使用了base/docker-compose-base.yaml这个compose配置,这里就不贴了,而这个yaml里的peer服务又依赖了base/peer-base.yaml。总之就是定义了一坨docker容器,然后利用docker-compose编排功能把容器跑起来。

关于docker-compose,可以参考官方文档:

networks、volumes等配置文件中关键字的意义可以参考上面的文档,简单来说部分是给docker实例准备的各种参数,与k8s的service配置文件比较类似,都是为编排服务里各种容器的。这里networks默认就是一个Linux bridge,volumes就是一个临时目录mount到docker容器里给容器用来保存临时数据。

配置文件里端口映射、命令行、环境变量啥的就不说了。

可以看出,整个集群或者说区块链网络就是通过docker compose的编排功能实现的。比手工部署跑起来简单方便多了。