热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

HyperledgerFabric1.2ChaincodeOperator解读和测试(二)

本文接上一节是测试部分搭建一个模拟测试环境作者将fabricrelease1.2工程中的example-e2e进行了改造来进行本次实验:(1࿰

本文接上一节是测试部分

 

搭建一个模拟测试环境

作者将fabric release1.2工程中的 example-e2e进行了改造来进行本次实验:

(1)首先我们将examples/e2e_cli/scripts/script.sh中的安装智能合约部分注释掉,或者从此处下载替换原有的脚本

(2)然后再写一个用于安装signcd的脚本 script_chaincode.sh ,放在examples/e2e_cli/scripts/ 目录下面

(3)启动测试网络:

  cd examples/e2e_cli/

  bash  network_setup.sh up

  ps: 注意,要保证当前docker image中fabric相关的镜像里lastest版本是1.2.0,否则可能以其他版本的镜像启动,导致执行无法成功

(3)执行以下命令进入cli容器

  docker exec -it cli bash


整个网络的组织架构:

OrgOrdererOrg1peer:Peer0 : peer0.org1Peer1 : Peer1.org1User:Org1Msp.adminOrg2peer:Peer2: peer0.org2Peer3: peer1.org2User:Org2Msp.admin

如果以上四步都没有报错说明环境正常。


测试场景

(1)缺省策略测试,即不指定实例化策略

预期结果:任意一个Org Admin都能实例化。

<1.1>无签名

setup0: 启动本地测试环境

cd $GOPATH/github.com/hyperledger/fabric/examples/e2e_cli

bash network_setup.sh restart

#等服务完全启动后再进入cli容器内

docker exec -it cli bash

ps:如果服务已经启动过了就无需再启动了

ps1&#xff1a;以下几步都是在cli容器内执行的

 

setup1: Org1 admin chaincode 打包

ORG_NUM&#61;1 PEER_NUM&#61;0 bash ./scripts/script_chaincode.sh chaincode package -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/example02/cmd -s ccpack.out

ps: 我们此时没有调用 -i 指令去指定背书策略&#xff0c;-S 没有指定所以没有owner签名。


setup2: Org2 admin 去向Peer3安装智能合约并实例化

ORG_NUM&#61;2 PEER_NUM&#61;3 bash ./scripts/script_chaincode.sh chaincode install signedccpack.outORG_NUM&#61;2 PEER_NUM&#61;3 bash ./scripts/script_chaincode.sh chaincode instantiate -C mychannel -n mycc -v 1.0 -c &#39;{"Args":["init","a","100","b","200"]}&#39; -P "OR(&#39;Org1MSP.peer&#39;,&#39;Org2MSP.peer&#39;)"

此时会抛出以下错误&#xff1a;

Error: could not assemble transaction, err Proposal response was not successful, error code 500, msg instantiation policy violation: signature set did not satisfy policy

而这不符合我们的预期;


setup3: Org1 admin 去向Peer3发送实例化请求

执行如下命令&#xff1a;

ORG_NUM&#61;1 PEER_NUM&#61;3 bash ./scripts/script_chaincode.sh chaincode instantiate -C mychannel -n mycc -v 1.0 -c &#39;{"Args":["init","a","100","b","200"]}&#39; -P "OR(&#39;Org1MSP.peer&#39;,&#39;Org2MSP.peer&#39;)"

查看本地docker容器

docker ps此时我们能看到新创建了一个容器&#xff1a;
dev
-peer1.org2.example.com-mycc-1.0-26c2ef32838554aac4f7ad6f100aca865e87959c9a126e86d764c8d01f8346ab

 这表示实例化成功&#xff0c;但是有一点peer命令比较麻烦&#xff0c;它只会向指定的 CORE_PEER_ADDRESS去发送命令&#xff0c;无法同时向多个节点发送初始化请求&#xff0c;所以其他节点再去实例化的时候会报错&#xff1a;xxxchaincode 已经存在了。


<1.2>多组织签名

setup0: 重启本地环境

cd $GOPATH/github.com/hyperledger/fabric/examples/e2e_clibash network_setup.sh restartdocker exec -it cli bash

××cli容器中执行以下步骤


setup1 : Org1 AdminOrg2 Admin 同时签名

ORG_NUM&#61;1 PEER_NUM&#61;0 bash ./scripts/script_chaincode.sh chaincode package -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/example02/cmd -s -S ccpack.outORG_NUM&#61;2 PEER_NUM&#61;2 bash ./scripts/script_chaincode.sh chaincode signpackage ccpack.out signedccpack.out
ps: peer cli 中指定
-S 就会默认的用localMsp对chaincode进行签名。

setup2: Org2 admin 去向Peer3安装智能合约并实例化

重复 <1.1>中的 setup2步骤

仍然会抛出不符合实例化策略的错误。


setup3: Org1 admin 去向Peer3发送实例化请求

重复 <1.1>中的 setup3步骤

执行成功

总结&#xff1a;目前来看不符合预期的结果&#xff01;从以上两种情况来看&#xff0c;即便是instantiation proposal creatorown list中&#xff08;对chaincode进行了签名&#xff09;&#xff0c;如果不符合策略仍然不会成功。 另外&#xff0c;我们发现是无论是否对CDS进行签名&#xff0c;Policy都会生效&#xff0c;校验Creator的时候用packge时的LocalMsp admin发起实例化都会成功。

分析源码找到了原因&#xff1a;Peercli 在打包时不指定policy的情况下&#xff0c;默认会添进去的"AND(&#39;" &#43; mspid &#43; ".admin&#39;)"策略。

peer/chaincode/package.gogetChaincodeInstallPackage(){… … ip :&#61; instantiationPolicyif ip &#61;&#61; "" {
//if an instantiation policy is not given, default
//to "admin must sign chaincode instantiation proposals"
mspid, err :&#61; mspmgmt.GetLocalMSP().GetIdentifier()
if err !&#61; nil {
return nil, err
}
ip
&#61; "AND(&#39;" &#43; mspid &#43; ".admin&#39;)"
}
… …
}

 

