背書策略
背書策略用來定義交易是否合法的判斷條件,策略以主體的形式表示。主體格式為'MSP.ROLE', MSP代表所要求的MSPID, ROLE表示角色,一共有四種合法角色:member, admin, client, peer。
背書策略的語法
背書策略的語法如下:
EXPR(E[, E...])
EXPR可以是AND、OR、OutOf,E可以是一個上面示例的主體或者是另一個嵌套的EXPR策略。示例如下:
AND('Org1.member', 'Org2.member', 'Org3.member') :要求三個主體中每一個主體都要簽名。
OR('Org1.member', 'Org2.member') :要求三個主體中至少有一個主體簽名。
OR('Org1.member', AND('Org2.member', 'Org3.member')):要求同時有主體Org1.member的簽名,以及主體Org2.member與Org3.member中至少一個主體的簽名。
OutOf(2, 'Org1.member', 'Org2.member', 'Org3.member') :要求三個主體中,至少有兩個主體簽名。
背書策略的新特性
鏈碼級別的背書策略綁定到相關鏈碼的生命周期中,它只可以在鏈碼初始化時候設置,或者在升級鏈碼時候更新。在fabric1.3版本中,對背書策略進行了優化,增加了背書策略的靈活性。允許針對key設置背書策略,key級別背書策略的設置可以在鏈碼中動態操作。基于key級的背書策略修改會保存在正常交易的讀寫集中。
如果沒有設置基于鍵級別的背書策略的話,使用的是鏈碼級別的背書策略。設置基于鍵級的背書策略的請求,需要滿足當前的背書策略。
基于鍵值背書策略的應用
shim包提供了以下的函數設置或者恢復鍵對應的背書策略。下面的ep代表是“endorsement policy”的縮寫。
SetStateValidationParameter(key string, ep []byte) error
GetStateValidationParameter(key string) ([]byte, error)
以上兩個函數是設置交易中鍵級背書策略的函數,針對私有信息中鍵級別的背書策略用一下兩個函數進行設置。
SetPrivateDataValidationParameter(collection, key string, ep []byte) error
GetPrivateDataValidationParameter(collection, key string) ([]byte, error)
為了幫助設置背書策略和將背書策略序列化為有效的字節格式的參數,shim包提供了便利的接口。
type KeyEndorsementPolicy interface {
// Policy returns the endorsement policy as bytes
Policy() ([]byte, error)
// AddOrgs adds the specified orgs to the list of orgs that are required
// to endorse
AddOrgs(roleType RoleType, organizations ...string) error
// DelOrgs delete the specified channel orgs from the existing key-level endorsement
// policy for this KVS key. If any org is not present, an error will be returned.
DelOrgs(organizations ...string) error
// ListOrgs returns an array of channel orgs that are required to endorse changes
ListOrgs() ([]string)
}
基于鍵級別背書策略的使用示例
此部分主要介紹了如何如何在鏈碼(chaincode)中設置鍵級別的背書策略。
示例鏈碼主要實現并使用了一下三個接口:
query:查詢
endorsement: 設置背書策略
add:賬戶添加額度
鏈碼的工程代碼已經上傳到git上,需要測試的話可以去git下載,git地址:https://github.com/suchongming/keylevelep
以下部分是測試的過程,測試環境共運行兩個組織Org1和Org2,鏈碼的背書策略AND('Org1.member', 'Org2.member'):
- 開始時候賬戶a余額為100
root@42ffceeab24e:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
100
- 賬戶a向余額添加10,向org1和org2同時背書,a余額為110,交易成功
root@4318321f14d0:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n mycc --peerAddresses peer0.org1.example.com:7051 --peerAddresses peer1.org2.example.com:7051 -c '{"Args":["add","a","10"]}'
2019-06-03 08:50:16.772 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
root@4318321f14d0:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
110
- 賬戶a余額添加10,僅向org1背書,a余額為110,交易失敗
root@a0b46d997084:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n mycc --peerAddresses peer0.org1.example.com:7051 -c '{"Args":["add","a","10"]}'
2019-06-04 01:24:39.195 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
root@a0b46d997084:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
110
- 修改賬戶a的背書策略為AND('Org1.member'),然后賬戶a余額添加10,僅向org1背書,a余額為120,交易成功
root@a0b46d997084:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n mycc --peerAddresses peer0.org1.example.com:7051 --peerAddresses peer0.org2.example.com:7051 -c '{"Args":["endorsement","a","Org1MSP"]}'
2019-06-04 01:24:27.752 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
root@a0b46d997084:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n mycc --peerAddresses peer0.org1.example.com:7051 -c '{"Args":["add","a","10"]}'
2019-06-04 01:24:39.195 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
root@a0b46d997084:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
120