Hyperledger Fabric 1.2 --- 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= PEER_NUM= 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= PEER_NUM= bash ./scripts/script_chaincode.sh chaincode install signedccpack.out ORG_NUM= PEER_NUM= 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= PEER_NUM= 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= PEER_NUM= 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= PEER_NUM= 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 的
creator
在
own
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= PEER_NUM= 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
的证明。另外我们可以看到
Org2
的
admin
并没有对
ccpack.out
进行签名也安装成功了,是否包含
ownerlist
看来并不影响实例化过程。
(
3
)不指定实例化策略打包直接安装
预期:任何一个组织的
Admin
都能初始化
setup
0:
重启测试环境
略
setup
1:直接安装
ORG_NUM= PEER_NUM= bash ./scripts/script_chaincode.sh chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/example02/cmd ORG_NUM= PEER_NUM= 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
policy
预期:任意一个
OrgAdmin
可以更新,因为在官方文档中说法是按照当前已经存在的chaincode的实例化策略进行判别,目前状态下的chaincode是没有指定策略,也就是任意一个org.admin身份都可以。
setup1:
安装新版本链码并指定
instantiate
policy策略,版本设置为
1.1
#
指定实例化策略为只有
Org1MSP.admin
ORG_NUM= PEER_NUM= 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= PEER_NUM= bash ./scripts/script_chaincode.sh chaincode install ccpack.out
setup2:
更新
chaincode
#
使用不符合新合约策略的
Org2MSP.admin
去更新智能合约
ORG_NUM= PEER_NUM= 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= PEER_NUM= bash ./scripts/script_chaincode.sh chaincode upgrade -o orderer.example.com: -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
policy
预期:只有符合当前安装的
chaincode
的
instantiate
策略的身份才可以去更新
此时我们刚执行完
4.2
测试,所以正好符合测试场景
setup1:
安装新版本链码并指定
instantiate
policy策略,版本设置为
1.2
#
指定实例化策略为只有
Org1MSP.admin
ORG_NUM= PEER_NUM= 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= PEER_NUM= ./scripts/script_chaincode.sh chaincode install ccpack.out
setup2:
更新
chaincode
#
使用不符合新合约策略的
Org2MSP.admin
去更新智能合约
ORG_NUM= PEER_NUM= ./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= PEER_NUM= bash ./scripts/script_chaincode.sh chaincode upgrade -o orderer.example.com: -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
}
官方的文档有很多隐藏的坑,所以当遇到问题时最好的方法是阅读源码为准。
Hyperledger Fabric 1.2 --- Chaincode Operator 解读和测试(二)的更多相关文章
- Hyperledger Fabric 1.2 --- Chaincode Operator 解读和测试(一)
前言 本文主要目的是用于整理Hyperledger Fabric中关于chaincode 管理和操作的内容,作者以release-1.2为范本进行讲解. 主要参考链接: https://hyperl ...
- hyperledger fabric 中java chaincode 支持离线打包
联盟链由于其本身的特性,目前应用在一些大型国有企业银行比较多.出于安全考虑,这些企业一般会隔离外网环境.所以在实际生产需求中可能存在需要在一个离线的环境中打包安装chaincode的情况. 本文基于这 ...
- Hyperledger Fabric Chaincode for Operators——实操智能合约
什么是Chaincode(智能合约)? chaincode是一个程序,它是使用Go语言编写的,最终在Java等其他编程语言中实现了指定的接口.chaincode运行在一个被背书peer进程独立出来的安 ...
- Hyperledger Fabric(5)ChainCode的编写步骤
链码(chaincode) 会对 Fabric应用程序 发送的交易做出响应,执行代码逻辑,与 账本 进行交互. 再复习下他们之间的逻辑关系: Hyperledger Fabric 中,Chainco ...
- Hyperledger Fabric CouchDB as the State Database
使用CouchDB作为状态数据库 状态数据库选项 状态数据库包括LevelDB和CouchDB.LevelDB是嵌入在peer进程中的默认键/值状态数据库,CouchDB是一个可选的外部状态数据库.与 ...
- Hyperledger Fabric CouchDB as the State Database——使用CouchDB
使用CouchDB作为状态数据库 状态数据库选项 状态数据库包括LevelDB和CouchDB.LevelDB是嵌入在peer进程中的默认键/值状态数据库,CouchDB是一个可选的外部状态数据库.与 ...
- Hyperledger Fabric 第一次安装
第一次安装fabric有很多坑.记录一下,主要跟版本问题. 参考的是http://www.cnblogs.com/aberic/p/7532114.html 这篇博客. 我用的阿里云centOs 7. ...
- Hyperledger Fabric 踩坑汇总
搭建基础环境 阿里云安装出现的一些问题解决 1. [signal SIGSEGV: segmentation violation code=0x1 addr=xxx pc=xxx] 类似的错误:原始错 ...
- 搭建基于hyperledger fabric的联盟社区(四) --chaincode开发
前几章已经分别把三台虚拟机环境和配置文件准备好了,在启动fabric网络之前我们要准备好写好的chaincode.chaincode的开发一般是使用GO或者JAVA,而我选择的是GO语言.先分析一下官 ...
随机推荐
- URL地址理解
/ 表示相对目录的根目录./ 表示相对目录的本层目录../ 表示相对目录的上层目录
- FWT背板笔记
板子 背板子.jpg \(Fwt\)用于解决这样的问题 \[C_i=\sum_{j\bigoplus k=i}A_j\times B_k\] 其中\(\bigoplus\)是一种二元运算符,如\(or ...
- 4、JVM-虚拟机性能监控与故障处理工具
前言: Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人却想出来. 4.1.概述 给一个系统定位问题的时候,知识.经验是关键基础,数据是依据,工具是 ...
- 使用Charles进行移动APP抓包分析
一.简介 Charles是目前最强大最流行的http抓包调试工具,Mac.Unix.Windows各个平台都支持.特别是做APP开发,调试与服务端的通信,Charles是必备工具. 目前Charles ...
- UVA - 11927 Games Are Important (SG)
Description Games Are Important One of the primary hobbies (and research topics!) among Computing ...
- UITableViewCell的父视图
最近版本测试阶段,发现一个奇怪的问题,以前在A测试机上出现的崩溃bug,解决后今天在B测试机上又出现了,在B上解决完之后,返回到设备A上发现又不行了.最后调试发现是测试设备系统版本不同导致的,A设备是 ...
- Redis高级应用——2
Redis-事务 Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证: 事务是一个单独的隔离操作,事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的 ...
- Java基础加强——动态代理
代理模式: 为其他对象提供一种代理以控制对这个对象的访问. 代理模式主要分为两类: 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了. ...
- JS 判断滚动底部并加载更多效果。。。。。。。。。
JS 判断滚动底部并加载更多效果......... <html lang="zh-cn"> <head> <meta http-equiv=" ...
- 查询红帽linux/Oracle Linux的发行版本的方法
[root@localhost ~]# lsb_release -aLSB Version: :core-4.0-amd64:core-4.0-ia32:core-4.0-noarch:grap ...