&#xff08;2&#xff09;指定实例化策略策略

预期&#xff1a;实例化成功

setup 0 重启测试环境

setup 1 打包智能合约并设置背书策略

ORG_NUM&#61;1 PEER_NUM&#61;3 bash ./scripts/script_chaincode.sh chaincode package -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/example02/cmd -s -i "OR(&#39;Org1MSP.admin&#39;,&#39;Org2MSP.admin&#39;)" ccpack.outps: cli 中默认设置的localMsp是Org1MSP

setup2: Org2 admin 去向Peer3安装智能合约并实例化

参照<1.1>setup2

结果&#xff1a;符合预期&#xff0c;测试成功。

总结: 我们这里只能测试OR策略&#xff0c;因为peer-cli只会读取本地的localMSP作为creator进行背书发送实例化请求&#xff0c;AND请求需要两个组织的admin的证明。另外我们可以看到Org2admin并没有对ccpack.out进行签名也安装成功了&#xff0c;是否包含ownerlist 看来并不影响实例化过程。



&#xff08;3&#xff09;不指定实例化策略打包直接安装

预期&#xff1a;任何一个组织的Admin都能初始化

setup 0&#xff1a; 重启测试环境

setup 1&#xff1a;直接安装

ORG_NUM&#61;2 PEER_NUM&#61;3 bash ./scripts/script_chaincode.sh chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/example02/cmdORG_NUM&#61;1 PEER_NUM&#61;3 bash ./scripts/script_chaincode.sh chaincode instantiate -C mychannel -n mycc -v 1.0 -c &#39;{"Args":["init","a","100","b","200"]}&#39; -P "OR(&#39;Org1MSP.peer&#39;,&#39;Org2MSP.peer&#39;)"

结果执行成功&#xff1a;与预期相互符合。


&#xff08;4&#xff09;升级chaincode

<4.1>已安装的chaincode 未指定instantiate policy

预期&#xff1a;任意一个OrgAdmin可以更新&#xff0c;因为在官方文档中说法是按照当前已经存在的chaincode的实例化策略进行判别&#xff0c;目前状态下的chaincode是没有指定策略&#xff0c;也就是任意一个org.admin身份都可以。

setup1: 安装新版本链码并指定instantiate policy策略&#xff0c;版本设置为1.1

#指定实例化策略为只有Org1MSP.admin

ORG_NUM&#61;1 PEER_NUM&#61;3 bash ./scripts/script_chaincode.sh chaincode package -n mycc -v 1.1 -p github.com/hyperledger/fabric/examples/chaincode/go/example02/cmd -s -i "AND(&#39;Org1MSP.admin&#39;)" ccpack.outORG_NUM&#61;2 PEER_NUM&#61;3 bash ./scripts/script_chaincode.sh chaincode install ccpack.out

 

setup2: 更新chaincode

#使用不符合新合约策略的Org2MSP.admin去更新智能合约

ORG_NUM&#61;2 PEER_NUM&#61;3 bash ./scripts/script_chaincode.sh chaincode upgrade -C mychannel -n mycc -v 1.1 -c &#39;{"Args":["init","a","100","b","200"]}&#39; -P "OR(&#39;Org1MSP.peer&#39;,&#39;Org2MSP.peer&#39;)"

执行失败


setup3:

#使用 Org1MSP.admin 去更新智能合约

ORG_NUM&#61;1 PEER_NUM&#61;3 bash ./scripts/script_chaincode.sh chaincode upgrade -o orderer.example.com:7050 -n mycc -v 1.1 -c &#39;{"Args":["init","a","100","b","200"]}&#39; -P "OR(&#39;Org1MSP.peer&#39;,&#39;Org2MSP.peer&#39;)" -C mychannel

