1 用途
1.1 交易流程回顧
Hyperledger Fabric
區塊鏈網絡交易的執行分為以下幾個步驟。Endorser
與 Committer
都是 Hyperledger Fabric
區塊鏈網絡中 Peer
節點的具體角色。與背書策略強相關的是第3步。
-
Client
構造交易并發往Endorser
節點,Endorser
節點執行交易并調用系統鏈碼ESCC
對交易簽名(背書),結果返回Client
-
Client
將交易響應發送給Orderer
節點進行排序出塊,Orderer
節點將交易打包到區塊中,廣播給網絡上的Committer
節點 -
Committer
節點收到區塊后,對區塊內交易逐一驗證,其中一個重要的步驟是調用系統鏈碼VSCC
校驗交易是否符合指定的Endorsement
策略,最后將區塊追加到區塊鏈上。
'(流程序號與圖中序號無關)
Fabric交易流程圖
1.2 作用
系統鏈碼 VSCC
的作用包括,背書策略為 VSCC
提供2、3的準則。
- 驗證
Endorser
節點對交易的簽名 - 驗證是否有足夠數量的節點對交易背書
- 背書信息來自指定源
2 用法
2.1 實體的定義
實體( Principal
):一個實體由 MSP
與 ROLE
定義,即某個組織內的某個角色。其中ROLE支持四種 client, peer, admin, member
。例如 Org0.admin
表示 Org0 這個 MSP 下的任意管理員; Org1.member
表示 Org1 這個 MSP 下的任意成員。
2.2 表達式
Endorsement Policy
的語法結構如下所示。EXPR
可以是是 AND
或者 OR
邏輯符。E 是實體或者嵌套的表達式。
// 基礎表達式形式
EXPR(E[, E...])
// 需要三個實體都提供簽名
AND('Org1.member', 'Org2.member', 'Org3.member')
// 需要兩個實體任一提供簽名
OR('Org1.member', 'Org2.member')
// 需要Org1的admin提供簽名,或者Org2,Org3的member同時提供簽名
OR('Org1.admin', AND('Org2.member', 'Org3.member'))
2.3 示例
2.3.1 在cli命令行中使用
# 實例化
$ peer chaincode instantiate -C <channelid> -n mycc -P "AND('Org1.member', 'Org2.member')"
# 升級
$ peer chaincode upgrade -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 2.0 -c '{"Args":["init","a","90","b","210"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')"
2.3.2 在SDK使用
Fabric 為SDK提供了另一套獨立的簡單語法來指定背書策略。
Node中可以創建如下對象,示例策略對應命令行的:
AND('ordererOrg.admin', OR(peerOrg1.member, peerOrg2.member))
{
identities: [
// 以下幾項自動編號為[0,1,2]
{ role: { name: "member", mspId: "peerOrg1" }},
{ role: { name: "member", mspId: "peerOrg2" }},
{ role: { name: "admin", mspId: "ordererOrg" }}
],
policy: {
// n-of 指定需要組內多少個進行簽名, 1-of 等價于 OR, max-of 等價于AND,此處2與后面的組相同,因此是AND
"2-of": [
// 對應編號2的身份
{ "signed-by": 2},
// 嵌套
{ "1-of": [{ "signed-by": 0 }, { "signed-by": 1 }]}
]
}
}
Java中創建如下 .yaml
文件,并調用 ChaincodeEndorsementPolicy.fromYamlFile()
進行解析即可。示例策略對應命令行的 :
OR(OR('Org1MSP.member', 'Org1MSP.admin'), OR('Org2MSP.member', 'Org2MSP.admin'))
# 指定策略中會用到的角色
identities:
# Org1MSP 中的 member
user1: {"role": {"name": "member", "mspId": "Org1MSP"}}
# Org2MSP 中的 member
user2: {"role": {"name": "member", "mspId": "Org2MSP"}}
# Org1MSP 中的 admin
admin1: {"role": {"name": "admin", "mspId": "Org1MSP"}}
# Org2MSP 中的 admin
admin2: {"role": {"name": "admin", "mspId": "Org2MSP"}}
policy:
# n-of 指定需要組內多少個進行簽名, 1-of 等價于 OR, max-of 等價于AND
1-of:
# 嵌套
- 1-of:
# user1 即上面角色中的 user1
- signed-by: "user1"
- signed-by: "admin1"
- 1-of:
- signed-by: "user2"
- signed-by: "admin2"
3 注意點
3.1 默認策略
Chaincode需要在部署時指定 Endorsement Policy
,否則默認的背書策略為通道中組織的任意成員( “any member of the organizations in the channel”)。例如,通道中有兩個組織 Org1
, Org2
,則默認策略為 OR('Org1.member', 'Org2.member')
。
3.2 新增實體
對于 Chaincode 實例化后才加入的組織,其節點可以進行 Chaincode 查詢操作,但是不能對背書交易進行提交,此時需要修改 Chaincode 的背書策略以增加該組織相關節點的權限。我們可以通過 Upgrade Chaincode
來達到為其指定新的背書策略的目標。
3.3 交易驗證失敗
如1.1所述,Hyperledger Fabric
區塊鏈網絡的交易執行到第3步時, Orderer
節點已經出塊,交易包含在區塊中。若此處僅僅是區塊內部的交易驗證失敗,不會影響區塊上鏈,只是對于該交易會標記一個交易失敗的驗證碼(ValidationCode
: "0" 表示交易成功,"非0"表示交易無效),對于背書策略不符的情況,驗證碼為 ENDORSEMENT_POLICY_FAILURE(10)
。
4 參考資料
- Hyperledger Fabric v1.1 官方文檔
https://hyperledger-fabric.readthedocs.io/en/release-1.1/endorsement-policies.html - Fabric Node SDK 說明文檔
https://fabric-sdk-node.github.io/global.html#ChaincodeInstantiateUpgradeRequest - Fabric 源碼
fabric-sdk-java-release-1.1\src\test\fixture\sdkintegration\chaincodeendorsementpolicy.yaml