一個是真正的key,value,它被存在 peer的私密數據庫(private state)中。
另外一部分爲公共數據,它是真實的私密數據key,value 哈希後的值 hash(key),hash(value),它被存在普通的peer數據庫中(state),orderer端能夠拿到該值。沒有被分配私密數據權限的peer,也僅僅能夠存儲hash後的key和value。數據庫
sdk將交易發送給背書節點,該背書節點須要經過policy(此
處的policy爲instantiation設定的)驗證。json
背書節點模擬執行交易 ,並將真實的私密數據 key和value存
儲於瞬時數據庫(private transient DB)中。基於collection policy,驗證經過的peer節點,經過gossip同步真實的私密數據,並將其存儲於瞬時數據庫中。學習
背書節點將模擬執行後的結果返回給SDK,返回的數據中僅有公共數據(hash過的私密數據)。SDK將peer返回的結果打包後發送給orderer,和普通的區塊同樣,orderer切塊後,將其分發給peer,此時全部的peer都拿到了公共數據,全部的peer均可以去驗證私有數據,沒有經過collection policy的peer,也能夠驗證,並且還不擁有真實的私密數據,保證了數據的私密性。ui
在commit以前,peer首先去判斷本身是否經過collection policy的檢查,若經過,將去檢查本身的瞬時數據庫中是否有真實的私密數據,若是沒有,將嘗試從別的peer處拉取數據。code
取到私密數據後,首先去和公共數據的hash去作比對,若一致,此時進行commit操做,將私密數據的HASH寫入到公共數據庫中。提交該交易和這個區塊到帳本中,成功提交後,私密數據將會從瞬時數據庫拷貝到私密數據庫中,並從瞬時數據庫中刪除。此時整個交易流程結束,數據成功寫入到帳本內。blog
一個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
ip
name: 集合名稱。部署
policy: 語法與簽名policy一致,容許哪些組織的peer保存私密數據。私有數據的policy成員必須包含在簽名policy的成員內。每一個policy都相似於一個過濾器 ,第一 層過濾爲簽名policy,第二層爲私密數據policy。若簽名policy未經過驗證,交易將執行失敗,也就不會產生私密數據。第二種狀況是當簽名policy經過,但私密數據policy未經過,將沒有peer保存真正的私密數據,只會將hash過的數據保存下來,私密數據也將會丟失,這樣的 policy定義是沒有意義的。get
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)
一、使用couchdb時,sdk去執行range或富查詢時,可能只返回結果集的子集,有些peer可能不含有私密數據。sdk能夠向多個peer去查詢而且比較查詢結果,能夠肯定某些peer是否缺乏數據。
二、chaincode在執行range或富查詢時,不支持在同一個交易中執行update操做,由於沒法判斷peer是否有權限擁有私密數據權限,或是否丟失私密數據。若是chaincode在一條交易中包含查詢私密數據和更新私密數據兩步操做,這個proposal將返回 Error。若是你的有這個需求,請分爲兩條交易去執行。可是一個chaincode方法中既包含GetPrivateData() 和PutPrivateData()倒是能夠的,由於全部peer都包含有哈希key的版本號。
三、私密數據collection僅僅定義了組織下的peer可否接收和保存私密數據,意味着僅有某些peer能夠查詢私密數據,collection不能限制誰調用chaincode。沒有限制權限的sdk均可以執行chiancode內部邏輯,最好是在chaincode 內部使用GetCreator() 來控制調用chaincode的權限。
想要在peer上永久保存私密數據,將blockToLive設置爲0便可。咱們都知道,當一條包含私密數據的交易在fabric中commit以後,私密數據將會在peer的瞬時數據庫中清除,可是若這條交易從不提交,私密數據將會永久保存在瞬時數據庫中。 這時就用到一個配置peer.gossip.pvtData.transientstoreMaxBlockRetention,當符合配置
時,將清除私密數據從瞬時數據庫中。
pullRetryThreshold: pull私密數據的超時時間,超時後將提交一個沒有私
密數據的block。
transientstoreMaxBlockRetention: 當私密數據在瞬時數據庫中存儲時,它與當時帳本中的區塊高度有關,該配置定義了當前區塊的高度與保證不會清除私密數據之間的最大差別。即每當commit的區塊高度達到該配置的倍數時,將觸大發清除瞬時數據庫中的私密數據。
pushAckTimeout:在背書交易的時候,將私密數據push到其餘區塊的握手超時時間。
btlPullMargin: 做緩衝區的區塊數 量,新增peer時,當peer解析到私密數據的公共信息時,會獲得私密數據所在區塊的編號,這時會去判斷 (帳本高度+ btlPullMargin) > (私密數據所在區塊高度+btl),若是成立,將不會去獲取這個私
密數據,將提交一個沒有私密數據的block到本身帳本。btlPullMargin默認值是10,若btl小於10,新增peer將不會同步任何私密數據。
轉載請註明出處:https://www.cnblogs.com/zooqkl