溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

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

發(fā)布時間:2021-12-28 17:24:07 來源:億速云 閱讀:209 作者:小新 欄目:互聯(lián)網(wǎng)科技

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

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

使用開發(fā)模式開啟你的Hyperledger Fabric鏈碼開發(fā)流程。這一點無論怎么強(qiáng)調(diào)都不過分,這會節(jié)省你大量的時間和精力,因為你可以自由地修改代碼而無需重新部署并激活鏈碼,也無需一遍遍地重啟網(wǎng)絡(luò)。


2、使用Fabric鏈碼的日志

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

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

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

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

看一下鏈碼:

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

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

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

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

stub.PutState("marble_count", totalNumberOfMarbles)

這樣會好一些嗎?Noooooooooooooooooo!

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

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

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

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

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

4、聰明地使用CouchDB查詢

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

  • Couch DB查詢不會修改交易的READ SET

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

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

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

5、編寫確定性的Fabric鏈碼

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

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

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

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

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

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

Example: CORE_CHAINCODE_EXECUTETIMEOUT=60s

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

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

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

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI