天天看點

Hyperledger Fabric 超級賬本的硬傷Hyperledger Fabric 超級賬本的硬傷Netkiller Blockchain 手劄

Hyperledger Fabric 超級賬本的硬傷

Netkiller Blockchain 手劄

本文作者最近在找工作,有意向緻電 13113668890

Mr. Neo Chan, 陳景峯(BG7NYT)

中國廣東省深圳市龍華新區民治街道溪山美地

518131

+86 13113668890

<[email protected]>

文檔始創于2018-02-10

版權 © 2018 Netkiller(Neo Chan). All rights reserved.

版權聲明

轉載請與作者聯系,轉載時請務必标明文章原始出處和作者資訊及本聲明。

http://www.netkiller.cn
http://netkiller.github.io
http://netkiller.sourceforge.net
微信訂閱号 netkiller-ebook (微信掃描二維碼)
QQ:13721218 請注明“讀者”
QQ群:128659835 請注明“讀者”

在使用超級賬本的過程中我發現一個問題,超級賬本無法并發操作一個 key,stub.PutState 是異步執行,我們無法确認它是否執行完成,在沒有執行完成之前再發起操作,就會産生覆寫。這個問題限制了超級賬本的很多場景應用,這是超級賬本的硬傷。

下面舉一個例子來說明超級賬本的問題

func (s *SmartContract) counter(stub shim.ChaincodeStubInterface, args []string) pb.Response {
    key  := "counter"
    count,err = stub.GetState(key)
    count = count + 1
    stub.PutState(key,count)
    return shim.Success(count)
}      

使用多線程請求chaincode中的counter函數100次。你會發現最終 count 并不等于 100。學習過多線程的朋友一定很清楚出了什麼問題。

問題出在 stub.PutState 函數count還沒有被寫入,其他線程就開始讀取stub.GetState(key),導緻讀取舊資料,最終計數器數字混亂。

很多場景需要更新區塊中的資料,如果頻繁操作,就會産生覆寫,目前Hyperledger Fabirc 并沒有提供解決方案。

1. 我們不知道 stub.PutState是否執行完成,因為存儲過程需要共識排序。

2. 超級賬本沒有提供事物處理或者互斥鎖。

我的應用場景是實作代币功能,需要從總賬号給注冊使用者轉賬,操作頻繁。

從總賬中減去 100
    key  := "coinbase"
    money,err = stub.GetState(key)
    money = money - 100
    stub.PutState(key,money)
  
    使用者賬号額度加100
    key  := "account"
    money,err = stub.GetState(key)
    money = money + 100
    stub.PutState(key,money)      

golang 提供的 mutex 也無法解決上面的問題,因為 mutex 鎖隻能工作在一個程序中。Peer / Orderer 節點不止一個。

使用 redis實作分布式鎖或許能實作,但思考過後決定放棄,轉為傳統資料庫。

另一個方案就是代币功能使用以太坊,其他需求使用超級賬本。

繼續閱讀