一步一步带你用超级账本fabric打造一个联盟链的应用

一步一步带你用超级账本fabric打造一个联盟链的应用

一步一步带你用超级账本fabric打造一个联盟链的应用

首先我们来通俗地说一下公共链、联盟链、私有链的区别,大家都知道区块链技术就是一个分布式的账本,那么公开链就是账本的信息内容是公开的,大家都能看到,联盟链就是只有一部分人看到账本,私有链就是只有自己能看到账本,其他人看不到。

一、联盟链的用处是什么?

传统的业务模型很难做到跨机构的交易被一个互信的机构监督执行。每个交易方都有自己独立的账本。发生交易时各自更改,造成账本同步的成本高昂且效率低下。仅有少数的中心系统,所以商业网络比较脆弱。联盟链提供了授权维护账本的机制,因此相对保证了数据的私密,公司作为上市主体,以盈利为目的,不可能所有的数据都公开。那么超级账本作为联盟链供企业使用比较合适。企业级区块链四大平台要素:1. 共享账本 2. 共识 3. 隐私和保密 4. 智能合约。 当前公链比如以太坊eos等其它三点都能满足,唯独隐私没法保证,另外效率普遍不高,没有最终确定性,又是被极客们主导的,不符合商业主流趋势,从而也限制了企业性质的应用。

企业级商用区块链网络比较适合使用联盟链和许可制。这样在一个限定的范围内,只有授权的节点和用户才能参与到交易和智能合约的执行中 来,而任何匿名节点或非授权用户均被拒绝服务。从团体联盟的角度 来看,这增加了区块链网络的安全可靠。 当前在欧美主流的区块链应用大部分是行业链或者是联盟链,也就是某一个行业的上下游,或者核心企业联合起来,一起构建的半公开化的区块链。从这个角度讲,超级账本具备成为未来最主要商用区块链技术平台的潜力,值得技术开发人员花时间和精力进行学习和研究。

联盟链的商用场景

金融:对银行、保险、清算、股权登记 交易、信用评级、公证等领域,既需要绝对的可信任,也需要隐私保密,所以特别适合区块链应用。比如可以模仿数字货币交易所做一套区块链股权登记和交易平台。

供应链:提供深度回溯、查询等核心功能,实现信息公开透明,出了问题可以依此来追责。附加值较高的食品、药品和疫苗、零部件生产检测结果等都可以使用区块链

传统企业的内部系统改造,加入区块链可以防止数据篡改

那么商用联盟链的代表就是超级账本fabric了

二、fabric

Hyperledger Fabric,它是由 IBM 带头发起的一个联盟链项目,于 15 年底移交给 Linux 基金会,成为开源项目。Hyperledger 基金会的成员有很多大牌,诸如 IBM,Intel,思科等。基金会里孵化了很多区块链项目,Fabric 是其中最出名的一个,一般我们说超级账本(Hyperledger)基本上指的都是 Fabric。目前使用fabric的商家有Cisco、 IBM、 Intel、 J. P. Morgan、 荷兰 银行、 SWIFT ,相信以后会更多。

那么我们来看看fabric的交流流程

一步一步带你用超级账本fabric打造一个联盟链的应用

(1)客户端构造交易提案

客户端应用程序利用任意SDK构造交易提案propose。该提案是一个调用智能合约功能函数的请求,用来确认哪些数据可以读取或写入账本。客户端把交易提案发送给一个或多个Peer节点,交易提案中包含本次交易要调用的合约标识、合约方法和参数信息以及客户端签名等。

(2)背书节点(Endorser)模拟执行交易

背书节点endorser收到交易提案后,验证签名并确定提交者是否有权执行操作。背书节点将交易提案的参数作为输入,在当前状态K-V数据库上执行交易,生成包含执行返回值、读操作集合和写操作集合的交易结果(此时不会更新账本),这些值的集合、背书节点的签名和背书结果(YES / NO)作为提案的结果返回给客户端SDK,SDK解析这些信息判断是否应用于后续的交易。

(3)背书节点将模拟执行结果返回给客户端

(4)客户端把交易发送到共识排序服务节点(Orderers)

应用程序(SDK)验证背书节点签名,并比较各节点返回的提案结果,判断提案结果是否一致以及是否参照指定的背书策略执行。客户端收到各个背书节点的应答后,打包到一起组成一个交易并签名,发送给Orderers。

(5-6-7)共识排序,生成新区块,提交交易

Orderers对接收到的交易进行共识排序,然后按照区块生成策略,将一批交易打包到一起,生成新的区块,调用deliver API投递消息,发送给提交节点(Committer)。Committer收到区块后,会对区块中的每笔交易进行校验,检查交易依赖的输入输出是否符合当前区块链的状态,完成后将区块追加到本地的区块链,并修改K-V状态数据库。

