Fabric鏈碼開發(fā)的原則有哪些

這篇文章主要介紹了Fabric鏈碼開發(fā)的原則有哪些,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

為榮縣等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及榮縣網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都網(wǎng)站制作、成都做網(wǎng)站、榮縣網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

1、啟用peer節(jié)點(diǎn)的開發(fā)模式

使用開發(fā)模式開啟你的Hyperledger Fabric鏈碼開發(fā)流程。這一點(diǎn)無論怎么強(qiáng)調(diào)都不過分,這會(huì)節(jié)省你大量的時(shí)間和精力,因?yàn)槟憧梢宰杂傻匦薷拇a而無需重新部署并激活鏈碼,也無需一遍遍地重啟網(wǎng)絡(luò)。

2、使用Fabric鏈碼的日志

這可能是能幫助你調(diào)試Hyperledger Fabric鏈碼并快速找出鏈碼bug的第一個(gè)有用的技能。鏈碼日志很簡(jiǎn)單易用,使用Fabric內(nèi)建的logger即可。

3、避免在Fabric鏈碼中使用全局鍵

在開發(fā)Hyperledger Fabric鏈碼時(shí),我們經(jīng)常會(huì)發(fā)現(xiàn)在搜索數(shù)據(jù)方面限制很多,因此要跟蹤在鍵值庫中注冊(cè)的鍵,我們有時(shí)會(huì)嘗試使用某些全局?jǐn)?shù)據(jù)。

例如,當(dāng)你再Hyperledger Fabric應(yīng)用中跟蹤注冊(cè)的彈珠時(shí),可能想創(chuàng)建一個(gè)全局的計(jì)數(shù)器以便生成彈珠的下一個(gè)ID。但是這么做的時(shí)候,你就引入了對(duì)這個(gè)變量的依賴。在開始的時(shí)候這看起來不是個(gè)問題,但是當(dāng)你提交并發(fā)交易時(shí)就會(huì)出錯(cuò)。為什么?讓我解釋一下。

看一下鏈碼:

package main
import (
	//other imports
	"github.com/hyperledger/fabric/core/chaincode/shim"
  	 pb "github.com/hyperledger/fabric/protos/peer"
)

//不要這么做!	
totalNumberOfMarbles := 0

func (t *SimpleChaincode) initMarble(stub shim.ChaincodeStubInterface, args []string) pb.Response {
    var err error
    
	marbleId := fmt.Sprintf("MARBLE_%06d",totalNumberOfMarbles)
	marbleName := args[0]
	color := strings.ToLower(args[1])
	owner := strings.ToLower(args[3])
	size, err := strconv.Atoi(args[2])
	
	//other code to initialize
	objectType := "marble"
	marble := &marble{objectType, marbleId, marbleName, color, size, owner}
	
	//--------------CODE SMELL----------------
	//BIG source of Non-determinism as well as performance hit.
	totalNumberOfMarbles = totalNumberOfMarbles + 1 
	//--------------CODE SMELL----------------
	

	//regular stuff...		
	err = stub.PutState(marbleId, marbleJSONasBytes)
	if err != nil {
		return shim.Error(err.Error())
	}
}

那么,為什么我不喜歡這樣?

第一個(gè)原因。假設(shè)你已經(jīng)完成這個(gè)Fabric鏈碼,一切都很正常,直到有一天,某個(gè)運(yùn)行這個(gè)鏈碼的peer節(jié)點(diǎn),崩潰了。雖然賬本數(shù)據(jù)還在,但是內(nèi)部有些可怕的事情已經(jīng)發(fā)生了。你可能重新啟動(dòng)peer節(jié)點(diǎn),起初一切看起來都正常。但是突然,這個(gè)節(jié)點(diǎn)背書的所有交易都開始失敗了。為什么?就是因?yàn)槟莻€(gè)全局計(jì)數(shù)變量已經(jīng)不能正確跟蹤真實(shí)的值了。其他的peer節(jié)點(diǎn)都計(jì)數(shù)到比如15K了,而這個(gè)節(jié)點(diǎn)突然從零開始計(jì)數(shù),你的彈珠的ID又從零開始了。因此,當(dāng)你將這個(gè)交易發(fā)送給排序節(jié)點(diǎn)(Orderer)并到達(dá)提交節(jié)點(diǎn)(Peer)時(shí),提交節(jié)點(diǎn)上的驗(yàn)證系統(tǒng)(Validation System Chaincode)會(huì)比較所有背書交易的提議響應(yīng),同時(shí)檢查是否有足夠的簽名存在,只要有一個(gè)提議響應(yīng)不匹配,提交節(jié)點(diǎn)就會(huì)拋出一個(gè)ENDORSEMENT_POLICY_FAILURE異常。

第二個(gè)原因?,F(xiàn)在讓我們嘗試解決上面的問題,在Fabric鏈碼的最后添加如下的代碼:

stub.PutState("marble_count", totalNumberOfMarbles)

這樣會(huì)好一些嗎?Noooooooooooooooooo!

想象一下,有兩個(gè)并發(fā)交易都試圖插入新的彈珠。

