简介
本文章出自NM1024.com:http://nm1024.com/436.html
此篇文章重点介绍Nodejs-SDK中部分常用的方法,为了便于理解方法的使用,故按照不同功能划分并释义;其中可能在一个功能中涉及到了很多个类方法的使用。
创建、更新Channel通道
client.extractChannelConfig(config_envelope)
从configtxgen工具生成的ConfigEnvelope对象中提取protobuf结构的ConfigUpdate对象。
后续可以使用signChannelConfig()方法对extractChannelConfig()返回的对象进行签名。收集完所有签名后,可以在createChannel()或updateChannel()上使用ConfigUpdate对象和签名。
client.signChannelConfig(config)
可以将通道配置更新发送到要处理的orderer。orderer强制执行channel创建或更新策略,仅在请求中收到自参与组织的足够签名时才进行更新。 通常,通道创建或更新请求必须由参与组织的ADMIN主体签名,尽管可以自定义此策略。
此方法使用客户端实例的当前签名标识来签署传入的配置字节,并返回签名后的protobuf消息发送到orderer。
client.createChannel(request)
发送消息到orderer开始构建新channel。channel通常有多个参与组织。要创建新channel,其中一个参与组织应调用此方法将创建请求并提交给orderer服务。
orderer成功创建channel后,下一步是通过将channel配置发送到每个peer节点,让每个组织的perr节点加入通道。该步骤通过调用joinChannel()方法完成。
这里的参数request中txId字段需要使用client.newTransactionID()生成。
client.updateChannel(request)
发送消息到orderer来更新现有channel。在orderer成功处理了channel更新后,orderer会切断包含新channel配置的新区块,并将其传递给channel中的所有参与的peer。
这里的参数request中txId字段需要使用client.newTransactionID()生成。
安装、更新Chaincode
client.installChaincode(request, timeout)
在fabric v1.0中,必须先调用此方法安装之后再次使用sendInstantiateProposal()实例化chaincode,然后才能调用它来处理事务。
Chaincode安装只是将新的chaincode源码和依赖项上传到peer。只允许ADMIN身份执行此操作。
channel.sendInstantiateProposal(request, timeout)
将chaincode实例化提案发送给一个或多个peer。chaincode必须在channel上实例化才能使用。首先必须通过调用client.installChaincode()将chaincode安装在预期运行此chaincode的peer上。
实例化链代码是一种完整的交易操作,这意味着它的提案必须被认可,然后将许可发送给orderer进行排序和验证。当事务最终被提交到peer对应的channel时,则认为chaincode被激活并且peer准备好接受处理事务的请求。
channel.sendUpgradeProposal(request, timeout)
向一个或多个peer发送chaincode升级提议。升级chaincide类似于实例化chaincode的步骤。必须首先将新chaincode安装在预期运行的peer上。
与实例化链代码类似,升级链代码也是完整的事务操作。
执行Chaincode
执行Chaincode有两种模式,一种为单一流程仅限查询使用;另一种为完整事务流,在更新、插入等涉及到修改数据的都需要使用此模式。
channel.queryByChaincode(request, useAdmin)
将请求发送给一个或多个指定的peer,并由其对应的chaincode执行返回结果。在fabric v1.0中,peer处理调用事务chaincode的请求与调用chaincode进行查询的方式没有区别;所有请求都将呈现给目标chaincode的“invoke”方法,必须在chaincode中实现该方法并,还必须用字节数组格式返回结果,并且调用者必须能够解码这些结果。
channel.sendTransactionProposal(request, timeout)
将交易提议发送给一个或多个peer。在安装并实例化chaincode之后,它就可以获得认可提议并参与事务处理。chaincode事务以一个提议发送,该提议被发送给对应的peer,该提议执行目标chaincode并决定是否应该批准该提议。在批准了该提议之后,客户端需将返回的结果提交至sendTransaction()做进一步处理。
ChannelEventHub事件中心
官方文档中移除了EventHub的相关说明,但新维护了ChannelEventHub;两个类实现的功能是相似的,可以使用ChannelEventHub完全替代。事件中心的主要功能如下:
连接一个节点的事件流
监听一个区块事件
监听交易时间并且确定交易是否成功提交进行标记
监听由链码产生的自定义事件
channel.newChannelEventHub(channel, peer)
构造一个ChannelEventHub对象
registerBlockEvent(onEvent, onError, options)
注册侦听器以接收目标peer所属的所有channel中的所有块事件。在每个块到达时调用侦听器的“onEvent”回调。如果期望目标peer参与多个channel,则必须在监听器的实现中并区分不同channel的块。
在异步运行的连接建立中可能会发生错误。最佳做法是提供一个“onError”回调,以便在此ChannelEventHub出现问题时得到通知。(所有的注册事件均可能发生。)
registerChaincodeEvent(ccid, eventname, onEvent, onError, options)
注册侦听器以接收chaincode事件。
registerTxEvent(txid, onEvent, onError, options)
注册回调函数,以便在给定id的事务已提交到块中时接收通知。(在完整事务流中需要使用到此功能)
connect(full_block)
建立与peer事件的连接。将以异步方式建立连接。如果连接无法建立,将通过registerXXXEvent()方法的错误回调通知应用程序。在调用connect()之前,必须通过调用registerBlockEvent,registerTxEvent或registerChaincodeEvent方法中的任何一个来注册至少一个带有错误回调的事件侦听器。
unregisterXXXEvent
注销由registerXXXEvent()方法生成的事件侦听器。
各类查询功能
信息查询在任何项目都非常常用,这里列举了fabric中部分常用的查询功能:
查询channel height
通过区块数字查询,通过区块hash值查询
查询一个节点所在的所有通道
查询节点中安装的所有链码
查询通道中的所有实例化链码
通过事务ID查询
查询通道的配置数据
channel.queryInfo(target, useAdmin)
查询有关区块链的高度、当前块哈希等信息。
channel.queryBlock(blockNumber, target, useAdmin, skipDecode)
可以使用区块编号查询到当前哈希、上一个块的哈希、当前块中所包含的信息等。
channel.queryBlockByHash(blockHash, target, useAdmin, skipDecode)
功能同channel.queryBlock(blockNumber, target, useAdmin, skipDecode),查询条件为区块哈希值。
channel.queryChannels(peer, useAdmin)
查询指定的peer加入的所有channel。
client.queryInstalledChaincodes(peer, useAdmin)
查询指定peer上已安装的chaincode。
channel.queryInstantiatedChaincodes(target, useAdmin)
查询指定peer上已实例化的chaincode。
channel.queryTransaction(tx_id, target, useAdmin, skipDecode)
在指定的peer上使用txid查询有关此txid交易的信息。
channel.getChannelConfig(target, timeout)
查询当前channelConfig。
用户与权限等
client.createUser(opts)
返回具有基于私钥和相应x509证书的签名标识的User对象。这允许应用程序使用预先存在的加密材料(私钥和证书)来构建具有签名功能的用户对象,此作为使用fabric-ca动态注册用户的替代方法。
请注意,成功创建新用户对象后,它将作为当前userContext设置为客户端实例。
client.getUserContext(name, checkPersistence)
按给定名称返回用户。这可以是同步调用或异步调用,具体取决于参数“checkPersistent”是否为true。如果true,该方法是异步的并返回Promise,否则它是同步的。SDK将注册用户保存在存储中,该存储可由应用程序的授权用户访问(身份验证由SDK外部的应用程序完成)。此函数尝试从本地存储(通过KeyValueStore接口)按名称加载用户。加载的用户对象必须表示具有由受信任CA(例如CA服务器)签名的有效注册证书的注册用户。
client.setUserContext(user, skipPersistence)
将User类的实例设置为此客户端实例的上下文中。此用户的签名标识(私钥及其对应的证书)将用于使用fabric后端对所有请求进行签名。
在设置用户上下文时,如果已在客户端实例上设置StateStore,则SDK会将对象保存在持久性缓存中。如果未设置StateStore,则不会建立此缓存,并且应用程序负责在应用程序崩溃后的恢复时再次设置用户上下文。
Fabric-CA-Client
在官方文档中原链接https://fabric-sdk-node.github.io/FabricCAServices.html被修改并重构为https://fabric-sdk-node.github.io/CertificateAuthority.html,所以部分流传的文章内链接失效。原文是这么说的:
The CertificateAuthority class represents a Certificate Authority configuration as defined in a Connection Profile. This class will wrapper a FabricCAClientImpl fabric-ca-client implementation as a FabricCAServices instance when this class is returned from the Client#getCertificateAuthority method. This class has all the same methods as the FabricCAServices so that this class may be used directly or use this class’s CertificateAuthority#getFabricCAServices method to get the actual FabricCAServices instance.
主体功能、方法依然是不变的:
注册新用户
登记用户同时获得由Fabric CA签署的注册证书
通过注册ID废除已有用户或废除特定证书
自定义的持久储存
提议(提案)+交易的完整事务流
先提议,后交易;这是fabric中常见的一种处理业务的流程。此模式的特点是先使用对应的方法提交一个Proposal,得到返回信息后使用channel.sendTransaction()发送此交易并等待最终结果。
以下必须使用此模式:
sendInstantiateProposal()
sendUpgradeProposal()
sendTransactionProposal()
channel.sendTransaction(request, timeout)
将包含交易提案认可的提案回复发送给orderer进行进一步处理。这是事务生命周期的第二阶段。orderer将在此channel的上下文中全局订阅消息,并将结果块交付给提交的peer,以便根据chaincode的认证方式进行验证。当提交的peer成功验证事务时,它将在块内将事务标记为有效。在块中的所有事务都已经过验证并被标记为有效或无效(带有原因码)之后,该块将被附加(提交)区块链账本上。
在使用此方法之前需要使用事件中心注册一个监听registerTxEvent(txid, onEvent, onError, options),当txid对应的事务提交到区块中时触发监听事件,之后确认无误后再使用channel.sendTransaction(request, timeout)提交请求。
公用、工具类方法
client.setStateStore(keyValueStore)
设置可选的存储以保持部分需要缓存存储的数据。状态存储必须实现模块:api.KeyValueStore接口。
SDK支持持久保存User对象,以便不必重复传递重量级对象(如证书和私钥)。开箱即用的SDK提供了基于文件的实现,以及基于CouchDB的实现,它也支持Cloudant。应用程序可以提供替代实现。
一般会结合/fabric-client/lib/utils.js中的newKeyValueStore()使用。
client.newTransactionID(admin)
返回一个新的TransactionID对象。此方法要求为客户端实例分配userContext。
参数admin如果为true,则应根据admin证书构建此transactionID。默认为基于userContext的非admin生成TransactionID。