(8-9)各节点之间进行区块数据同步

好了,我们来实践操作一下吧。

三、部署一个fabric应用

Fabric依赖docker容器, 因此需要先安装和配置docker

下载超级账本源代码

1.如果没有安装git则执行

sudo apt install git

2.通过git安装

git clone https://github.com/hyperledger/fabric.git

部署调用

下载fabric Docker镜像文件

进入目录: cd fabric/ scripts
修改读写权限 chmod +x bootstrap.sh
改写.sh文件
Mac:sed -i '' 's/ curl/# curl/ g' bootstrap.sh
其它: sed -i 's/ curl/# curl/ g' bootstrap.sh
执行下载: ./bootstrap.sh

下载一个fabric-samples样例进行部署

git clone https://github.com/hyperledger/fabric-samples.git
进入目录并执行
cd fabric- samples/ basic-network docker-compose -f docker-compose.yml up -d
查看启动的容器
会输出以下内容: localhost: basic- network clarity$ docker ps CONTAINER ID IMAGE NAMES efddfbf4fc0a hyperledger/ fabric- peer: x86_ 64- 1. 0. 0 peer0. org1. example. com 606d13c1e7a2 hyperledger/ fabric- couchdb: x86_ 64- 1. 0. 0 couchdb d8c870db8634 hyperledger/ fabric- ca: x86_ 64- 1. 0. 0 ca. example. com c6f25a5e6fd6 hyperledger/ fabric- tools: x86_ 64- 1. 0. 0 cli a5f6331c5bc5 hyperledger/ fabric- orderer: x86_
创建通道,加入通道
加入 通道
peer channel join -b mychannel.block
创建通道
peer channel create -o orderer. example. com: 7050 -c mychannel -f /etc/ hyperledger/ configtx/ channel. tx
切换 环境 到 管理员 用户 的 MSP, 进入 Peer 节点 容器 peer0. org1. example. com
docker exec -it -e "CORE_ PEER_ MSPCONFIGPATH=/ etc/ hyperledger/ msp/ users/ Admin@ org1. example. com/ msp" peer0. org1. example. com bash
退出 Peer 节点 容器
exit
进入 cli 容器 安装 链 码 和 实例 化
进入容器
docker exec -it cli/bin/bash
安装链码
peer chaincode install -n mycc -v v0 -p github.com/chaincode_example02
实例化链码
peer chaincode instantiate -o orderer. example. com: 7050 -C mychannel -n mycc -v v0 -c '{"Args":["init","a","100","b","200"]}'
链码调用和查询
peer chaincode query -C mychannel -n mycc -v v0 -c '{"Args":["query","a"]}'
模拟转账
从“ a” 转移 10 到“ b”: peer chaincode invoke -C mychannel -n mycc -v v0 -c '{"Args":["invoke","a", "b"," 10"]}'
在分别查询a和b的值
peer chaincode query -C mychannel -n mycc -v v0 -c '{"Args":[" query"," a"]}' peer chaincode query -C mychannel -n mycc -v v0 -c '{"Args":[" query"," b"]}'

ok,一个完整的区块链应用就部署到fabric上了,那么网友肯定问,我们怎么没写代码就完成了,对,我们只不过使用了他的demo样例代码

我们先看看整个的fabric开发结构图

一步一步带你用超级账本fabric打造一个联盟链的应用

从上图我们可以看出开发人员只需要编写链码和编写应用程序调用链码进行交易就行了,链码就是智能合约。链码支持JAVA、GO、PYTHON,NODEJS进行开发

为了方便诸多不同的应用场景且使用不同语言的开发人员,Hyperledger Fabric 提供了许多不同的 SDK 来支持各种编程语言。如:

Hyperledger Fabric Node SDK:https://github.com/hyperledger/fabric-sdk-node
Hyperledger Fabric Java SDK:https://github.com/hyperledger/fabric-sdk-java
Hyperledger Fabric Python SDK:https://github.com/hyperledger/fabric-sdk-py
Hyperledger Fabric Go SDK:https://github.com/hyperledger/fabric-sdk-go

我们将使用 Golang 进行链码的开发,所以我们应该确定在本系统中有 Hyperledger Fabric 提供的相关API,其它语言的 SDK 我们以后再讲。

如果本地系统中没有相关的API,请执行如下下载命令:

$ go get -u github.com/hyperledger/fabric/core/chaincode/shim

链码启动必须通过调用 shim 包中的 Start 函数,而 Start 函数被调用时需要传递一个类型为 Chaincode 的参数,这个参数 Chaincode 是一个接口类型,该接口中有两个重要的函数 Init 与 Invoke 。
Chaincode 接口定义如下:

