07.Fabric的智能合约详解

导语

智能合约是区块链中一个非常重要的概念和组成部分。在Fabric中内成为Chaincode,中文翻译为链码。涉及到链码地方都是 Chaincode.

7.1 Chaincode 初探

Fabric中的Chaincode包含了一个Chaincode代码和Chaincode管理命令这两部分。

  • Chaincode 代码是业务的承载体,负责具体的业务逻辑
  • Chaincode 管理命令负责 Chaincode的部署,安装,维护等工作

1.Chaincode代码

Fabric的Chaincode是一段运行在容器中的程序。Chaincode是客户端程序和Fabric之间的桥梁。

通过Chaincode客户端程序可以发起交易,查询交易。

Chaincode是运行在Dokcer容器中,因此相对来说安全。

目前支持 java,node,go,go是最稳定的。其他还在完善。

2.Chaincode的管理命令

Chaincode管理命令主要用来对Chaincode进行安装,实例化,调用,打包,签名操作。

Chaincode命令包含在Peer模块中,是peer模块中一个子命令, 该子命令的名称 是chaincode.该子命令是 peer chaincode

7.2 快速编写和运行一个Chaincode

1.创建一个Chaincode代码的目录

首先创建一个目录存放Chaincode的代码。建议放在$GOPATH指定的路径中。
s

2.创建 Chaincode源代码文件并且编写源代码

在创建域代码文件的命令如下:
在这里插入图片描述
07.Fabric的智能合约详解_第1张图片07.Fabric的智能合约详解_第2张图片在这里插入图片描述07.Fabric的智能合约详解_第3张图片07.Fabric的智能合约详解_第4张图片在这里插入图片描述07.Fabric的智能合约详解_第5张图片

  • 第一步 部署
  • 在这里插入图片描述
  • 第二步 实例化
  • 在这里插入图片描述
  • 第三步 调用
  • 在这里插入图片描述
    如果 没有出现错误,那我们就完完成了一个最简单的chaincode的代码编写部署,发布,调用的过程。

7.3 Golang版本的Chaincode的代码结构

真的勇士敢于直面惨淡的人生,敢于正视淋漓的鲜血

7.3.1 Chaincode源代码的基本结构
1.包名
  • 一个chaincode通常是一个 Goalng源文件,包名必须是main
  • package main
2.引入包

Chaincode需要引入一个写Fabric提供的一些系统包,这些系统提供了Chaincode和Fabric进行通信的接口。
232
在引入包中, shim提供了Fabric系统提供的上下文环境,包含了Chaincode和Fabic交互的接口。在Chaincode中,执行赋值,查询,等功能都是需要通过shim.

3.定义结构体并实现

每个chaincode必须需要定义一个结构体,结构体的名称可以是任意符合Golang命名规范的字符串。
在这里323图片描述

chaincode结构体是chaincode的主体结构。chaincode结构体需要实现Fabric提供的接口 peer,其中必须实现的两个方法是:
22323

4.Chaincode的init方法

Init方法是系统初始化方法,当执行命令 peer chaincode instantiate实例化chaincode的时候回调用该方法,同时命令中-c选项后面内容会作为参数传入Init方法中。实例化chaincode实例化命令:

在这里插入图片描述

上面命令传入4个参数。注意命令中Args后面一共5个参数,其中一个参数init是固定值,后面 的才是参数。

参数是没有限制的。 可以采用json格式传递

获取传入参数:
在这里插入图片描述

4.Invoke方法

Invoke 方法的主要作用是写人数据 ,比如发起交易等。

在执行命令peer chaincode invoke 的时候系统会调用该方法, 同时会把命令中-c中参数传入方法中。

在这里插入图片描述

传入三个参数, 注意Args后面数据中的第一个值 invoke 是默认的固定参数。

7.3.2 shim 包的核心方法

shim 主要负责和客户端进行通信。

1.Success

Success 方法负责将正确的消息返回给调用Chaincode的客户端。
07.Fabric的智能合约详解_第6张图片

2.Error

Error方法将错误的信息返回给调用Chaincode的客户端。

07.Fabric的智能合约详解_第7张图片

在这里插入图片描述

3.LogLevel

LogLevel方法负责修改Chaincode中运行日志的级别。
07.Fabric的智能合约详解_第8张图片

7.3.3 ChaincodeStublnte face 接口中的核心方法

在shim包中有个一个接口ChaincodeStublnte 。在Invoke方法和Query方法中该接口作为参数传入方法中。

ChaincodeStublnte 提供了一组方法。

  • 系统管理
  • 存储管理
  • 交易管理
  • 调用外部chaincode

