Hyperledger Fabric的維運 — 背書政策

每個chaincode都有一個背書政策,該政策指定渠道上必須執行chaincode並背書執行結果的一群對等節點,以便交易被視為有效。 這些背書政策定義了必須“背書(edorse)”(即批准)提案執行的組織(透過對等節點)。

作為對等節點執行的交易驗證步驟的一部分,每個驗證對等節點都會檢查以確保交易有包含適當數量的背書(多少組織同意)並且它們來自預期的來源(這兩者都會在背書政策中指定)。 並確認背書是有效的(即它們是來自有效憑證的有效簽名)。

需要背書的多種方式

預設情況下,背書政策在chaincode definition中指定,由渠道成員同意,然後提交給渠道(就是一個背書政策會涵蓋與chaincode關聯的所有狀態)。

對於private data collections,我們還可以在private data collections的級別指定背書政策,這將包含private data collections中任何密鑰的chaincode level背書政策,從而進一步限制哪些組織可以寫入private data collections。

最後,在某些情況下,特定的公共渠道狀態或private data collections state(換句話說,特定的key-value pair)可能需要具有不同的背書政策。這種基於狀態(state)的背書允許chaincode level或collections level的背書政策被特定key的不同政策所覆寫過去。

為了說明可能使用各種類型的背書政策的情況,我們舉例渠道中的資產為房屋。將房屋作為可交易資產的“創造(creation)”(也稱為“發行”)必須滿足chaincode level的背書政策(換句話說,將代表房屋的key-value pair放入world state)。如何設置chaincode level的背書政策的說明如下。

如果代表房屋的key需要特定的背書政策,則可以在房屋創建時或之後定義。有非常多的原因為何是有必要或想要設置特定狀態的背書政策。這棟房屋可能是豪宅,因此有必要獲得估價師的認可。此外,屋主(如果他們是渠道的成員)可能還希望確保渠道中其他的交易夥伴簽署交易。在這兩種情況下,特定資產都需要一個背書政策,該策略不同於與這個chaincode關聯的其他資產的預設背書政策,也就是特殊資產需要特殊的背書政策。

我們將在後續部分說明如何定義基於狀態(state-based)的背書政策。但首先,讓我們看看我們如何設置chaincode levle的背書政策。

設置chaincode-level背書政策

渠道成員在為其組織批准chaincode definition時也同時同意了chaincode level的背書政策。 足夠數量的渠道成員需要批准chaincode definition以滿足 Channel/Application/LifecycleEndorsement 政策,該政策預設設置為大多數渠道成員,然後chaincode definition才能提交給渠道。 提交chaincode definition後,chaincode就可以使用了。 任何將資料寫入帳本的chaincode 呼叫都需要由足夠多的渠道成員驗證以滿足背書策略。

當我們使用Fabric的 peer指令並帶有signature-policy flag 批准和提交chaincode definition時,我們就可以建立背書政策。

peer lifecycle chaincode approveformyorg --channelID mychannel --signature-policy "AND('Org1.member', 'Org2.member')" --name mycc --version 1.0 --package-id mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173 --sequence 1 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --waitForEvent

上面的範例使用 AND(‘Org1.member’, ‘Org2.member’) 政策批准 名為mycc 的chaincode definition,指令要求 Org1 和 Org2 的成員簽署交易。 在足夠數量的渠道成員批准 mycc 的chaincode definition後,可以使用以下命令將chaincode definition和背書政策提交給渠道:

peer lifecycle chaincode commit -o orderer.example.com:7050 --channelID mychannel --signature-policy "AND('Org1.member', 'Org2.member')" --name mycc --version 1.0 --sequence 1 --init-required --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --waitForEvent --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

如果啟用了identity classification,則可以使用 PEER role將背書限制為只有對等節點。

如果我們沒有指定政策,則預設的chaincode definition的預設政策會Channel/Application/Endorsement 政策,這需要大多數渠道成員驗證交易。這個政策取決於渠道的成員,因此在渠道中加入或刪除組織時會自動更新。使用渠道政策的一個優點是可以修改它們然後渠道成員的資格就會自動更新。

如果我們使用 — signature-policy flag 指定背書政策,則需要手動在組織加入或離開渠道時更新該政策。定義chaincode後加入到渠道的新組織才能查詢chaincode但無法執行或認可chaincode本身。而新加入的組織能查詢的前提是查詢權限需要渠道政策有定義的適當授權以及chaincode可以執行的任何application level checks。只有背書政策語法中列出的組織才能簽署交易。

背書政策的指令語法

正如我們在上面看到的,政策以主體(principals)呈現(“主體”是與角色匹配的身份)。 主體被描述為“MSP.ROLE”,其中 MSP 呈現所需的 MSP ID,ROLE 表示四種接受的角色之一:member、admin、client和peer。

以下是一些有效主體的範例:

  • 'OrgA.admin': OrgA MSP裡的任一個管理員
  • 'OrgB.member': OrgB MSP裡的任一個成員
  • 'OrgC.client': OrgC MSP裡的任一個客戶端
  • 'OrgC.peer': OrgC MSP裡的任一個對等節點

語法是:

EXPR(E[, E…])

