• -------------------------------------------------------------
  • ====================================

05-ChainCode生命周期、分类及安装、实例化命令解析

区块链 dewbay 5年前 (2020-01-06) 1868次浏览 已收录 0个评论 扫描二维码

在 HyperLedger-Fabric 区块链网络中,ChainCode是一个重要的部分。它运行在与外界隔离的容器中,承担着更新账本的重要功能。可以说,Fabric 区块链网络所维护的公共账本,正是因为有了ChainCode,才有了“代码即法律”一说。接下来,这篇文章将来将简单介绍一下ChainCode。全文按照如下结构来展开:

05-ChainCode生命周期、分类及安装、实例化命令解析
全文结构

1、ChainCode 与智能合约

首先,来说一下智能合约。

智能合约,是一个抽象的概念。那么,智能合约有什么样的特性呢?

智能合约的历史可以追溯到 1990s 年代。它是由尼克萨博(Nick Szabo)提出的理念,几乎与互联网同龄。他在发表在自己的网站的几篇文章中提到了智能合约的理念。他的定义如下:

“一个智能合约是一套以数字形式定义的承诺(promises) ,包括合约参与方可以在上面执行这些承诺的协议。”

这样高度抽象的定义,只有建立在一定的知识储备量,才能够理解。这里,我们不去强行解释清楚什么是智能合约,而是抓住智能合约的几个重要的属性,来慢慢的理解智能合约。

简单来讲智能合约就是用程序实现合约的内容,并且这个程序是事件驱动、有状态的。下图是智能合约的模型。

05-ChainCode生命周期、分类及安装、实例化命令解析
智能合约模型

智能合约程序不只是一个可以自动执行的计算机程序:它自己就是一个系统参与者。它对接收到的信息进行回应,它可以接收和储存价值,也可以向外发送信息和价值。

这个程序就像一个可以被信任的人,可以临时保管资产,总是按照事先的规则执行操作

智能合约模型:它是运行在可复制、共享的账本上的计算机程序,可以处理信息,接收、储存和发送价值。

从合同的角度来说,智能合约(Smart contract )是一种旨在以信息化方式传播、验证或执行合同的计算机程序。

那么,什么是ChainCode

ChainCode(链码)是智能合约在 Fabric 区块链网络的实现形式。

链码被部署在 Fabric 网络节点上,运行在隔离沙盒(目前为 Docker 容器)中,并通过 gRPC 协议与相应的 Peer 节点进行交互,以操作分布式账本中的数据。

启动 Fabric 网络后,可以通过命令行或 SDK 进行链码操作,验证网络运行是否正常。

它扮演的角色如下图所示:

05-ChainCode生命周期、分类及安装、实例化命令解析

应用程序通过向区块链网络发送交易来调用智能合约,从而操作账本中的状态。


2、ChainCode 的运行方式

在 Fabric 中交易的处理过程,客户端将提案首先发送到背书节点,背书节点检提案的合法性。如果合法的话,背书节点将通过交易所属的链码临时执行一个交易,并执行背书节点在本地持有的状态副本。

Chaincode应该仅仅被安装于 chaincode 所有者的背书节点上,链码运行在节点上的沙盒(Docker 容器)中,并通过 gRPC 协议与相应的 Peer 节点进行交互,以使该 chaincode 逻辑对整个网络的其他成员保密。

请务必在一条 channel 上每一个要运行你 chaincode 的背书节点上安装你的 chaincode

其他没有 chaincode 的成员将无权成为 chaincode 影响下的交易的认证节点(endorser)。也就是说,他们不能执行 chaincode。不过,他们仍可以验证交易并提交到账本上。

ChainCode要在区块链网络中运行,需要经过链码安装链码实例化两个步骤。

[多次安装,一次实例化]
在一个区块链子链中,该网络是由“1 账本+1 通道+N 个 peer 节点”组成。
如果我们要手动来搭建 Fabric 网络的话,即通过命令行的形式来进行 ChainCode 的安装与实例化。我们需要多次 install,一次 instance。