07.Fabric的智能合约详解_第9张图片

1. ChaincodeStublnterface 接口的系统相关方法
  • GetFunctionAndParameters:该方法负责接收调用Chaincode的客户端传递过来的参数。

07.Fabric的智能合约详解_第10张图片

一个命令来测试GetFunctionAndParameters方法是怎样接收客户端传递过来的参数。
在这里插入图片描述

2.ChaincodeStubinterface) 接口的存储管理相关方法
    1. PutState :负责把客户端传递过来的数据保存到 Fabric中。
      07.Fabric的智能合约详解_第11张图片
    1. GetState:负责从Fabric中取出数据。然后把这些数据交给Chaincode处理。
      07.Fabric的智能合约详解_第12张图片
    1. GetStateByRange: 根据Key的范围来查询相关的数据。
      07.Fabric的智能合约详解_第13张图片

07.Fabric的智能合约详解_第14张图片

    1. GetHistoryForKey:负责查询某个键的历史记录。

07.Fabric的智能合约详解_第15张图片

07.Fabric的智能合约详解_第16张图片

    1. DelState: 用来删除一个Key。
      07.Fabric的智能合约详解_第17张图片
    1. CreateCompositeKey:负责创建一个组合键。
      07.Fabric的智能合约详解_第18张图片
    1. GetState rPartialCompositeKey:用来查询复合键的值。

07.Fabric的智能合约详解_第19张图片

07.Fabric的智能合约详解_第20张图片

    1. SplitCompositeKey:用来拆分复合键的属性。
      07.Fabric的智能合约详解_第21张图片
3. ChaincodeStublnterface 接口中交易管理相关方法
    1. GetTxTimestamp :负责获取当前客户端发送的交易时间戳。

07.Fabric的智能合约详解_第22张图片

07.Fabric的智能合约详解_第23张图片

4. 调用其他Chaincode的方法
    1. InvokeChaincode:这个接口可以调用其他Chaincode。

07.Fabric的智能合约详解_第24张图片

7.4 Chaincode的相关操作命令和选项

Chaincode是通过peer模块的Chaincode子命令来完成相关部署的工作。执行命令 peer chain-help:
07.Fabric的智能合约详解_第25张图片

  • Chaincode命令的公用选项

    • cafile:PEM格式证书的位置
    • o,orderer:orderer服务器的访问地址
    • tls:使用orderer的TLS证书的位置
    • transient :JSON参数的编码映射
    1. Chaincode 命令的子命令 :数可以是配置文件也可以是环境变量,所以采用环境变量
    • c,------ctor------JSON格式的构造参数,默认是{}
    • l,------lang------编写的语言,默认是golang
    • n, ------name--------Chaincode的名字
    • p, ------path -------Chaincode源代码的路径
    • v,------version--------当前的操作Chaincode的版本。

在这里插入图片描述

instal命令成功后,会在peer模块的数据文件中生成一个-n参数和一个-v参数组成的文件。

在该路径下面会发现一个名为:qlkszzncc.1.1的类似的文件。这个文件就是 Chaincode打包之后的文件。

    1. instantiate:可以对已经执行过得instanll命令的Chaincode进行实例化。

命名执行完成之后会启动Chain运行的Docker镜像,同时还会对Chaincode进行初始化。
- C -----channelID-----当前命命令运行的通道。默认是 testchainid
- c -----ctor-----JSON格式的构造参数。默认值是{}
- E -----escc -----应用于当前Chaincode的系统背书Chaincode的名字
- l -----lang-----编写Chaincode的变成语言,默认值是Golang
- n-----name-----Chaincode的名称
- P-----policy-----当前的Chaincode的背书策略
- v-----version-----当前操作的Chaincode的版本,
- V-----vscc-----当前Chaincode调用的验证系统Chaincode的名字
在这里插入图片描述

    1. invoke: invoke命令用来调用chaincode
    • C-----channelID------当前命令运行的通道 默认是testchainid
    • c------ctor-----JSON格式的构造参数, 默认值是{}
    • n-----name-----Chaincode的名字

