智能合约简介

概述

在 Hyperledger Fabric 中,链码(Chaincode)又称为智能合约(下文中我们统一称为链码),是用Go,node.js或Java编写的程序,主要用于操作账本上的数据。用户的应用程序通过链码与 Fabric 账本数据进行交互。

一个完整的 Fabric 区块链应用包含用户的应用程序和用户编写的链码两部分。用户的应用程序通过区块链网络中部署的 Peer 节点调用链码,用户链码通过区块链网络的 Peer 节点来操作账本数据。如下图所示:智能合约

Fabric 中的 Peer 节点提供了调用链码相关服务的接口。用户的应用程序可以通过调用相关接口和 Fabric Peer 进行交互, Peer 节点通过与链码容器进行交互,完成应用程序和链码之间的交互。

用户的应用程序可以通过以下两种方式与 Fabric Peer 进行交互:

  • 利用 Fabric 提供的 SDK 与 Fabric Peer 进行交互,具体参看 Fabric SDK。

  • 利用阿里云BaaS提供的 API 接口 与 Fabric Peer 进行交互。

生命周期

链码开发编写完成后,并不能直接使用,需要经过一系列的操作之后才能应用在 Hyperledger Fabric 网络中进而处理客户端提交的交易。这一系列的操作是由链码的生命周期来负责管理。

Fabric 1.x 中管理 Chaincode 的生命周期主要有如下几个命令:

  1. package: 对指定的链码进行打包的操作。

  2. install: 将已编写完成的链码安装在网络节点中。

  3. instantiate: 对已安装的链码进行实例化。

  4. upgrade: 对已有链码进行升级。链代码可以在安装后根据具体需求的变化进行升级。

Fabric 2.x 中管理 Chaincode 的生周期主要有如下几个命令:

  1. package: 对指定的链码进行打包的操作。

  2. approveformyorg: 在网络提议某个已编写完成的链码。

  3. commit: 在网络中正式提交已编写完成的链码,默认超过半数成员通过提议后才能生效。

说明

Tips:在阿里云BaaS的控制台上,用户可以直接完成链码的上传、安装、实例化等操作,不需要依赖命令行来完成。

链码类型

在 Hyperledger Fabric 中,链码一般分为:

  • 系统链码

  • 用户链码

系统链码

系统链码负责 Fabric 节点自身的处理逻辑,包括系统配置、背书、校验等工作。系统链码仅支持 Go 语言,在 Peer 节点启动时会自动完成注册和部署,所以安装,实例化和升级不适用于系统链码。

系统链码主要包括以下几种:

  • 生命周期系统链码(LSCC):Lifecycle System Chaincode,负责对用户链码的生命周期进行管理。

  • 配置系统链码(CSCC):Configuration System Chaincode,负责处理 Peer 端的 Channel 配置。

  • 查询系统链码(QSCC):Query System Chaincode,提供账本查询 API,如获取区块和交易等信息。

用户链码

用户链码是由应用程序开发人员根据业务场景需求使用 Golang、node.js 或 Java 语言编写的操作区块链分布式账本的状态的业务处理逻辑代码,用户链码运行在链码容器中,通过 Fabric 提供的接口与账本状态进行交互。

用户链码在区块链应用上处于非常关键的一环,它直接接受用户业务逻辑的调用,并对区块链分布式账本数据进行操作。

背书策略

每个智能合约都有与之相关的背书策略。该背书策略可确定哪些组织必须批准智能合约生成的交易,然后才能将其确认为有效交易。在上传链码及实例化链码时,需要为其指定对应的背书策略。

背书策略举例:

  • OR ('Org1MSP.peer','Org2MSP.peer') 表示此通道中的两个组织任何一方背书即可;

  • AND (‘Org1MSP.peer’,’Org2MSP.peer’) 表示需要此通道中的两个组织背书。

更多参考:Fabric设计->背书策略

交易执行流程

在 Hyperledger Fabric上,一笔交易的执行需要 Peer节点、orderer节点、CA节点及client端共同参与。

  • Peer节点:该节点是参与交易的主体,可以说是代表每个参与到链上的成员,它负责储存完整的账本数据即区块链数据,负责共识环节中的执行智能合约,验证区块和交易并将合法交易提交(commit)到账本中。

  • Orderer节点:该节点接受包含背书签名的交易请求进行排序并打包生产新的区块,主体功能便是对交易排序从而保证各Peer节点上的数据一致性。

  • CA节点:该节点负责对加入链内的所有节点进行授权认证,包括上层的client端,每一个节点都有其颁发的证书用于交易流程中的身份识别。

  • client:Fabric对于client端提供了SDK让开发人员可以更容易的对接到区块链内的交易环节,交易的发起便是通过SDK进行。

交易的执行流程主要包含如下4大步骤:

交易执行流程
说明

该交易的执行流程图来自于Fabric社区的开源技术文档(已采用知识共享署名 4.0 国际许可协议进行许可)。

  1. 由client端发起一个交易请求,client会根据链码的背书策略决定把该笔交易发往哪些背书的peer节点,由peer节点进行投票,client汇总各背书节点的结果。上图中的背书策略要求Peer1、Peer2及Peer3参与交易,所以client将请求分别发给 Pee1、Peer2 和 Peer3。

  2. 三个 Peer 节点接收到交易请求后执行对应的链码并对结果进行签名然后分别将输出结果返回给client。

  3. client将收到所有的执行结果后连同各peer的背书(包括其投票结果以及背书签名)后打包发送给 Orderer节点。

  4. Orderer 将接收到的该次交易在交易池里进行排序并组合打包生成一个新的区块,并将新的区块发送给所有的Peer节点,每个Peer节点接收到新区块后,对其中的每一笔交易结果的签名进行验证是否符合背书策略,以及比对读写集合与本地的版本是否相同,如满足所有条件则将新的区块写入本地账本内完成交易。

更多参考:Fabric设计->交易流程

注意事项

跨通道的链码间调用

如果被调用链码与调用链码位于不同的通道,则仅允许读取查询。 也就是说,在另一个通道上的被调用链码仅仅是一个查询,它不参与后续提交阶段的状态验证检查。

相同通道下的链码间调用

如果被调用链码与调用链码位于相同通道,则其被调用链码生成的读写集会被加入调用链码对应的交易,即共用同一笔交易而不会产生不同的交易。

链码shim包依赖

链码中需要依赖shim包(ChainCodeStub)来与Peer节点通信,部分语言shim包也提供了扩展接口(例如处理调用者身份)。在链码实例化编译时Peer节点默认提供了与节点版本一致的shim包,如果您的链码依赖其他兼容版本(v1.4.x)的shim包,请一并打包在链码文件中。

  • 2020年4月29日之前创建的节点版本为v1.4.2,之后创建的节点版本为v1.4.5

  • Golang 依赖:

    • 老版本:github.com/hyperledger/fabric/core/chaincode/shim、github.com/hyperledger/fabric/protos/peer

    • 新版本:github.com/hyperledger/fabric-chaincode-go/shim、github.com/hyperledger/fabric-protos-go/peer

  • Java 依赖:fabric-chaincode-shim-1.4.x.jar、fabric-chaincode-protos-1.4.x.jar