也就是说,对于整个 Fabric 网络来说,假设有 X 个背书节点,那么,我们需要给每个背书节点安装 ChainCode,但是在整个网络搭建过程中只需要 instance ChainCode 一次。
因为 install 针对的是背书节点,instance 针对的是通道。

install 链码的对象是背书节点,主要目的是方便背书节点对运行链码,对交易进行模拟。
instance 链码的对象是 channel,主要目的是为了将安装过的链码在指定通道上进行实例化调用,在节点上创建容器启动,并执行初始化操作。实例化的过程中,需要指定背书策略,来确定通道上哪些节点执行的交易才能添加到账本中。

安装的过程其实就是对指定的代码进行编译打包,并把打包好的文件发送到 Peer,等待接下来的实例化。其实,这就是我们接下来要讲解的链码的生命周期这一部分。

实例化链上代码主要是在 Peer 所在的机器上对前面安装好的链上代码进行包装,生成对应 Channel 的 Docker 镜像和 Docker 容器。并且在实例化时我们可以指定背书策略

1. Chaincode 运行在一个受保护的 Docker 容器当中,与背书节点的运行互相隔离。
2. Chaincode 可通过应用提交的交易对账本状态初始化并进行管理。


3、ChainCode 的生命周期

对于区块链网络的操作者来说,他们也许并不想涉足 chaincode 应用的开发,不过却需要肩负管理区块链网络的责任,并运用 Hyperledger Fabric API 来安装、实例化与升级 chaincode。

Hyperledger Fabric API 提供了四个管理 chaincode生命周期的命令:package, install, instantiate,upgrade。在未来的版本中,正考虑添加stopstart交易的指令,以便能方便地停止与重启 chaincode,而不用非要真正卸载它才行在一个区块链网络中,将打包、安装、实例化和升级 chaincode 的过程作为一种可操作的 chaincode生命周期函数进行调用。

在这里,我们简单讨论package,signpackageinstall, instantiate,upgrade,stop&start这几个生命周期。具体如下图所示:

05-ChainCode生命周期、分类及安装、实例化命令解析
链码的生命周期

1.Packaging | 打包

在区块链中,将链码安装到 Peer 节点,与我们安装普通程序不一样。

Fabric 对链码的安装有严格的验证和安全机制。

安装好的链码,谁有资格实例化?

又该使用什么样的背书策略来调用 ChainCode 呢?

这一切,都需要在安装之前,将它们规定好。我们把这些附加信息+ChainCode 源码统称为 ChainCode 包。

一般而言,ChainCode 包由以下三个部分组成:

  • chaincode 本身,其由ChaincodeDeploymentSpec(Chaincode 部署规范)来定义。ChaincodeDeploymentSpec,以下简称CDS。CDS 是根据代码及一些其他属性(名称,版本等)来定义 chaincode。
  • 一个可选的实例化策略,该策略可被 背书策略 描述。
  • 一组表示 chaincode所有权的签名

打包的过程,就是将这三部分信息打包成一个整体。一般来说,打包 chaincode 有两种方式:

第一种是当你想要让 chaincode 有多个所有者的时候,此时就需要让 chaincode 包被多个所有者签名。这种情况下需要我们创建一个被签名的 chaincode 包(SignedCDS),这个包依次被每个所有者签名。

另一种就比较简单了,让 chaincode 有一个所有者的时候,此时只要被一个人签名即可。

要创建一个签名过的 chaincode 包,请用下面的指令:

peer chaincode package -n mycc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -v 0 -s -S -i "AND('OrgA.admin')" ccpack.out