在这里插入图片描述

    1. list:查询已经安装好的Chaincode.
  • C-----channelID-----当前命令运行的通道。默认值是 testchainid
    • installed------获取当前Peer节点可以被install的chaincode
    • instantiated-----获取当前Channel中已经被instantiated的chaincode
      在这里插入图片描述
    1. package :将 Chaincode打包
    • s-----cc-package:对打包后的Chaincode 进行签名
    • c ------ctor------JSON格式的构造参数,默认值是{}
    • i------instantiate-policy ------Chaincode的权限
    • l------ lang------编写的Chaincode的变成语言,默认值是golang
    • n------name------Chaincode的名称
    • p------path------Chaincode源代码的路径
    • S------sign-----对打包的文件用本地MSP配置文件中localmspId指定的值进行签名
    • v------version ------当前操作的 Chaincode的版本。
      在这里插入图片描述
    1. query:执行Chaincode代码中的query方法。
    • C------channelID,当前命令运行的通道,默认值是 testchainid
    • c------ctor------JSON格式的构造参数,默认值是{}
    • x-----hex------是否对输出的内容进行编码处理
    • n------name------Chaincode的名字
    • r------raw------是否输入二进制内容
    • t------tid------ 指定当前查询的编号

在这里插入图片描述

    1. signpackage:对已经打好包的 Chaincode进行签字
      在这里插入图片描述
    1. upgrade:更新已经存在的Chaincode
    • C------channelID------当前命令运行的通道,默认值是testchainid
    • c-----ctor JSON格式的构造参数,默认值是{}
    • E-----escc------应用于当前Chaincode的系统背书Chaincode的名字
    • l------lang------编写Chaincode的编程语言。 默认值是 golang
    • n------name----- Chaincode的名字
    • p------path------Chaincode源代码的路径
    • P-----policy------当前Chaincode的背书策略
    • v-----version------当前的操作Chaincode的版本
    • V------vscc------当前 Chaincode调用的验证系统Chaincode名称
  • 在这里插入图片描述

7.4 如何通过 Chaincode进行交易的endorse

区块链最重要的一个特点是:去中心化。所有参与者集体维护公共账本。

Fabaric 中对数据参与方对数据的确认是真实通过Chaincode来进行的。

在Fabric中有一个非常重要的概念成为Endorsement中文名为背书。

什么是背书呢?

背书就是仪表交易被确认的过程。大概意思就是交易你必须背会一本书才能操作。

背书策略被用来指示对相关的参与方如何对交易进行确认。当一个节点接收到一个交易请求的时候,会调用vscc系统(系统Chaincode,专门负责处理背书相关的操作)与交易的Chaincode共同来验证交易的合法性。在vscc和交易的 Chaincode共同对交易的确认中,通常会做一下的校验。

  • 所有的背书是否有效
  • 参与背书的数量是否满足要求
  • 所有背书参与方是否满足要求

背书策略是第二和第三的一种方式。

背书策略的设置是通过Chaincode部署时instantiate命令中的-p参数来设置的。

在这里插入图片描述

上面的命令是对Chaincode进行实例化的操作。我们提取-p后面的参数:

在这里插入图片描述

这个参数包说明是当前Chaincode发起的交易,需要组织编号为 Org1MSP的组织编号为Org2MSP的组织中的任何一个用户共同参与交易的确认并且同意。这样交易才能生效并且记录到 区块链中。

通过上述背书策略的示例我们可以知道背书策略是通过一定的关键字和系统的属性组成的。

背书拆解:

  • and 参与背书者之间的关系,and表示所有参与方的任何一方参与背书即可完成交易的确认。还可以使用OR,如果使用OR表示参与方的任何一方参与背书即可完成交易的确认。

  • OrglMSP.m mber 这是表示参与背书的组织和组织中参与背书的用户。Org1MSP表示组织的编号。这个值是怎么来的呢
    在cryptoge模块中,给模块根据配置文件生成系统的配置和账号信息。在cryptogen的配置文件有一个节点 Organizations-ID,该节点的值就是该组织的编号。也是在配置背书策略时需要使用到的组织的额编号。member泛指组织内的任何一个用户,淡然也可以是组织某个具体的用户

背书的而编写规则

  • 背书规则示例一
    -在这里插入图片描述
    按照背书规则一进行背书交易,必须经过组织中的用户共同验证交易才能生效
    在这里插入图片描述

按照背书规则而进行背书交易,只需要经过一个组织中的任何一个成员验证 就可以生效

  • 背书规则三

在这里插入图片描述

按照第三种规则进行别墅交易的方法有两个让交易生效。

  1. 组织1 中的某个用户交易进行验证
  2. 组织2和组织3 中的成员共同对交易进行验证

还有一点需要注意,就是背书规则只是针对Chain中写入数据的操作进行校验,对于查询类的操作不需要背书。

在这里插入图片描述

Fabric中的背书发生在客户端。需要进行相关的代码的编写才能完成整个背书的操作。

你可能感兴趣的:(07.Fabric的智能合约详解)