以下,将通过一个块链网络运营商Noah的眼睛来探索链码。于诺亚的兴趣,我们将重点关注链码生命周期操作;作为块代码在块链网络中的操作生命周期的函数的链式代码的封装,安装,实例化和升级过程。
一、链码生命周期
Hyperledger Fabric API允许与块链网络中的各种节点(对等体,订户和MSP)进行交互,并且还允许在批准的对等节点上进行包代码,安装,实例化和升级链码。Hyperledger Fabric语言特定的SDK提取了Hyperledger Fabric API的细节,以促进应用程序开发,虽然它可以用于管理链码的生命周期。此外,Hyperledger Fabric API可以通过CLI直接访问,我们将在本文档中使用。
我们提供四个命令来管理链码的生命周期:包package
,安装install
,实例化instantiate
和升级upgrade
。在未来的版本中,我们正在考虑添加停止stop和启动start事务以禁用并重新启用链码,而无需实际卸载它。链代码已成功安装并实例化后,链码处于活动状态(正在运行),并可通过调用事务处理事务。链码可以在安装完成后随时升级。
二、包Packing
链码包由3部分组成:
链码,由ChaincodeDeploymentSpec或CDS定义。 CDS根据代码和其他属性(如名称和版本)定义了chaincode包,
可选的实例化策略,可以通过用于认可的相同策略进行语法描述,并在认可政策中描述,
一组签名由实体“拥有”链码。
签名用于以下目的:
建立链码的所有权,允许验证包的内容,以及 以允许检测包篡改。
链码上链码的实例化事务的创建者根据链码的实例化策略进行验证。
1.创建包
包装链码有两种方法。一个是当你想拥有一个链码的多个所有者,因此需要使用多个身份签署的链码包。这个工作流程要求我们最初创建一个签名的链码包(SignedCDS),随后将其连续传递给其他所有者进行签名。更简单的工作流程是在部署仅具有发出安装事务的节点的标识签名的SignedCDS时。
我们将首先处理更复杂的案例。但是,如果您不需要担心多个所有者,您可以跳到下面的“安装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选项。否则,该过程将创建一个SignedCDS,除了CDS之外仅包括实例化策略。
-s选项指示进程使用由core.yaml中的localMspid属性的值标识的MSP对程序包进行签名。
-s选项是可选的。但是,如果没有签名创建包,则不能使用signpackage命令由其他所有者签名。
可选的-i选项允许为链码指定实例化策略。实例化策略具有与认可策略相同的格式,并指定哪些身份可以实例化链码。
在上面的例子中,只有OrgA的管理员可以实例化链码。如果没有提供策略,则使用默认策略,这仅允许对等体的MSP的管理员身份实例化链码。
2.包签名
创建时签署的链码包可以交给其他业主进行检查和签名。该工作流程支持链码包的带外签名。
ChaincodeDeploymentSpec可以由集体所有者可选地签名以创建SignedChaincodeDeploymentSpec(或SignedCDS)。 SignedCDS包含3个元素:
1.CDS包含链码的源代码,名称和版本。
2.链码的实例化政策,表示为认可政策。
3.链码所有者的列表,通过认可来定义。
请注意,当某些渠道上的链码被实例化时,这种认可策略是在带外确定的,以提供适当的MSP主体。如果未指定实例化策略,则默认策略是通道的任何MSP管理员。
每个所有者通过将其与该所有者的身份(例如证书)组合并签署组合结果来批准ChaincodeDeploymentSpec。
链码所有者可以使用以下命令签名先前创建的签名包:
peer chaincode signpackage ccpack.out signedccpack.out
ccpack.out和signedccpack.out分别是输入和输出包。 signedccpack.out包含使用本地MSP签名的包的附加签名。
3.安装链码
将要安装的交易链码源代码打包成一个称为ChaincodeDeploymentSpec(或CDS)的规定格式,并将其安装在将运行该链码的对等节点上。
您必须在将运行您的链码的通道的每个认可对等节点上安装链码。
当安装API只是一个ChaincodeDeploymentSpec,它将默认实例化策略并包含一个空的所有者列表。
链码只能安装在链码的拥有成员的认可对等节点上,以保护链码逻辑与网络上其他成员的机密性。那些没有链码的成员,不能是链码交易的代言人;也就是说,它们不能执行链码。但是,它们仍然可以验证并将交易提交给分类帐。
要安装链码,请将SignedProposal发送到系统链码部分中描述的生命周期系统链码(LSCC)。例如,要使用CLI安装Simple Asset Chaincode简介中描述的sacc示例链码,命令将如下所示:
peer chaincode install -n asset_mgmt -v 1.0 -p sacc
CLI内部为sacc创建SignedChaincodeDeploymentSpec并将其发送到本地对等体,该对等体调用LSCC上的Install方法。-p选项的参数指定链码的路径,该路径必须位于用户的GOPATH的源树中,例如。 $ GOPATH / src目录/ SACC。有关命令选项的完整说明,请参阅CLI部分。
请注意,为了安装在对等体上,SignedProposal的签名必须来自对等体的本地MSP管理员的1。
4、实例化
实例化交易调用生命周期系统链码(LSCC)来创建和初始化通道上的链码。这是一个链码信道绑定过程:链码可以绑定到任何数量的信道,并且在每个信道上单独和独立地操作。换句话说,无论链码可能被安装和实例化了多少其他频道,状态将与交易提交的频道保持隔离。
实例化交易的创建者必须满足SignedCDS中包含的链码的实例化策略,并且还必须是通道上的写入器,它被配置为通道创建的一部分。这对于通道的安全性很重要,以防止流氓实体部署链式代码或欺骗成员来执行未绑定通道上的链式代码。
例如,请记住,默认实例化策略是任何MSP管理员通道,因此链码实例化事务的创建者必须是通道管理员的成员。当交易建议到达代理人时,它会根据实例化策略来验证创建者的签名。在提交到分类帐之前,在事务验证期间再次完成此操作。
实例交易还在该频道上设置了该代码的认可政策。认可政策描述了渠道成员接受的交易结果的认证要求。
例如,使用CLI实例化sacc chaincode并用john和0初始化状态,命令如下所示:
peer chaincode instantiate -n sacc -v 1.0 -c '{"Args":["john","0"]}' -P "OR ('Org1.member','Org2.member')"
注意认可政策(CLI使用抛光符号),这需要Org1或Org2的任何成员的所有交易的认可。也就是说,Org1或Org2必须对sacc执行Invoke的结果进行签名,以使事务生效。
在成功实例化之后,链码在通道上进入活动状态,并准备处理ENDORSER_TRANSACTION类型的任何交易提案。这些交易在到达支持对等体时同时处理。
5.更新
链码可以随时通过更改其版本来升级,这是SignedCDS的一部分。其他部分,如所有者和实例化策略是可选的。然而,链码名称必须相同;否则将被视为完全不同的链码。
在升级之前,新版本的链码必须安装在所需的支持者身上。升级是类似于实例化事务的事务,它将新版本的链码绑定到通道。绑定到旧版本的链码的其他渠道仍然与旧版本一起运行。换句话说,升级事务只会影响一个通道,即交易提交的通道。
请注意,由于链码的多个版本可能同时处于活动状态,所以升级过程不会自动删除旧版本,因此用户必须暂时进行管理。
与实例化事务有一个微妙的区别:根据当前链码实例化策略检查升级事务,而不是新策略(如果指定)。这是为了确保只有当前实例化策略中指定的现有成员可以升级链码。
请注意,在升级期间,调用chaincode Init函数来执行任何数据相关更新或重新初始化它,因此必须注意在升级链码时避免复位状态。
6.开始和停止
请注意,停止和启动生命周期交易尚未实施。但是,您可以通过从每个支持者中删除chaincode容器和SignedCDS包来手动停止链码。这是通过删除每个承载对等节点运行的每个主机或虚拟机上的链码的容器,然后从每个支持的对等节点删除SignedCDS:
docker rm -f <container id> rm /var/hyperledger/production/chaincodes/<ccname>:<ccversion>
停止在工作流中以受控的方式进行升级将是有用的,其中在发布升级之前可以在所有对等体上的通道上停止链码。
7.Cli
我们正在评估为Hyperledger Fabric对等体二进制文件分发平台特定二进制文件的需求。暂时的,你可以直接在运行中的docker容器内调用命令。
要查看当前可用的CLI命令,请从正在运行的fabric-peer Docker容器中执行以下命令:
docker run -it hyperledger/fabric-peer bash
# peer chaincode --help
Usage: peer chaincode [command] Available Commands: install Package the specified chaincode into a deployment spec and save it on the peer's path. instantiate Deploy the specified chaincode to the network. invoke Invoke the specified chaincode. package Package the specified chaincode into a deployment spec. query Query using the specified chaincode. signpackage Sign the specified chaincode package upgrade Upgrade chaincode. Flags: --cafile string Path to file containing PEM-encoded trusted certificate(s) for the ordering endpoint -C, --chainID string The chain on which this command should be executed (default "testchainid") -c, --ctor string Constructor message for the chaincode in JSON format (default "{}") -E, --escc string The name of the endorsement system chaincode to be used for this chaincode -l, --lang string Language the chaincode is written in (default "golang") -n, --name string Name of the chaincode -o, --orderer string Ordering service endpoint -p, --path string Path to chaincode -P, --policy string The endorsement policy associated to this chaincode -t, --tid string Name of a custom ID generation algorithm (hashing and decoding) e.g. sha256base64 --tls Use TLS when communicating with the orderer endpoint -u, --username string Username for chaincode operations when security is enabled -v, --version string Version of the chaincode specified in install/instantiate/upgrade commands -V, --vscc string The name of the verification system chaincode to be used for this chaincode Global Flags: --logging-level string Default logging level and overrides, see core.yaml for full syntax --test.coverprofile string Done (default "coverage.cov") Use "peer chaincode [command] --help" for more information about a command.
为了方便在脚本化应用程序中的使用,在命令失败的情况下,对等体命令总是生成一个非零返回码。
peer chaincode install -n mycc -v 0 -p path/to/my/chaincode/v0 peer chaincode instantiate -n mycc -v 0 -c '{"Args":["a", "b", "c"]} -C mychannel peer chaincode install -n mycc -v 1 -p path/to/my/chaincode/v1 peer chaincode upgrade -n mycc -v 1 -c '{"Args":["d", "e", "f"]} -C mychannel peer chaincode query -C mychannel -n mycc -c '{"Args":["query","e"]}' peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}'
三、系统链码
系统链码具有相同的编程模型,除了它在对等体进程中运行,而不是象一般链接码在孤立的容器中运行。因此,系统链码内置于对等可执行文件中,并不遵循上述相同的生命周期。特别是安装,实例化和升级不适用于系统链码。
系统链码的目的是在对等和链码之间实现快捷的gRPC通信成本,并且权衡管理的灵活性。例如,系统链码只能用对等体二进制升级。它还必须使用固定的一组参数进行注册,并且不具有认可政策或认可政策功能。
系统链码在Hyperledger Fabric中用于实现多个系统行为,以便系统集成商可以根据需要对其进行替换或修改。
当前系统链码列表::
1.LSCC生命周期系统链码【 Lifecycle system chaincode】处理上述生命周期请求。
2.CSCC配置系统链码【Configuration system chaincode】处理对端的通道配置。
3.QSCC查询系统链码【Query system chaincode】提供分类帐查询API,例如获取块和事务。
4.ESCC认可系统链码【Endorsement system chaincode 】通过签署交易建议回复来处理认可。
5.VSCC验证系统链码【Validation system chaincode】处理事务验证,包括检查认可策略和多路调用并发控制。
修改或更换这些系统链式代码时,特别是LSCC,ESCC和VSCC必须小心,因为它们在主事务执行路径中。值得注意的是,由于VSCC在将其提交给分类帐之前对块进行验证,所以通道中的所有对等体都必须计算相同的验证以避免分类分歧(非确定性)。如果VSCC被修改或更换,则需要特别小心。