1.背书策略的定义

每个链码都有背书策略,背书策略指定了通道上的一组 Peer 节点必须执行链码,并且为执行结果进行背书,以此证明交易是有效的。这些背书策略指定了必须为提案进行背书的组织。
作为Peer节点进行交易验证的一部分,每个 Peer 节点的检查确保了交易保存了合适数量的背书,并且是指定背书节点的背书。这些背书结果的检查,同样确保了它们是有效的(比如,从有效的证书得到的有效签名)。

2.背书策略的分类

根据fabric2.0的官方文档,背书策略共分为三类:链码级别的背书策略、集合级别的背书策略、键级别的背书策略。

3.背书策略的语法

策略是使用主体来表达的(主题是跟角色匹配的)。主体可以描述为'MSP.ROLE', MSP 代表了 MSP ID, ROLE 是以下4个其中之一:member, admin, client, and peer。

以下是几个有效的主体示例:

'Org0.admin': Org0 MSP的任何管理员
'Org1.member': Org1 MSP的任何成员
'Org1.client': Org1 MSP的任何客户端
'Org1.peer': Org1 MSP的任何 Peer

语法是:

EXPR(E[, E...])

EXPR 可以是AND, OR, 或者OutOf, 并且E是一个以上语法的主体或者另外一个 EXPR

比如:
AND('Org1.member', 'Org2.member', 'Org3.member')要求3个组织的都至少一个成员进行签名。
OR('Org1.member', 'Org2.member') 要求组织1或者组织2的任一成员进行签名。
OR('Org1.member', AND('Org2.member', 'Org3.member'))要求组织1的任一成员签名,或者组织2和组织3的任一成员,分别进行签名。
OutOf(1, 'Org1.member', 'Org2.member'), 等价于OR(‘Org1.member’, ‘Org2.member’)
类似的, OutOf(2, 'Org1.member', 'Org2.member') 等价于 AND('Org1.member', 'Org2.member'), OutOf(2, 'Org1.member', 'Org2.member', 'Org3.member')等价于 OR(AND('Org1.member', 'Org2.member'), AND('Org1.member', 'Org3.member'), AND('Org2.member', 'Org3.member')).

4.设置背书策略

此为前述(修改智能合约)的拓展,所有操作均在修改智能合约后执行。

4.1 链码级别背书策略

链码级别背书策略可以理解为通过简单执行shell指令指定背书。

4.1.1 或逻辑

在pee0.org1和peer0.org2安装链码后,在peer0.org1的环境变量下执行以下指令,使得交易只需任意org1或org2的成员背书。(如不设置,则默认半数以上通道成员进行背书)

  1. 同意合约
peer lifecycle chaincode approveformyorg  --signature-policy "OR('Org1MSP.member','Org2MSP.member')" --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID channel2 --name mycc1 --version 1 --package-id mycc_1:9be809ce61602d4b44000dc1d39dcb3707eb9c132e6cbe8cfe7d7facd26458e3 --sequence 2 –waitForEvent

切换环境变量,重复执行上述指令。

  1. 提交合约
peer lifecycle chaincode commit -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID channel2 --name mycc1 --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --version 1 --sequence 2    --signature-policy "OR('Org1MSP.member','Org2MSP.member')"
  1. 验证背书策略

这里指定背书节点为peer0.org1

peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C channel2 -n mycc1 --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt  -c '{"Args":["invoke","a","b","10"]}'

查询a的值,如果相较指令执行前,确实减了10,则交易成功。

peer chaincode query -C channel2 -n mycc1 -c '{"Args":["query","a"]}'

4.1.2 与逻辑

  1. 同意合约
peer lifecycle chaincode approveformyorg  --signature-policy "AND('Org1MSP.member','Org2MSP.member')" --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID channel2 --name mycc1 --version 1 --package-id mycc_1:0f82614b848d9f8a3ec49f718c8521709736fe89957c8f1a97918df726f83e51 --sequence 2 --waitForEvent

切换环境变量,重复执行上述指令。

  1. 提交合约
peer lifecycle chaincode commit -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID channel2 --name mycc1 --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --version 1 --sequence 2    --signature-policy "AND('Org1MSP.member','Org2MSP.member')"
  1. 验证背书策略

这里指定背书节点为peer0.org1,测试不满足背书策略时的情况。

peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C channel2 -n mycc1 --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt  -c '{"Args":["invoke","a","b","10"]}'

查询a的值,相较指令执行前,无变化,交易失败。

peer chaincode query -C channel2 -n mycc1 -c '{"Args":["query","a"]}'

4.2 键级别背书策略

键级别背书策略可以理解为通过编写的链码内部调用SDK来指定背书。

4.2.1 修改链码

  1. 备份first-network链码源文件
sudo nautilus

通过图形界面备份fabric-samples/chaincode/abstore/go文件,另存为go_origin

  1. 修改abstore.go文件中的背书策略并保存

4.2.2 下载扩展依赖

  1. 从图形界面(abstore/go目录)进入到终端,执行如下指令
source ~/.profile   			#更新环境变量
GO111MODULE=on go mod vendor  	#更新vendor
  1. 下载扩展依赖

Go 链码需要 Go 标准库之外的一些依赖包(比如链码 shim)。当链码安装到 peer 的时候,这些报的源码必须被包含在你的链码包中。如果你将你的链码构造为一个模块,最简单的方法就是在打包你的链码之前使用 go mod vendor 来 “vendor” 依赖。

go mod tidy
go mod vendor

这就把你链码的扩展依赖放进了本地的 vendor 目录。

当依赖都引入到你的链码目录后, peer chaincode packagepeer chaincode install操作将把这些依赖一起放入链码包中。

  1. 检验是否获取到相关依赖包
ll vendor/github.com/hyperledger/fabric-chaincode-go/

Fabric 交易背书和签名过程 fabric背书节点指定_环境变量


已获取到pkg和shim包

ll vendor/github.com/hyperledger/fabric-chaincode-go/pkg

Fabric 交易背书和签名过程 fabric背书节点指定_github_02


已获取到statebased包

  1. 编译链码
go build

4.2.3 打包链码

peer lifecycle chaincode package mycc_new.tar.gz --path github.com/hyperledger/fabric-samples/chaincode/abstore/go/ --lang golang --label mycc_1

4.2.4 安装链码

peer lifecycle chaincode install mycc_new.tar.gz

4.2.5 同意链码

peer lifecycle chaincode approveformyorg --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID channel2 --name mycc1 --version 1  --package-id  mycc_1:1019711c7eebe7f23827321ffc33549708ce2e9e9c95e2983df3ecea5e45de39 --sequence 2 –waitForEvent

切换环境变量,重复4.2.4和4.2.5的操作

4.2.6 提交链码

peer lifecycle chaincode commit -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID channel2 --name mycc1 --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --version 1 --sequence 2

4.2.7 验证背书策略

  1. 指定背书策略为Org1 and Org2
peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C channel2 -n mycc1 --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt  -c  '{"Args":["endorsement","a","Org1MSP","add"]}'
peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C channel2 -n mycc1 --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt  -c  '{"Args":["endorsement","a","Org2MSP","add"]}'

虽然调用后,会返回Chaincode invoke successful结果,但交易不一定有效,需要查看peer容器的日志。

Fabric 交易背书和签名过程 fabric背书节点指定_环境变量_03


交易成功。

  1. 检验addTen函数

指定peer0.org1和peer0.org2对a进行加10操作

peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C channel2 -n mycc1 --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt  -c '{"Args":["addTen","a"]}'

查询a的状态值

peer chaincode query -C channel2 -n mycc1 -c '{"Args":["query","a"]}'

a值成功加10,表示交易有效。

只指定peer0.org1进行加10操作

peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C channel2 -n mycc1 --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt  -c '{"Args":["addTen","a"]}'

查询a的状态值

peer chaincode query -C channel2 -n mycc1 -c '{"Args":["query","a"]}'

查看peer日志

Fabric 交易背书和签名过程 fabric背书节点指定_环境变量_04


a值未发生变化,交易无效。

  1. 修改背书策略,删除Org2的MSP,检验addTen

只指定Org1

peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C channel2 -n mycc1 --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt  -c  '{"Args":["endorsement","a","Org2MSP","del"]}'

修改成功也可查看日志,因为每次配置的变化都将记录在账本中。

对a进行加10操作

peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C channel2 -n mycc1 --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt  -c '{"Args":["addTen","a"]}'

查询a的状态值

peer chaincode query -C channel2 -n mycc1 -c '{"Args":["query","a"]}'

a值成功加10,表示交易有效。