type Chaincode interface{
Init(stub ChaincodeStubInterface) peer.Response
Invoke(stub ChaincodeStubInterface) peer.Response
}
Init 与 Invoke 方法
编写链码,关键是实现 Init 与 Invoke 两个方法,必须由所有链码实现。Fabric 通过调用指定的函数来运行事务。
**Init:**在链码实例化或升级时被调用, 完成初始化数据的工作。
**invoke:**更新或查询提案事务中的分类帐本数据状态时,Invoke 方法被调用, 因此响应调用或查询的业务实现逻辑都需要在此方法中编写实现。
在实际开发中,开发人员可以自行定义一个结构体,然后重写 Chaincode 接口的两个方法,并将两个方法指定为自定义结构体的成员方法;具体可参考下一节的内容。

shim 包为链码提供了 API 用来访问/操作数据状态、事务上下文和调用其他链代码;peer 包提供了链码执行后的响应信息。所以开发链码需要引入如下依赖包:
"github.com/hyperledger/fabric/core/chaincode/shim"
shim 包提供了链码与账本交互的中间层。
链码通过 shim.ChaincodeStub 提供的方法来读取和修改账本的状态。
"github.com/hyperledger/fabric/protos/peer"
peer.Response:封装的响应信息。
一个开发的链码源文件的必要结构如下:

package main

// 引入必要的包
import(
"fmt"

"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/protos/peer"
)

// 声明一个结构体
type SimpleChaincode struct {

}

// 为结构体添加Init方法
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) peer.Response{
// 在该方法中实现链码初始化或升级时的处理逻辑
// 编写时可灵活使用stub中的API
}

// 为结构体添加Invoke方法
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) peer.Response{
// 在该方法中实现链码运行中被调用或查询时的处理逻辑
// 编写时可灵活使用stub中的API
}

// 主函数,需要调用shim.Start( )方法
func main() {
err := shim.Start(new(SimpleChaincode))
if err != nil {
fmt.Printf("Error starting Simple chaincode: %s", err)
}
}

因为链码是一个可独立运行的应用,所以必须声明在一个 main 包中,并且提供相应的 main 函数做为应用入口。

四、性能

为了应对orderers排序节点在处理高并发请求的性能问题,fabric除了solo模式外,还有一个kalfa模式,kalfa+zookeeper

Kafka本质上是一个消息处理系统,它使用的是经典的发布-订阅模型。消息的消费者订阅特定的主题,以便收到新消息的通知,生产者则负责消息的发布。

当主题的数据规模变得越来越大时,可以拆分为多个分区,Kafka保障在一个分区内的消息是按顺序排列的。

Kafka并不跟踪消费者读取了哪些消息,也不会自动删除已经读取的消息。Kafka会保存消息一段时间,例如一天,或者直到数据规模超过一定的阈值。消费者需要轮询新的消息,这是的他们可以根据自己的需求来定位消息,因此可以重放或重新处理事件。消费者处于不同的消费者分组,对应一个或多个消费者进程。每个分区被分贝给单一的消费者进程,因此同样的消息不会被多次读取。

崩溃容错机制是通过在多个Kafka代理之间复制分区来实现的。因此如果一个代理由于软件或硬件故障挂掉,数据也不会丢失。当然接下来还需要一个领导-跟随机制,领导者持有分区,跟随者则进行分区的复制。当领导者挂掉后,会有某个跟随者转变为新的领导者。

如果一个消费者订阅了某个主体,那么它怎么知道从哪个分区领导者来读取订阅的消息?

答案在于zookeeper服务。

zookeeper是一个分布式key-value存储库,通常用于存储元数据及集群机制的实现。zookeeper允许服务(Kafka代理)的客户端订阅变化并获得实时通知。这就是代理如何确定应当使用哪个分区领导者的原因。zookeeper有超强的故障容错能力,因此Kafka的运行严重依赖于它。

在zookeeper中存储的元数据包括:

消费者分组在每个分区的读取偏移量
访问控制清单,用于访问授权与限制
生产者及消费者配额,每秒最多消息数量
分区领导者及健康信息

在Hyperledger Fabric中的Kafka实际运行逻辑如下:
一步一步带你用超级账本fabric打造一个联盟链的应用

对于每一条链,都有一个对应的分区
每个链对应一个单一的分区主题
排序节点负责将来自特定链的交易(通过广播RPC接收)中继到对应的分区
排序节点可以读取分区并获得在所有排序节点间达成一致的排序交易列表
一个链中的交易是定时分批处理的,也就是说当一个新的批次的第一个交易进来时,开始计时
当交易达到最大数量时或超时后进行批次切分,生成新的区块
定时交易是另一个交易,由上面描述的定时器生成
每个排序节点为每个链维护一个本地日志,生成的区块保存在本地账本中
交易区块通过分发RPC返回客户端
当发生崩溃时,可以利用不同的排序节点分发区块,因为所有的排序节点都维护有本地日志


{{collectdata}}

网友评论0