黎跃春
孔壹学院、ChainDesk创始人兼CEO
如果您有任何关于区块链的问题,可以加入区块链技术交流QQ群729666975(进群无需添加验证信息,直接点击下一步,等待管理员通过即可),我们会为您一一解答。
从零到壹学习Hyperledger Fabric为一个系列,一共15讲,包括搭建Hyperledger Fabric环境、Hyperledger Fabric Samples安装、建立第一个网络、手动配置网络实现及测试Chaincode、编写第一个应用等。今天我们将为大家介绍从零到壹学习Hyperledger Fabric第十三讲:node测试。话不多说,马上开启我们的Hyperledger Fabric学习之旅。
课程学习,添加莉莉微信(kongyixueyuan)获取。
孔壹学院
简介
数字货币曾是区块链技术的唯一应用场景
对智能合约的支持突破了场景限制, 丰富了区块链应用的适用范围, 可以支持多行业、大规模的商业应用
区块链应用
区块链应用: 一般由若干部署在区块链网络中的智能合约, 以及调用这些智能合约的应用程序组成
用户专注于与业务本身相关的应用程序
智能合约则封装了与区块链账本直接交互的相关过程, 被应用程序调用
智能合约开发
智能合约本质上是为了对上层业务逻辑进行支持且直接与账本结构打交道, 处于核心位置.
所以设计得当可以简化上层应用开发的过程
应用程序开发
应用程序通过调用智能合约提供的方法接口实现业务逻辑, 可以使用JavaScript、Python、Go、Java等主流语言进行开发
链码的原理
链码延伸自智能合约的概念, 支持使用主流高级编程语言实现
区块链网络中的成员商定业务逻辑后, 可将业务逻辑编程到链码中, 所有人遵守合约执行
链码会创建一些状态(state)并写入账本中。状态带有绑定到链码的命名空间,仅限于创建他的链码使用,不能被其他链码直接访问。不过,在合适的范围内,一个链码也可以调用另一个链码,间接访问其状态
链码在Fabric节点上的隔离沙盒(目前为Docker容器)中运行, 并通过gRPC协议与节点进行交互
调用链码
读写账本
返回响应
......
Fabric中支持多种语言实现链码,包括Golang、JavaScript、Java等
基本工作原理
首先用户通过客户端向Fabric的背书节点发出调用链码的交易提案
节点对交易提案进行包括ACL权限检查在内的各种检验, 通过后则创建模拟执行这一交易的环境
之后, 节点和链码容器之间通过gRPC消息来交互, 模拟执行交易并给出背书结论
当链码的代码逻辑需要读写账本时,通过shim层发送相应操作类型给节点, 节点本地操作账本后返回响应消息
客户端收到足够的背书节点的支持后, 便可以将这笔交易发送给排序节点进行排序, 并最终写入区块链
链码接口与结构
依赖包
链码实现需要引入如下依赖包
"github.com/hyperledger/fabric/core/chaincode/shim"
shim包提供了链码与账本交互的中间层
链码通过shim.ChaincodeStub提供的方法来读取和修改账本状态
"github.com/hyperledger/fabric/protos/peer"
链码接口
每个链码都需要实现chaincode接口:
Init与Invoke方法
编写链码, 关键是实现Init与Invoke两个方法
Init方法在链码部署或升级时被调用, 完成初始化工作
对数据进行操作时, Invoke方法被调用, 因此响应调用或查询的业务逻辑都需要在此方法中实现
必要结构
一个链码的必要结构如下
链码API
账本状态交互API
链码需要将数据记录在分布式账本中.需要记录的数据称为状态, 以K-V对的形式存储
账本状态交互API可以对账本状态进行操作
GetState(key string) ([]byte, error) 通过Key来返回数组的特定值
PutState(key string, value []byte) error账本中写入特定的键和值
DelState(key string) error从账本中移除指定的键和值
GetStateByRange(startKey, endKey string) (StateQueryIteratorInterface, error)根据指定的范围内的健值
GetHistoryForKey(key string) (HistoryQueryIteratorInterface, error)返回指定健的所有历史值
GetQueryResult(query string) (StateQueryIteratorInterface, error)对(支持富查询功能的)状态数据库进行富查询
交易信息相关API
GetTxID() string返回交易提案中指定的交易ID
GetTxTimestamp() (*timestamp.Timestamp, error)返回交易创建的时间戳,这个时间戳是peer收到交易的当前时间
GetBinding() ([]byte, error)返回交易的binding信息
GetSignedProposal() (*pb.SignedProposal, error)返回与交易提案相关的所有数据
GetCreator() ([]byte, error)返回该交易的提交者的身份信息
GetTransient() (map[string][]byte, error)返回交易中不会被写至账本中的一些临时信息
参数API
GetArgs() [][]byte返回调用链码时交易提案中指定的参数
GetArgsSlice() ([]byte, error)返回调用链码时交易提案中指定的参数
GetFunctionAndParameters() (function string, params []string)返回调用链码时交易提案中指定的被调用的函数名称及其参数
GetStringArgs() []string返回调用链码时晩中指定的参数
领取专属 10元无门槛券
私享最新 技术干货