例如,一個(gè)交易要將marble_count的值更新為34,marble_count狀態(tài)的新版本為10。而另一個(gè)交易則要將marble_count的值更新為35, 它也認(rèn)為marble_count的新版本為10。記住,由于這兩個(gè)交易是并發(fā)的,兩個(gè)交易看到的都是current_version(marble_count) = 09。

現(xiàn)在其中一個(gè)交易將在另一個(gè)交易之前到達(dá)Fabric的排序節(jié)點(diǎn),marble_count鍵已經(jīng)更新到新的值,這時(shí)marble_count的版本已經(jīng)是10,因此后到的交易將失敗,因?yàn)閙arble_count的版本已經(jīng)是10 ,而后續(xù)交易還認(rèn)為它讀的是版本09并且將更新到版本10。這是區(qū)塊鏈中經(jīng)典的雙花問題(double spending)。

Hyperledger Fabric在提交交易時(shí)使用一種優(yōu)化的鎖模型。正如我已經(jīng)解釋過的,提議響應(yīng)由客戶端從背書節(jié)點(diǎn)采集,然后發(fā)送給排序節(jié)點(diǎn)并最終由排序節(jié)點(diǎn)將其分發(fā)給提交節(jié)點(diǎn)。著這個(gè)兩步過程中,如果有些在背書階段讀取的鍵的版本發(fā)生了變化,你就會(huì)得到MVCC_READ_CONFLICT錯(cuò)誤。當(dāng)存在并發(fā)交易同時(shí)更新相同的鍵時(shí),就有可能出現(xiàn)這個(gè)問題。

關(guān)于這一點(diǎn)的詳細(xì)說明,可以參考這篇文章。

4、聰明地使用CouchDB查詢

Couch DB查詢(又稱為Mongo查詢)在搜索Fabric節(jié)點(diǎn)的鍵值庫中的數(shù)據(jù)時(shí)非常有用,但是有一些坑你需要注意。

  • Couch DB查詢不會(huì)修改交易的READ SET

Mongo查詢僅用來查詢節(jié)點(diǎn)的鍵值庫也就是狀態(tài)庫。它不會(huì)修改交易的read set。這可能會(huì)在交易中 導(dǎo)致幻讀(phantom reads)。

  • 只能搜索已經(jīng)存入CouchDB的數(shù)據(jù)

不要試圖用Mongo查詢按鍵名搜索。雖然你可以訪問CouchDB的Fauxton控制臺(tái),但你無法按鍵查詢。例如,不允許查詢 channelName\0000KeyName。更好的方法時(shí)將鍵作為你自己數(shù)據(jù)的屬性保存。

5、編寫確定性的Fabric鏈碼

永遠(yuǎn)不要編寫不確定的鏈碼。意思是說如果我在多個(gè)不同的時(shí)間、不同的環(huán)境下執(zhí)行鏈碼,總應(yīng)該得到相同的結(jié)果。例如,避免使用像rand.New(...)t := time.Now() 這樣的代碼,或者依賴于某個(gè)沒有在賬本中持久化的變量。

這是因?yàn)?,如果生成的讀寫集不一樣,Hyperledger Fabric的驗(yàn)證系統(tǒng)鏈碼(Validation System Chaincode)會(huì)拒絕交易并拋出ENDORSEMENT_POLICY_FAILURE異常。

6、調(diào)用其他通道的Fabric鏈碼時(shí)要小心

在鏈碼中調(diào)用同一個(gè)通道中的另一個(gè)鏈碼沒問題,但是要了解的是,如果是要調(diào)用另一個(gè)通道的鏈碼,你只能得到鏈碼方法的返回結(jié)果,而不會(huì)在另一個(gè)通道賬本中有任何提交。目前,跨通道的鏈碼調(diào)用不會(huì)修改數(shù)據(jù),因此,一個(gè)交易一次只能寫入一個(gè)通道。

7、記得設(shè)置Fabric鏈碼的執(zhí)行超時(shí)時(shí)間

在高負(fù)載的情況下,你的Hyperledger Fabric鏈碼可能不會(huì)在30s內(nèi)完成。因此一個(gè)好的實(shí)踐是根據(jù)需求定制鏈碼執(zhí)行超時(shí)值。這是由core.yaml中的參數(shù)決定的。你可以在docker compose 文件中如下設(shè)置:

Example: CORE_CHAINCODE_EXECUTETIMEOUT=60s

8、避免從Fabric鏈碼中訪問外部資源

訪問外部資源可能會(huì)暴露系統(tǒng)漏洞并給你的Hyperledger Fabric鏈碼引入安全威脅。無論如何你不會(huì)希望外部資源中的惡意代碼影響你的鏈碼邏輯。因此請(qǐng)盡可能的避免再Fabric鏈碼中訪問區(qū)塊鏈外部的資源。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Fabric鏈碼開發(fā)的原則有哪些”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!

網(wǎng)頁名稱:Fabric鏈碼開發(fā)的原則有哪些
文章地址:http://www.muchs.cn/article2/ijsioc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供、Google用戶體驗(yàn)、電子商務(wù)、定制網(wǎng)站面包屑導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)