Hyperledger Fabric --- Chaincode Operator 解读和测试(二)

本文接上一节是测试部分

搭建一个模拟测试环境

作者将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

整个网络的组织架构:

OrgOrderer
  Org1
    peer:
      Peer0 : peer0.org1
      Peer1 : Peer1.org1
    User:
      Org1Msp.admin

  Org2
    peer:
      Peer2: peer0.org2
      Peer3: peer1.org2

  User:

      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:以下几步都是在cli容器内执行的

setup1:
Org1
admin
chaincode
打包

 ORG_NUM=1 PEER_NUM=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 指令去指定背书策略,-S 没有指定所以没有owner签名。

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

ORG_NUM=2 PEER_NUM=3 bash ./scripts/script_chaincode.sh chaincode install signedccpack.out

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

此时会抛出以下错误:

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发送实例化请求

执行如下命令:

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

查看本地docker容器

docker ps

此时我们能看到新创建了一个容器:
dev-peer1.org2.example.com-mycc-1.0-26c2ef32838554aac4f7ad6f100aca865e87959c9a126e86d764c8d01f8346ab

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

<1.2>多组织签名

setup0:
重启本地环境

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

bash network_setup.sh restart

docker exec -it cli bash

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

setup1
:
Org1
Admin
Org2
Admin
同时签名

ORG_NUM=1 PEER_NUM=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.out

ORG_NUM=2 PEER_NUM=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步骤

执行成功

总结:目前来看不符合预期的结果!从以上两种情况来看,即便是instantiation
proposal

creatorown
list
中(对chaincode进行了签名),如果不符合策略仍然不会成功。
另外,我们发现是无论是否对CDS进行签名,Policy都会生效,校验Creator的时候用packge时的LocalMsp
admin
发起实例化都会成功。

分析源码找到了原因:Peercli
在打包时不指定policy的情况下,默认会添进去的"AND(‘"
+ mspid + ".admin‘)"
策略。

peer/chaincode/package.go

getChaincodeInstallPackage(){
    … …
    ip := instantiationPolicy

if ip == "" {
//if an instantiation policy is not given, default
//to "admin  must sign chaincode instantiation proposals"
mspid, err := mspmgmt.GetLocalMSP().GetIdentifier()
if err != nil {
return nil, err
}
ip = "AND(‘" + mspid + ".admin‘)"
}
… …
}

2)指定实例化策略策略

预期:实例化成功

setup 0 重启测试环境

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

ORG_NUM=1 PEER_NUM=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(‘Org1MSP.admin‘,‘Org2MSP.admin‘)" ccpack.out

ps: cli 中默认设置的localMsp是Org1MSP

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

参照<1.1>setup2

结果:符合预期,测试成功。

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

3)不指定实例化策略打包直接安装

预期:任何一个组织的Admin都能初始化

setup
0

重启测试环境

setup
1
:直接安装

ORG_NUM=2 PEER_NUM=3 bash ./scripts/script_chaincode.sh chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/example02/cmd

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

结果执行成功:与预期相互符合。

4)升级chaincode

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

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

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

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

ORG_NUM=1 PEER_NUM=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(‘Org1MSP.admin‘)" ccpack.out

ORG_NUM=2 PEER_NUM=3 bash ./scripts/script_chaincode.sh chaincode install ccpack.out

setup2: 更新chaincode

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

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

执行失败

setup3:

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

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

执行成功

结果: 不符合预期

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

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

此时我们刚执行完4.2测试,所以正好符合测试场景

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

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

ORG_NUM=2 PEER_NUM=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(‘Org2MSP.admin‘)" ccpack.out

ORG_NUM=2 PEER_NUM=3 ./scripts/script_chaincode.sh chaincode install ccpack.out

setup2: 更新chaincode

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

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

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

符合预期

Setup3:

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

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

执行失败

结果: 不符合预期

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



// 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 := lscc.getChaincodeData(chaincodeName, cdbytes)
if err != nil {
return nil, err
}
//do not upgrade if same version
if cdLedger.Version == cds.ChaincodeSpec.ChaincodeId.Version {
return nil, IdenticalVersionErr(chaincodeName)
}
//do not upgrade if instantiation policy is violated
if cdLedger.InstantiationPolicy == nil {
return nil, InstantiationPolicyMissing("")
}
// get the signed instantiation proposal

    //校验是否符合当前版本的InstantiationPolicy
signedProp, err := stub.GetSignedProposal()
if err != nil {
return nil, err
}

err = lscc.support.CheckInstantiationPolicy(signedProp, chainName, cdLedger.InstantiationPolicy)
if err != nil {
return nil, err
}

    //校验是否符合请求中实例化的chaincode所指定的 Instantiation Policy
//retain chaincode specific data and fill channel specific ones
cdfs.Escc = string(escc) //用于背书的系统级智能合约名称 默认为escc
cdfs.Vscc = string(vscc) //用于校验的系统级智能合约名称 默认为cscc
cdfs.Policy = policy //从client端传入
// retrieve and evaluate new instantiation policy
cdfs.InstantiationPolicy, err = lscc.support.GetInstantiationPolicy(chainName, ccpackfs)
if err != nil {
return nil, err
}
err = lscc.support.CheckInstantiationPolicy(signedProp, chainName, cdfs.InstantiationPolicy)
if err != nil {
return nil, err
}
…… ……
return cdfs, nil
}
官方的文档有很多隐藏的坑,所以当遇到问题时最好的方法是阅读源码为准。 

pre { direction: ltr; color: rgb(0, 0, 10); text-align: left }
pre.western { font-family: "Liberation Mono", serif }
pre.cjk { font-family: "Nimbus Mono L" }
pre.ctl { font-family: "Liberation Mono" }
p { margin-bottom: 0.25cm; direction: ltr; color: rgb(0, 0, 10); line-height: 120%; text-align: left }
p.western { font-family: "Liberation Serif", serif; font-size: 12pt }
p.cjk { font-family: "Noto Sans CJK SC Regular"; font-size: 12pt }
p.ctl { font-family: "Noto Sans CJK SC Regular"; font-size: 12pt }
code.western { font-family: "Liberation Mono", serif }
code.cjk { font-family: "Nimbus Mono L" }
code.ctl { font-family: "Liberation Mono" }

原文地址:https://www.cnblogs.com/cnblogs-wangzhipeng/p/9531733.html

时间: 2024-11-10 17:35:09

Hyperledger Fabric --- Chaincode Operator 解读和测试(二)的相关文章

Hyperledger Fabric 1.0 从零开始(十二)——fabric-sdk-java应用

Hyperledger Fabric 1.0 从零开始(十)--智能合约 Hyperledger Fabric 1.0 从零开始(十一)--CouchDB 上述两章,最近网上各路大神文章云集,方案多多,因为最近工作太忙太忙,我暂时就先不赘述了,后续会提供我参考过的大神文章链接出来. 这章先捡大家都比较在意的java sdk应用方案贴出来,很多朋友都找我要过,我主要是把注释都写进去了,用法简单了说了下,一般情况下会java开发的都能看懂. 年前实在太忙. JAVA-SDK 9.1.基本介绍 官方在

实战:区块链hyperledger fabric 初体验 - 2: 测试网络

1.make gen_config generate the crypto-config and channel-artifacts. $ hyperledger/docker-compose-files/hyperledger_fabric/v1.0.5 $ make gen_config 2.进入到cli容器里面 $ docker exec -it fabric-cli bash 3.Create Application Channel with default name of busine

(三)Hyperledger Fabric 1.1安装部署-chaincode测试

环境搭建完毕,需要的工具和镜像安装完毕,就可以进行chaincode测试了,接下来参考官方教程运行first-network. 进入first-netwok: cd first-network first-network的文件结构如下 在first-network目录下有两个自动化脚本byfn.sh和eyfn.sh,这两个脚本的启动顺序是先执行byfn.sh再执行eyfn.sh(eyfn.sh不是必须的,eyfn.sh的作用稍后再介绍).byfn.sh的执行格式为:./byfn.sh (up|d

在Ubuntu中部署并测试HyperLedger Fabric

最近开始研究区块链,对这个新兴的技术有了基本概念上的了解,所以打算基于一个开源项目做做实验.如果是做数字货币,那么比特币的源代码是最好的了,不过这算是区块链1.0吧,已经有很多改进的竞争币和山寨币出来了,所以打算对区块链2.0,也就是智能合约入手. 智能合约比较成功的就是以太坊了.以太坊主要是公有链,其实对企业应用来说并不是特别合适,而且本身并没有权限控制功能,面向企业的,主要还是超级账本HyperLedger的Fabric和刚刚开源出来的R3的Corda.关于这些项目的应用场景和区别,我觉得这

搭建基于hyperledger fabric的联盟社区(七) --升级chaincode

上个版本的chaincode有很多功能不完备,所以要部署新版本的chaincode.Fabric支持在保留现有状态的前提对chaincode进行升级. 一.新版chaincode 新版本的chaincode增加的功能如下: 1.增加了数据追溯功能,在社区用户发起transaction时,chaincode将自动在用户证书中提取用户信息,将其存储在帖子的字段里. 2.加入了敏感词监管功能,敏感词字典和敏感词过滤功能在外部提供,chaincode通过http api(post 请求)调用服务. 3.

hyperledger fabric 1.0.5 分布式部署 (二)

环境:2台 ubuntu 16.04 角色列表 角色 IP地址 宿主端口 docker端口  peer0.org1.example.com  47.93.249.250  7051  7051  peer1.org1.example.com  47.93.249.250  7051  8051  peer0.org2.example.com  47.93.249.250  7051  9051  peer1.org2.example.com  47.93.249.250  7051  10051

Hyperledger Fabric 实战(十二): Fabric 源码本地调试

借助开发网络调试 fabric 源码本地调试 准备工作 IDE Goland Go 1.9.7 fabric-samples 模块 chaincode-docker-devmode fabric 源码 步骤 添加本地域名 127.0.0.1 peer 127.0.0.1 orderer 用 ide 打开 $GOPATH 下的fabric源码目录 在源码目录下添加 dev-network 把 sampleconfig 下的所有文件复制到 dev-network 修改 core.yaml 中 fil

Hyperledger Fabric 1.0 从零开始(二)——公网环境构建

1:环境构建 在本文中用到的宿主机环境是Centos ,版本为Centos.x86_647.2,通过Docker 容器来运行Fabric的节点,版本为v1.0.因此,启动Fabric网络中的节点需要先安装Docker.Docker-compose和Go语言环境,然后在网上拉取相关的Docker镜像,再通过配置compose文件来启动各个节点. 1.1:Docker安装 进入docker官网 GetDocker ->Centos ->Get CE(社区版)->Get Docker CE o

Hyperledger Fabric CA User’s Guide——概述(二)

概述 下面的图表说明了如何将Hyperledger Fabric CA与总体的Hyperledger Fabric结构相匹配. 有两种方式与一种Hyperledger Fabric CA服务器进行交互:通过Hyperledger Fabric CA的客户端或通过任意一种Fabric的SDKs.所有与Hyperledger Fabric CA服务器的通信都是通过REST api进行的.有关这些REST api的swagger文档,请参见fabric-ca/swagger/swagger-fabri