其中 EXPR的參數為 AND, OR, OutOf三個其中一種,而E代表的則是主題或是可以是另一個 EXPR的nested call。另外其他以下的範例:

  • AND(‘Org1.member’, ‘Org2.member’, ‘Org3.member’) — 要求三個組織的成員都要有人簽名
  • OR(‘Org1.member’, ‘Org2.member’) — 這要求兩個組織中只要有一個組織的成員簽名即可
  • OR(‘Org1.member’, AND(‘Org2.member’, ‘Org3.member’)) — 需要Org2跟3的組織成員都簽名,或是Org1的成員簽名。
  • 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’))。其實就是三個組織只要有任兩個同意即可。

設定collection-level的背書政策

與chaincode lev背書政策類似,當我們批准並提交chaincode definition時,我們還可以指定chaincode的private data collections和相應的collection-level背書政策。如果設置了collection-level的背書政策,則寫入private data collections key的交易將要求指定的組織對等節點已經背書了這筆交易。

我們可以使用collection-level的背書政策來限制哪些組織對等節點可以寫入private data collection key namespace,例如確保未經授權的組織不能寫入collection,並確任private data collection中的任何狀態已獲得所需要的collection組織的認可。

collection-level的背書政策可能比chaincode level的背書政策和collection的rivate data distribution policy限制更多或更少。例如,大多數組織可能需要為chaincode交易背書,但特定組織可能需要為包含特定collection中有特定key的交易背書。

如果我們沒有指定collection-level的背書政策,則會討用chaincode level的背書政策來保護對private data collection key namespace的寫入。如果一組滿足chaincode level背書政策的組織被授權在其他組織的private data collection中建立資料,這可能是需要的。例如,如果這些組織被信任處理交易,但由於監管法規而無權存儲和事後查詢私人資料,或者如果私人資料正在通過使用 private data collections從一群組織共享或傳輸到另一群組織。在另一個場景中, private data collections成員可能需要完全控制對 private data collections的寫入,在這種情況下,提就需要提供collection level的背書政策。

collection levle背書政策的語法與chaincode level背書政策的語法完全一樣— — 在collection configuration中,我們可以使用 signaturePolicy 或 channelConfigPolicy 搭配endorsementPolicy。

設定key-level的背書政策

設置一般性chaincode-level或collection-level背書政策與相應chaincode的生命週期相關聯。 它們只能在定義渠道上的chaincode時設置或修改。

相比之下,可以在chaincode中以更精細的方式設置和修改key-level背書政策。 修改是一般性chaincode的read-write set的一部分。

shim API 提供以下函數來從一般性key設置和檢索背書政策。

注意:
下面的 ep 代表“背書政策(endorsement policy)”,可以使用上面描述的相同語法或使用下面描述較簡易的函數來表示。 任何一種方法都將產生可由基本 shim API 使用的背書政策。

SetStateValidationParameter(key string, ep []byte) error
GetStateValidationParameter(key string) ([]byte, error)

對於屬於collection中private data一部分的key,以下函數適用:

SetPrivateDataValidationParameter(collection, key string, ep []byte) error
GetPrivateDataValidationParameter(collection, key string) ([]byte, error)

為了幫助設定背書政策並將它們編組到驗證參數中,Go shim 提供了一個具有便利功能的延伸,允許chaincode開發人員根據組織的 MSP identifiers處理背書政策。

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)
}

例如,當key變更時,我們需要設定一個背書政策,這個政策需要兩個特定的組織為其變更背書。這需要將兩個組織的 MSPID 都傳遞給 AddOrgs(),然後呼 Policy() 來建構可以傳遞到的背書政策SetStateValidationParameter()。

驗證(Validation)

在提交時,設置key的值與設置key的背書政策沒有什麼不同 — — 兩者都會更新key的狀態並根據相同的規則進行驗證。

正如我們上面所討論的,如果修改了key並且沒有key-level的背書政策存在,則預設情況下會套用chaincode-level或collection-level的背書政策。當第一次為key設置key-level背書政策時也是如此 — — 新的key-level背書政策必須首先根據預先存在的chaincode-level 或collection-level背書政策進行背書。

如果修改了key並且存在key-level的背書政策,則key-level的背書政策會蓋過chaincode-level 或collection-level的背書策略。實際上,這意味著key-level的背書政策可以比chaincode-level 或collection-level的背書政策限制更多或更少。因為必須滿足chaincode-level 或collection-level的背書政策才能去設置key-level的背書政策,所以沒有違反信任假設。

如果一個key的背書政策被移除(設置為 nil),chaincode-level 或collection-level的背書政策將再次成為預設政策。

如果一個交易修改了多個key,這些key關聯道不同的key-level背書政策,則需要滿足所有這些政策才能使交易有效。

--

--

運用"雲端服務"加速企業的數位轉型願景
運用"雲端服務"加速企業的數位轉型願景

Written by 運用"雲端服務"加速企業的數位轉型願景

我們協助您駕馭名為"雲端運算"的怪獸,馴服它為您所用。諮詢請來信jason.kao@suros.com.tw. https://facebook.com/jason.kao.for.cloud

No responses yet