执行成功

结果: 不符合预期


<4.2>已安装的chaincode 指定instantiate policy

预期&#xff1a;只有符合当前安装的chaincodeinstantiate策略的身份才可以去更新

此时我们刚执行完4.2测试&#xff0c;所以正好符合测试场景

setup1: 安装新版本链码并指定instantiate policy策略&#xff0c;版本设置为1.2

#指定实例化策略为只有Org1MSP.admin

ORG_NUM&#61;2 PEER_NUM&#61;3 bash ./scripts/script_chaincode.sh package -n mycc -v 1.2 -p github.com/hyperledger/fabric/examples/chaincode/go/example02/cmd -s -i "AND(&#39;Org2MSP.admin&#39;)" ccpack.outORG_NUM&#61;2 PEER_NUM&#61;3 ./scripts/script_chaincode.sh chaincode install ccpack.out

 

setup2: 更新chaincode

#使用不符合新合约策略的Org2MSP.admin去更新智能合约

ORG_NUM&#61;2 PEER_NUM&#61;3 ./scripts/script_chaincode.sh chaincode upgrade -C mychannel -n mycc -v 1.2 -c &#39;{"Args":["init","a","100","b","200"]}&#39; -P "OR(&#39;Org1MSP.peer&#39;,&#39;Org2MSP.peer&#39;)"

不能实例化成功&#xff1a;msg instantiation policy violation: signature set did not satisfy policy

符合预期


Setup3:

ORG_NUM&#61;1 PEER_NUM&#61;3 bash ./scripts/script_chaincode.sh chaincode upgrade -o orderer.example.com:7050 -n mycc -v 1.2 -c &#39;{"Args":["init","a","100","b","200"]}&#39; -P "OR(&#39;Org1MSP.peer&#39;,&#39;Org2MSP.peer&#39;)" -C mychannel

不能实例化成功&#xff1a;msg instantiation policy violation: signature set did not satisfy policy

执行失败

结果&#xff1a; 不符合预期

总结&#xff1a;根据我们对源码的研究&#xff0c;更新智能合约的时候不仅仅会校验当前已经实例化合约的instantiate_policy 还会去校验新安装合约的 instantiate_policy&#xff0c;必须二者全部符合才能生效&#xff01;

// executeUpgrade implements the "upgrade" Invoke transaction.
func (lscc *lifeCycleSysCC) executeUpgrade(stub shim.ChaincodeStubInterface, chainName string, cds *pb.ChaincodeDeploymentSpec, policy []byte, escc []byte, vscc []byte, cdfs *ccprovider.ChaincodeData, ccpackfs ccprovider.CCPackage, collectionConfigBytes []byte) (*ccprovider.ChaincodeData, error) {//获取当前版本的chaincode cds
//we need the cd to compare the version
cdLedger, err :&#61; lscc.getChaincodeData(chaincodeName, cdbytes)
if err !&#61; nil {
return nil, err
}
//do not upgrade if same version
if cdLedger.Version &#61;&#61; cds.ChaincodeSpec.ChaincodeId.Version {
return nil, IdenticalVersionErr(chaincodeName)
}
//do not upgrade if instantiation policy is violated
if cdLedger.InstantiationPolicy &#61;&#61; nil {
return nil, InstantiationPolicyMissing("")
}
// get the signed instantiation proposal//校验是否符合当前版本的InstantiationPolicy
signedProp, err :&#61; stub.GetSignedProposal()
if err !&#61; nil {
return nil, err
}err
&#61; lscc.support.CheckInstantiationPolicy(signedProp, chainName, cdLedger.InstantiationPolicy)
if err !&#61; nil {
return nil, err
}
//校验是否符合请求中实例化的chaincode所指定的 Instantiation Policy
//retain chaincode specific data and fill channel specific ones
cdfs.Escc &#61; string(escc) //用于背书的系统级智能合约名称 默认为escc
cdfs.Vscc &#61; string(vscc) //用于校验的系统级智能合约名称 默认为cscc
cdfs.Policy &#61; policy //从client端传入
// retrieve and evaluate new instantiation policy
cdfs.InstantiationPolicy, err &#61; lscc.support.GetInstantiationPolicy(chainName, ccpackfs)
if err !&#61; nil {
return nil, err
}
err
&#61; lscc.support.CheckInstantiationPolicy(signedProp, chainName, cdfs.InstantiationPolicy)
if err !&#61; nil {
return nil, err
}
…… ……
return cdfs, nil
}


官方的文档有很多隐藏的坑&#xff0c;所以当遇到问题时最好的方法是阅读源码为准。

 

转:https://www.cnblogs.com/cnblogs-wangzhipeng/p/9531733.html



推荐阅读
author-avatar
yzxnha_975
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有