1. 程式人生 > >fabric私密數據學習筆記

fabric私密數據學習筆記

兩個 方法 差異 組織 數據 file core osal 模擬

fabric私密數據學習筆記

私密數據分為兩部分

一個是真正的key,value,它被存在 peer的私密數據庫(couchDB或者levelDB)中。
另一部分為公共數據,它是真實的私密數據key,value 哈希後的值 hash(key),hash(value),它被存在普通的peer數據庫中,orderer端可以拿到該值。沒有被分配私密數據權限的peer,也僅僅可以存儲hash後的key和value。

何時使用channel進行數據隔離,何時使用私密數據進行隔離

  1. 需要組織間進 數據隔離時,使用channel進行數據隔離。
  2. 當需要組織內進 數據隔離時,使用私密數據進行數據隔離。
  3. 處於同一channel的多個組織之間進行數據隔離時,也要使用私密數據進行數據隔離。

私有數據在fabric中的交易流程

技術分享圖片

  1. sdk將交易發送給背書節點,該背書節點需要通過policy(此
    處的policy為instantiation設定的)驗證。

    技術分享圖片

    技術分享圖片

  2. 背書節點模擬執行交易 ,並將真實的私密數據 key和value存
    儲於瞬時數據庫(private transient DB)中。基於collection policy,驗證通過的peer節點,通過gossip同步真實的私密數據,並將其存儲於瞬時數據庫中。

    技術分享圖片

  3. 背書節點將模擬執行後的結果返回給SDK,返回的數據中僅有公共數據(hash過的私密數據)。SDK將peer返回的結果打包後發送給orderer,和普通的區塊一樣,orderer切塊後,將其分發給peer,此時所有的peer都拿到了公共數據,所有的peer都可以去驗證私有數據,沒有通過collection policy的peer,也可以驗證,而且還不擁有真實的私密數據,保證了數據的私密性。

    技術分享圖片

  4. 在commit之前,peer首先去判斷自己是否通過collection policy的檢查,若通過,將去檢查自己的瞬時數據庫中是否有真實的私密數據,如果沒有,將嘗試從別的peer處拉取數據。

    技術分享圖片

  5. 取到私密數據後,首先去和公共數據的hash去做比對,若一致,此時進行commit操作,將私密數據的HASH寫入到公共數據庫中。提交該交易和這個區塊到賬本中,成功提交後,私密數據將會從瞬時數據庫拷貝到私密數據庫中,並從瞬時數據庫中刪除。此時整個交易流程結束,數據成功寫入到賬本內。

如何定義私密數據 collection

一個collection定義包含一個或多個collection,在合約實例化
的時候安裝該collection。cli去部署集合時,使用參數 --

collections-config。

peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C mychannel -n marblesp -v 1.0 -c ‘{"Args":["init"]}‘ -P "OR (‘Org0MSP.member‘,‘Org1MSP.member‘)" --collections-config collections.json

collection的集合定義

name: 集合名稱。

policy: 語法與簽名policy一致,允許哪些組織的peer保存私密數據。私有數據的policy成員必須包含在簽名policy的成員內。每個policy都類似於一個過濾器 ,第一 層過濾為簽名policy,第二層為私密數據policy。若簽名policy未通過驗證,交易將執行失敗,也就不會產生私密數據。第二種情況是當簽名policy通過,但私密數據policy未通過,將沒有peer保存真正的私密數據,只會將hash過的數據保存下來,私密數據也將會丟失,這樣的 policy定義是沒有意義的。

requiredPeerCount: 配置最小分發私有數據peer的數 ,在 peer背書交易和返回給SDK的時間段。當配置為0時,表示不需要分發,但是當maxPeerCount大於0時,還是會分發,分不分發是由這兩個配置項共同決定的。當都是0的情況下,私密數據是存在丟失的可能性。該值必須小於等於maxPeerCount。

maxPeerCount:基於私密數據冗余的目的,將數據分發到其他peer的數量 。如果背書節點掛掉,在背書和commit階段,其他處於collection的peer節點將不能接收到該節點的私密數據, 將從其余已經分發的節點去pull數據。如果這個值設置為0,私密數據在交易背書時間段沒有分發,將強制向所有peer去嘗試pull私密數據。

blockToLive:私密數據生效時長 ,在私密數據庫中保存的時長,將為特定的幾個塊生效,是時間到達後,將會被清除,再也查不到該數據。 設置為0,將一直被保存,永不清除。

一個有權限保存私有數據的peer,丟失了私密數據,在將來的交易中引用私密數據時,將報錯,此處體現 requiredPeerCount和maxPeerCount 的重要性。

collection需要配合chaincode使用,chaincode的shim提供了以下接口:

PutPrivateData(collection,key,value) GetPrivateData(collection,key) GetPrivateDataByRange(collection, startKey, endKey string) GetPrivateDataByPartialCompositeKey(collection, objectType string, keys []string)

Couchdb

GetPrivateDataQueryResult(collection, query string)

使用私密數據的chiancode註意事項:

1、使用couchdb時,sdk去執行range或富查詢時,可能只返回結果集的子集,有些peer可能不含有私密數據。sdk可以向多個peer去查詢並且比較查詢結果,可以確定某些peer是否缺少數據。

2、chaincode在執行range或富查詢時,不支持在同一個交易中執行update操作,因為無法判斷peer是否有權限擁有私密數據權限,或是否丟失私密數據。如果chaincode在一條交易中包含查詢私密數據和更新私密數據兩步操作,這個proposal將返回 Error。如果你的有這個需求,請分為兩條交易去執行。但是一個chaincode方法中既包含GetPrivateData() 和PutPrivateData()卻是可以的,因為所有peer都包含有哈希key的版本號。

3、私密數據collection僅僅定義了組織下的peer能否接收和保存私密數據,意味著僅有某些peer可以查詢私密數據,collection不能限制誰調用chaincode。沒有限制權限的sdk都可以執行chiancode內部邏輯,最好是在chaincode 內部使用GetCreator() 來控制調用chaincode的權限。

私密數據清除

想要在peer上永久保存私密數據,將blockToLive設置為0即可。我們都知道,當一條包含私密數據的交易在fabric中commit之後,私密數據將會在peer的瞬時數據庫中清除,但是若這條交易從不提交,私密數據將會永久保存在瞬時數據庫中。 這時就用到一個配置peer.gossip.pvtData.transientstoreMaxBlockRetention,當符合配置
時,將清除私密數據從瞬時數據庫中。

私密數據在core.yaml中的gossip配置

pullRetryThreshold: pull私密數據的超時時間,超時後將提交一個沒有私
密數據的block。
transientstoreMaxBlockRetention: 當私密數據在瞬時數據庫中存儲時,它與當時賬本中的區塊高度有關,該配置定義了當前區塊的高度與保證不會清除私密數據之間的最大差異。即每當commit的區塊高度達到該配置的倍數時,將觸大發清除瞬時數據庫中的私密數據。
pushAckTimeout:在背書交易的時候,將私密數據push到其他區塊的握手超時時間。
btlPullMargin: 作緩沖區的區塊數 量,新增peer時,當peer解析到私密數據的公共信息時,會得到私密數據所在區塊的編號,這時會去判斷 (賬本高度+ btlPullMargin) > (私密數據所在區塊高度+btl),如果成立,將不會去獲取這個私
密數據,將提交一個沒有私密數據的block到自己賬本。btlPullMargin默認值是10,若btl小於10,新增peer將不會同步任何私密數據。

fabric私密數據學習筆記