选项说明:

  • -s:选项创建了一个可被多个所有者签名的包,而非简单地创建一个 CDS。如果使用-s,那么当其他所有者要签名的时候,-S也必须同时使用。否则,该过程将创建一个仅包含实例化策略的签名 chaincode 包(SignedCDS)。
  • -S选项可以使在core.yaml文件中被localMspid相关属性值定义好的 MSP 对包进行签名。该选项是可选的。不过,如果我们创建了一个没有签名的包,那么它就不能被任何其他所有者用signpackage指令进行签名。
  • -i选项也是可选的,它允许我们为 chaincode 指定实例化策略。实例化策略与背书策略格式相同,它指明谁可以实例化 chaincode。

2.signpackage | 签名并打包

一个在创建时就被签名的 chaincode 包可以交给其他所有者进行检查与签名。具体的工作流程支持通道外对 chaincode 包签名。

ChaincodeDeploymentSpec 可以选择被全部所有者签名并创建一个 SignedChaincodeDeploymentSpec(SignedCDS),SignedCDS 包含三个部分:

  • CDS 包含 chaincode 的源码、名称与版本
  • 一个 chaincode 实例化策略,其表示为背书策略
  • chaincode 所有者的列表,由 Endorsement 定义

一个 chaincode 所有者可以对一个之前创建好的带签名的包进行签名,具体使用如下指令:

peer chaincode signpackage ccpack.out signedccpack.out

指令说明:

  • 指令中的ccpack.outsignedccpack.out分别是输入与输出包。
  • signedccpack.out则包含一个用本地 MSP 对包进行的附加签名。

3. install | 安装

install 的过程会将 chaincode 的源码以一种被称 ChaincodeDeploymentSpec(CDS)的规定格式打包,并把它安装在一个将要运行该 chaincode 的 peer 节点上。

在 Fabric 网络中,我们需要在一个 channel 上每一个要运行你 chaincode 的背书节点上安装你的 chaincode。

Chaincode 应该仅仅被安装于 chaincode 所有者的背书节点上,以使该 chaincode 逻辑对整个网络的其他成员保密。其他没有 chaincode 的成员将无权成为 chaincode 影响下的交易的认证节点(endorser)。对于认证节点来说,他们不能执行 chaincode。不过,他们仍可以验证交易并提交到账本上。

下面安装 chaincode:

使用 CLI 安装一个存放在 sacc 目录下的 chaincode 时,命令如下

peer chaincode install -n asset_mgmt -v 1.0 -p sacc

选项说明:

  • -n:name 对链码进行命令
  • -v: version 指定 chaincode 的版本
  • -p: path 指明 chainCode 的路径

在 CLI 内部会为 sacc 创建 SignedChaincodeDeploymentSpec,并将其发送到本地 peer 节点。这些节点会调用 LSCC 上的Install方法。

4. instantiate | 实例化 chaincode

实例化 ChainCode 过程会调用 生命周期系统 chaincode (LSCC)来在一个 channel 上创建并初始化一段 chaincode。实例化过程,会生成对应 Channel 的 Docker 镜像和 Docker 容器。并且在实例化时我们可以指定背书策略。

当然,一个实例化交易的创建者必须符合在 SignedCDS 中 chaincode 的实例化策略,且必须充当 channel 的写入器(这会成为 channel 创建配置的一部分),这对于 channel 的安全至关重要。

使用 CLI 去实例化 名为 mycc 的 chaincode,指令具体如下:

peer chaincode instantiate -n mycc -v 1.0 -c '{"Args":["john","0"]}' -P "OR ('Org1.member','Org2.member')"

选项说明:

  • -n 实例化链码的名称
  • -c –ctor,链码的具体执行参数,为 json 格式
  • -P –Policy 指定实例化策略

5.upgrade | 升级 chaincode

一段 chaincode 可以通过更改它的版本(SignedCDS 的一部分)来随时进行更新。至于 SignedCDS 的其他部分,比如所有者及实例化策略,都是可选的。不过,chaincode 的名称必须一致,否则它会被当做完全不同的另一段 chaincode。

