Hyperledger Fabric啟用CouchDB為狀態(tài)數(shù)據(jù)庫_第1頁
Hyperledger Fabric啟用CouchDB為狀態(tài)數(shù)據(jù)庫_第2頁
Hyperledger Fabric啟用CouchDB為狀態(tài)數(shù)據(jù)庫_第3頁
Hyperledger Fabric啟用CouchDB為狀態(tài)數(shù)據(jù)庫_第4頁
Hyperledger Fabric啟用CouchDB為狀態(tài)數(shù)據(jù)庫_第5頁
已閱讀5頁,還剩18頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

HyperledgerFabric啟用CouchDB為狀態(tài)數(shù)據(jù)庫一.概述1.數(shù)據(jù)請(qǐng)求流超級(jí)賬本采用背書/共識(shí)模型,模擬執(zhí)行和區(qū)塊驗(yàn)證是在不同角色的節(jié)點(diǎn)中分開執(zhí)行的。模擬執(zhí)行是并發(fā)的,這樣可以提高擴(kuò)展性和吞吐量:背書節(jié)點(diǎn):模擬執(zhí)行鏈碼Peer節(jié)點(diǎn):驗(yàn)證交易并提交2.超級(jí)賬本存儲(chǔ)元素超級(jí)賬本包含以下元素:賬本編號(hào):快速查詢存在哪些賬本賬本數(shù)據(jù):實(shí)際的區(qū)塊數(shù)據(jù)存儲(chǔ)區(qū)塊索引:快速查詢區(qū)塊/交易狀態(tài)數(shù)據(jù):最新的世界狀態(tài)數(shù)據(jù)歷史數(shù)據(jù):跟蹤鍵的歷史每個(gè)Peer節(jié)點(diǎn)會(huì)維護(hù)四個(gè)DB,分別為:賬本索引庫(IdStore):存儲(chǔ)ChainID狀態(tài)數(shù)據(jù)庫(StateDB):存儲(chǔ)worldstate歷史數(shù)據(jù)庫(HistoryDB):存儲(chǔ)Key的版本變化區(qū)塊索引庫(BlockIndex):存儲(chǔ)Block索引3.狀態(tài)數(shù)據(jù)庫狀態(tài)數(shù)據(jù)庫可選類型包括LevelDB和CouchDB。LevelDB是嵌入在peer進(jìn)程中的默認(rèn)鍵/值狀態(tài)數(shù)據(jù)庫,CouchDB是一個(gè)可選的外部狀態(tài)數(shù)據(jù)庫。與LevelDB鍵/值存儲(chǔ)一樣,CouchDB可以存儲(chǔ)任何以chaincode建模的二進(jìn)制數(shù)據(jù)(CouchDB附件函數(shù)在內(nèi)部用于非json二進(jìn)制數(shù)據(jù))。但是,當(dāng)chaincode值(例如,資產(chǎn))被建模為JSON數(shù)據(jù)時(shí),作為JSON文檔存儲(chǔ),CouchDB支持對(duì)chaincode數(shù)據(jù)進(jìn)行豐富的查詢。LevelDB和CouchDB都支持核心chaincode操作,例如獲取和設(shè)置一個(gè)鍵(資產(chǎn)),并根據(jù)鍵進(jìn)行查詢。鍵可以通過范圍查詢,可以對(duì)組合鍵進(jìn)行建模,以支持針對(duì)多個(gè)參數(shù)的等價(jià)查詢。例如,作為所有者的組合鍵,資產(chǎn)id可以用于查詢某個(gè)實(shí)體擁有的所有資產(chǎn)。這些基于key的查詢可以用于針對(duì)賬本的只讀查詢,以及更新總賬的事務(wù)。如果將資產(chǎn)建模為JSON并使用CouchDB,那么就可以使用chaincode中的CouchDBJSON查詢語言對(duì)chaincode數(shù)據(jù)值執(zhí)行復(fù)雜的富查詢,這些類型的查詢對(duì)于理解賬本上的內(nèi)容很有幫助。對(duì)于這些類型的查詢,事務(wù)協(xié)議響應(yīng)通常對(duì)客戶端應(yīng)用程序有用,但通常不會(huì)作為事務(wù)提交到排序服務(wù)。事實(shí)上,也無法保證結(jié)果集在chaincode執(zhí)行與富查詢提交時(shí)間之間的穩(wěn)定性,因此使用富查詢的結(jié)果去執(zhí)行最終的事務(wù)更新操作是不合適的,除非可以保證結(jié)果集在chaincode執(zhí)行時(shí)間與提交時(shí)間之間的穩(wěn)定性,或者可以處理在后續(xù)交易中的潛在變化。例如,如果對(duì)Alice所擁有的所有資產(chǎn)執(zhí)行一個(gè)富查詢并將其傳輸給Bob,那么一個(gè)新的資產(chǎn)可能會(huì)被另一個(gè)事務(wù)分配給Alice,這是在chaincode執(zhí)行時(shí)間和提交時(shí)間之間的另一個(gè)事務(wù),可能此過程中會(huì)錯(cuò)過這個(gè)“虛值”。CouchDB作為一個(gè)獨(dú)立的數(shù)據(jù)庫進(jìn)程與peer一起運(yùn)行,因此在設(shè)置、管理和操作方面有額外的考慮。我們可以考慮從默認(rèn)的嵌入式LevelDB開始,如果需要額外的復(fù)雜的富查詢,可以轉(zhuǎn)移到CouchDB。將chaincode資產(chǎn)數(shù)據(jù)建模為JSON是一種很好的做法,這樣我們就可以在將來執(zhí)行需要的復(fù)雜的富查詢。二.啟用CouchDB本文均采用HyperledgerFabric1.2中fabric-samples中相關(guān)組件與資源,在測(cè)試環(huán)境(fabric-samples/chaincode-docker-devmode)通過Docker啟動(dòng)CouchDB服務(wù)1.配置CouchDB啟動(dòng)信息參考:fabric-samples/first-network/docker-compose-couch.yamlcouchdb0:container_name:couchdb0image:hyperledger/fabric-couchdb#PopulatetheCOUCHDB_USERandCOUCHDB_PASSWORDtosetanadminuserandpassword#forCouchDB.ThiswillpreventCouchDBfromoperatinginan"AdminParty"mode.environment:-COUCHDB_USER=-COUCHDB_PASSWORD=#Comment/Uncommenttheportmappingifyouwanttohide/exposetheCouchDBservice,#forexamplemapittoutilizeFauxtonUserInterfaceindevenvironments.ports:-"5984:5984"networks:-byfn修改:fabric-samples/chaincode-docker-devmode/docker-compose-simple.yaml末尾添加并修改couchdb:container_name:couchdbimage:hyperledger/fabric-couchdb#PopulatetheCOUCHDB_USERandCOUCHDB_PASSWORDtosetanadminuserandpassword#forCouchDB.ThiswillpreventCouchDBfromoperatinginan"AdminParty"mode.environment:-COUCHDB_USER=-COUCHDB_PASSWORD=#Comment/Uncommenttheportmappingifyouwanttohide/exposetheCouchDBservice,http://www.f-1.cc#forexamplemapittoutilizeFauxtonUserInterfaceindevenvironments.ports:-"5984:5984"2.配置CouchDB連接信息參考fabric-samples/first-network/docker-compose-couch.yaml:environment:-CORE_LEDGER_STATE_STATEDATABASE=CouchDB-CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0:5984#TheCORE_LEDGER_STATE_COUCHDBCONFIG_USERNAMEandCORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD#providethecredentialsforledgertoconnecttoCouchDB.Theusernameandpasswordmust#matchtheusernameandpasswordsetfortheassociatedCouchDB.-CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=-CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=depends_on:-couchdb0修改:fabric-samples/chaincode-docker-devmode/docker-compose-simple.yaml中peer模塊修改前peer:container_name:peerimage:hyperledger/fabric-peerenvironment:-CORE_PEER_ID=peer-CORE_PEER_ADDRESS=peer:7051-CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer:7051-CORE_PEER_LOCALMSPID=DEFAULT-CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock-CORE_LOGGING_LEVEL=DEBUG-CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/mspvolumes:-/var/run/:/host/var/run/-./msp:/etc/hyperledger/mspworking_dir:/opt/gopath/src//hyperledger/fabric/peercommand:peernodestart--peer-chaincodedev=true-oorderer:7050ports:-7051:7051-7053:7053depends_on:-orderer修改后peer:container_name:peerimage:hyperledger/fabric-peerenvironment:-CORE_PEER_ID=peer-CORE_PEER_ADDRESS=peer:7051-CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer:7051-CORE_PEER_LOCALMSPID=DEFAULT-CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock-CORE_LOGGING_LEVEL=DEBUG-CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp-CORE_LEDGER_STATE_STATEDATABASE=CouchDB-CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb:5984-CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=-CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=volumes:-/var/run/:/host/var/run/-./msp:/etc/hyperledger/mspworking_dir:/opt/gopath/src//hyperledger/fabric/peercommand:peernodestart--peer-chaincodedev=true-oorderer:7050ports:-7051:7051-7053:7053depends_on:-orderer-couchdb注意JSON文件的格式以及配置信息的一致性,如couchdb名稱等3.啟動(dòng)測(cè)試環(huán)境#docker-compose-fdocker-compose-simple.yamlup-d#dockercontainerls三.編寫鏈碼1.代碼結(jié)構(gòu)代碼包:testdb代碼文件domain.go//數(shù)據(jù)結(jié)構(gòu)代碼main.go//業(yè)務(wù)測(cè)試代碼2.數(shù)據(jù)結(jié)構(gòu)packagemaintypeBillStructstruct{ObjectTypestring`json:"DocType"`//對(duì)象類型定義BillInfoIDstring`json:"BillInfoID"`//票據(jù)IDBillInfoAmtstring`json:"BillInfoAmt"`//票據(jù)金額BillInfoTypestring`json:"BillInfoType"`//票據(jù)類型BillIsseDatastring`json:"BillIsseData"`//出票日期BillDueDatestring`json:"BillDueDate"`//到期日期HoldrAcctstring`json:"HoldrAcct"`//持票人名稱HoldrCmIDstring`json:"HoldrCmID"`//持票人IDWaitEndroseAcctstring`json:"WaitEndroseAcct"`//待背書人名稱WaitEndorseCmIDstring`json:"WaitEndorseCmID"`//待背書人ID}3.測(cè)試代碼請(qǐng)仔細(xì)閱讀注釋信息,此處不做代碼分割描述packagemainimport("/hyperledger/fabric/core/chaincode/shim""fmt""/hyperledger/fabric/protos/peer""encoding/json""bytes")//定義結(jié)構(gòu)體CouchDBChaincode,作為shim.ChaincodeStubInterface實(shí)現(xiàn)類對(duì)象typeCouchDBChaincodestruct{}//重寫shim.ChaincodeStubInterface接口的Init方法func(t*CouchDBChaincode)Init(stubshim.ChaincodeStubInterface)peer.Response{returnshim.Success(nil)}//重寫shim.ChaincodeStubInterface接口的Invoke方法func(t*CouchDBChaincode)Invoke(stubshim.ChaincodeStubInterface)peer.Response{//獲取用戶意圖與參數(shù)fun,args:=stub.GetFunctionAndParameters()//根據(jù)用戶意圖判斷使用何種實(shí)現(xiàn)函數(shù)iffun=="billInit"{returnbillInit(stub)}elseiffun=="queryBills"{returnqueryBills(stub,args)}elseiffun=="queryWaitBills"{returnqueryWaitBills(stub,args)}//如果用戶意圖不符合如上,進(jìn)行錯(cuò)誤提示returnshim.Error("非法操作,指定的函數(shù)名無效")}//billInit函數(shù):初始化票據(jù)數(shù)據(jù)funcbillInit(stubshim.ChaincodeStubInterface)peer.Response{/*定義第一個(gè)票據(jù):持票人名稱:AAA持票人ID:AID待背書人名稱:無待背書人ID:無*/billA:=BillStruct{ObjectType:"billObj",BillInfoID:"POC001",BillInfoAmt:"1000",BillInfoType:"111",BillIsseData:"20180501",BillDueDate:"20180508",HoldrAcct:"AAA",HoldrCmID:"AID",WaitEndroseAcct:"",WaitEndorseCmID:"",}//通過json.Marshal方法對(duì)票據(jù)進(jìn)行序列化操作billAByte,_:=json.Marshal(billA)//通過stub.PutState方法存儲(chǔ)序列化后的字節(jié)數(shù)組err:=stub.PutState(billA.BillInfoID,billAByte)iferr!=nil{returnshim.Error("初始化第一個(gè)票據(jù)失敗:"+err.Error())}billB:=BillStruct{ObjectType:"billObj",BillInfoID:"POC002",BillInfoAmt:"1000",BillInfoType:"111",BillIsseData:"20180501",BillDueDate:"20180508",HoldrAcct:"AAA",HoldrCmID:"AID",WaitEndroseAcct:"BBB",WaitEndorseCmID:"BID",}billBByte,_:=json.Marshal(billB)err=stub.PutState(billB.BillInfoID,billBByte)iferr!=nil{returnshim.Error("初始化第二個(gè)票據(jù)失敗:"+err.Error())}billC:=BillStruct{ObjectType:"billObj",BillInfoID:"POC003",BillInfoAmt:"1000",BillInfoType:"111",BillIsseData:"20180501",BillDueDate:"20180508",HoldrAcct:"BBB",HoldrCmID:"BID",WaitEndroseAcct:"CCC",WaitEndorseCmID:"CID",}billCByte,_:=json.Marshal(billC)err=stub.PutState(billC.BillInfoID,billCByte)iferr!=nil{returnshim.Error("初始化第三個(gè)票據(jù)失敗:"+err.Error())}billD:=BillStruct{ObjectType:"billObj",BillInfoID:"POC004",BillInfoAmt:"1000",BillInfoType:"111",BillIsseData:"20180501",BillDueDate:"20180508",HoldrAcct:"CCC",HoldrCmID:"CID",WaitEndroseAcct:"BBB",WaitEndorseCmID:"BID",}billDByte,_:=json.Marshal(billD)err=stub.PutState(billD.BillInfoID,billDByte)iferr!=nil{returnshim.Error("初始化第四個(gè)票據(jù)失敗:"+err.Error())}returnshim.Success([]byte("所有票據(jù)初始化成功"))}//queryBills函數(shù):批量查詢指定用戶的持票列表funcqueryBills(stubshim.ChaincodeStubInterface,args[]string)peer.Response{//判斷是否有參數(shù)傳入iflen(args)!=1{returnshim.Error("必須指定持票人的證件號(hào)碼")}//將第一個(gè)參數(shù)作為用戶IDholdrCmID:=args[0]/*將CouchDB查詢字符串拼接成一個(gè)JSON串,格式如下:{"selector":{"docType":"billObj","HoldrCmID":"%s"}}*/queryString:=fmt.Sprintf("{\"selector\":{\"DocType\":\"billObj\",\"HoldrCmID\":\"%s\"}}",holdrCmID)//通過自定義的getBillByQueryString函數(shù)進(jìn)行數(shù)據(jù)查詢操作result,err:=getBillByQueryString(stub,queryString)iferr!=nil{returnshim.Error("根據(jù)持票人的證件號(hào)碼批量查詢持票人持有票據(jù)列表時(shí)發(fā)生錯(cuò)誤"+err.Error())}returnshim.Success(result)}//queryWaitBills函數(shù):批量查詢指定用戶的待背書票據(jù)列表funcqueryWaitBills(stubshim.ChaincodeStubInterface,args[]string)peer.Response{iflen(args)!=1{returnshim.Error("必須指定待背書人的證件號(hào)碼")}waitEndorseCmID:=args[0]queryString:=fmt.Sprintf("{\"selector\":{\"docType\":\"billObj\",\"WaitEndorseCmID\":\"%s\"}}",waitEndorseCmID)result,err:=getBillByQueryString(stub,queryString)iferr!=nil{returnshim.Error("根據(jù)待背書人的證件號(hào)碼批量查詢待背書票據(jù)列表時(shí)發(fā)生錯(cuò)誤"+err.Error())}returnshim.Success(result)}//自定義函數(shù):getBillByQueryString:根據(jù)指定的查詢字符串(CouchDB查詢語句)查詢數(shù)據(jù)funcgetBillByQueryString(stubshim.ChaincodeStubInterface,queryStringstring)([]byte,error){//通過stub.GetQueryResult方法獲取迭代器iteratoriterator,err:=stub.GetQueryResult(queryString)iferr!=nil{returnnil,err}//延遲關(guān)閉迭代器iteratordeferiterator.Close()//定義字節(jié)緩沖變量varbufferbytes.Buffer//定義分割符varisSplitbool//對(duì)迭代器進(jìn)行遍歷操作foriterator.HasNext(){//通過迭代器的Next()方法獲取下一個(gè)對(duì)象的Key與Value值(*queryresult.KV)result,err:=iterator.Next()iferr!=nil{returnnil,err}ifisSplit{buffer.WriteString(";")}//定義格式//key:result.keyresult.Valuebuffer.WriteString("key:")buffer.WriteString(result.Key)buffer.WriteString(",value:")buffer.WriteString(string(result.Value))//獲取到第一個(gè)值后,將isSplit設(shè)置為true,用于跟第二個(gè)值進(jìn)行分割isSplit=true}//返回buffer對(duì)象的字節(jié)類型returnbuffer.Bytes(),nil}funcmain(){//啟動(dòng)鏈碼CouchDBChaincodeerr:=shim.Start(new(CouchDBChaincode))//如有報(bào)錯(cuò),提示報(bào)錯(cuò)信息iferr!=nil{fmt.Errorf(err.Error())}}四.安裝鏈碼1.上傳鏈碼上傳鏈碼包testdb至:fabric-samples/chaincode中#ls/home/bruce/hyfa/fabric-samples/chaincode/testdb/domain.gomain.go2.編譯鏈碼#cd/home/bruce/hyfa/fabric-samples/chaincode/testdb/#gobuild#lsdomain.gomain.gotestdb3.啟動(dòng)鏈碼進(jìn)入chaincode容器進(jìn)行操作#dockercontainerexec-itchaincodebash#進(jìn)入chaincode容器進(jìn)行操作#cdtestdb/#CORE_PEER_ADDRESS=peer:7052CORE_CHAINCODE_ID_NAME=testCouchDB:1.0./testdb2018-08-0510:33:37.063UTC[shim]SetupChaincodeLogging->INFO001Chaincodeloglevelnotprovided;defaultingto:INFO2018-08-0510:33:37.063UTC[shim]SetupChaincodeLogging->INFO002Chaincode(buildlevel:)startingup...4.安裝與實(shí)例化鏈碼進(jìn)入cli容器進(jìn)行操作#dockercontainerexec-itclibash#peerchaincodeinstall-ntestCouchDB-v1.0-pchaincodedev/chaincode/testdb#peerchaincodeinstantiate-ntestCouchDB-v1.0-Cmyc-c'{"Args":["init"]}'如有更新請(qǐng)用如下命令進(jìn)行操作#peerchaincodeinstall-ntestCouchDB-v1.1-pchaincodedev/chaincode/testdb#peerchaincodeupgrade-ntestCouchDB-v1.1-Cmyc-c'{"Args":["init"]}'五.測(cè)試鏈碼1.初始化票據(jù)#peerchaincodeinvoke-ntestCouchDB-Cmyc-c'{"Args":["billInit"]}'2.查詢指定用戶所持票據(jù)#peerchaincodequery-ntestCouchDB-Cmyc-c'{"Args":["queryBills","AID"]}'key:POC001,value

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論