在升级之前,chaincode 的新版本必须安装在需要它的背书节点上。升级是一个类似于实例化交易的交易,它会将新版本的 chaincode 与 channel 绑定。其他与旧版本绑定的 channel 则仍旧运行旧版本的 chaincode。换句话说,升级交易只会一次影响一个提交它的 channel。

6.stop&star | 停止与启动

注意,停止与启动生命周期交易的功能还没实现。不过,你可以通过移除 chaincode 容器以及从每个背书节点删除 SignedCDS 包来停止 chaincode。具体而言,就是删除所有主机或虚拟机上 peer 节点运行于其中的 chaincode 的容器,随后从每个背书节点删除 SignedCDS。

7.chainCode 的状态总结

在上述的过程中,ChainCode 的状态有以下几种。这里做一个小总结:

  • CDS -ChainCodeSpec 包含链码源码,名称,版本等信息
  • SignedCDS-SignedChaincodeDeploymentSpec ,包含 CDS、一个 chaincode 实例化策略,其表示为背书策略、chaincode 所有者的列表,由 Endorsement 定义。

Spec “规范”


4.ChainCode 的种类

在 Fabric 中,链码可以分为两种,系统 chaincode用户 chaincode

1.系统 ChainCode

系统链码则负责 Fabric 节点自身的处理逻辑,包括系统配置、背书、校验等工作。这些处理过程最初通过硬编码(Hard-Coded)的方式固化在系统中。Fabric 通过系统链码的形式来实现,运行在 Peer 主进程内,兼顾了逻辑实现和管理的灵活性,以及通信的性能。

例如:一个系统 chaincode 只能通过 peer 节点的二进制文件升级。同时,系统 chaincode 只能以一组编译好的特定的参数进行注册,且不具有背书策略相关功能。

以下是系统 chaincode 的表格:

05-ChainCode生命周期、分类及安装、实例化命令解析05-ChainCode生命周期、分类及安装、实例化命令解析
Fabric 五大类型系统链码

系统链码目前仅支持 Go 语言,在 Peer 节点启动时会自动完成注册和部署,以进程内逻辑形式跟主进程进行交互。

2.用户 chaincode

用户链码对应用开发者来说十分重要,它提供了基于区块链分布式账本的状态处理逻辑,基于它可以开发出多种复杂的应用。在超级账本 Fabric 项目中,用户可以使用 Go 语言来开发链码,未来还将支持包括 Java、JavaScript 在内的多种高级语言。

用户链码相关的代码都在 core/chaincode 路径下。其中 core/chaincode/shim 包中的代码主要是供链码容器侧调用使用,其他代码主要是 Peer 侧使用。

3.两者的比较

相同点

  • 系统 chaincode用户 chaincode两种的编程模型相同,

不同点

  • 系统 chaincode 运行于 peer 节点内而用户 chaincode 运行在一个隔离的容器中。因此,系统 chaincode 在节点内构建且不遵循上文描述的 chaincode 生命周期。
  • 安装实例化升级这三项操作不适用于系统 chaincode。

5.总结

上面三部分,我们简单介绍了 ChainCode 的基本特性,了解了 ChainCode 在区块链网络中以怎样的形式存在,也清楚了 ChainCode 的生命周期以及 ChainCode 的分类。这一部分,对后续 ChainCode 的开发,是必须要掌握的知识。

参考文献:

HyperLedger-Fabric 中文文档-智能合约操作手册

HyperLedger-Fabric-中文文档-CLI

《区块链原理、设计与应用》-杨保华-9.5 链码的概念与使用

《区块链原理、设计与应用》-杨保华-12.5 用户链码

《区块链原理、设计与应用》-杨保华-12.6 系统链码

 

转自知乎 苏小乐 :https://www.zhihu.com/people/shan-de-ding-zhu/activities


露水湾 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:05-ChainCode生命周期、分类及安装、实例化命令解析
喜欢 (0)
[]
分享 (0)
关于作者:
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址