Hyperledger Fabric開發(fā)實戰(zhàn)-04編寫智能合約

本文是在閱讀《區(qū)塊鏈開發(fā)實戰(zhàn)-Hyperledger Fabric關(guān)鍵技術(shù)與案例分析》一書的同時,在實踐中記錄的一些實踐步驟與經(jīng)驗分享。

Hyperledger Fabric開發(fā)實戰(zhàn)-05證書服務(wù)器

在上一節(jié)Hyperledger Fabric開發(fā)實戰(zhàn)-03智能合約中,演示了一個簡單的Chaincode示例,可以看到,Chaincode中主要是Init和Invoke方法的實現(xiàn)。兩個方法的原型如下:

func (t *mychaincode) Init(stub shim.ChaincodeStubInterface) pb.Response{
}
func (t *mychaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response{
}

可以看到,主要是對shim.ChaincodeStubInterface的使用。

shim接口

shim.ChaincodeStubInterface

// 獲取傳入的參數(shù),args是一個數(shù)組
function,args = stub.GetFunctionAndParameters()
// 將數(shù)據(jù)保存到fabric中
PutState(key string, value []byte) error
// 將數(shù)據(jù)保存到fabric中
GetState(key string) ([]byte,error)
// 獲取區(qū)間內(nèi)的key
GetStateByRange(startKey,endKey string) (StateQueryInterface,error)
// 獲取key的歷史
GetHistoryForKey(key string) (HistoryQueryIteratorInterface,error)
// 刪除key
DelState(key string) error
// 創(chuàng)建一個組合對象,類似hash對象
CreateCompositeKey(objectType string,attributes [] string) (string,error)
// 獲取hash對象的屬性內(nèi)容
GetStateByPartialCompositeKey(objectType string,keys []string) (StateQueryInterface,error)
// 拆分復(fù)合對象的key
SplitCompositeKey(compositeKey string) (string,[]string,error)

pb.Response

shim提供了一組方法,用來包裝返回的信息

返回成功

// 原型
func Success(payload []byte) pb.Response
// 使用
shim.Success([]byte("success"))

返回失敗

// 原型
func Error(msg string) pb.Response
// 使用
shim.Error("success"))

Chaincode存取數(shù)據(jù)

通過上面的shim接口,我們可以看到如何將數(shù)據(jù)存放到賬本中,如何從賬本取出,下面編寫一個例子來演示,對上一節(jié)的代碼進行改動。

Init方法中,接收兩個名字和金額,如["init","Alice","100","Bob","200"]

func (t *mychaincode) Init(stub shim.ChaincodeStubInterface) pb.Response{
    var args []string
    fmt.Println(" << ====[Init] success init it is view in docker ======")
    _,args = stub.GetFunctionAndParameters()
    var a ,b string
    var aAmt,bAmt int
    var err error
    a = args[0]
    aAmt,err = strconv.Atoi(args[1])
    b = args[2]
    bAmt,err = strconv.Atoi(args[3])
    fmt.Println("aAmt is ",aAmt)
    fmt.Println("bAmt is ",bAmt)
    stub.PutState(a,[]byte(args[1]))
    stub.PutState(b,[]byte(args[3]))
    if err != nil{
       fmt.Println("error")
    } 
    return shim.Success([]byte("success init"))
}

Invoke方法中,接受A到B的轉(zhuǎn)賬,如["invoke","Alice","Bob","10"]

func (t *mychaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response{
   var args []string 
   var aAmtBytes,bAmtBytes []byte
   fmt.Println(" << ====[Invoke] success init it is view in docker ======")
   _,args = stub.GetFunctionAndParameters()
   var a ,b string
   var aAmt,bAmt int
   var transAmt int
   //var err error
   a = args[0]
   b = args[1]
   transAmt,_ = strconv.Atoi(args[2])
   aAmtBytes,_ = stub.GetState(a)
   bAmtBytes,_ = stub.GetState(b)
   aAmt, _ = strconv.Atoi(string(aAmtBytes))
   bAmt, _ = strconv.Atoi(string(bAmtBytes))
   fmt.Println("aAmt form fabric is ",aAmt)
   fmt.Println("bAmt form fabric is ",bAmt)
   aAmt = aAmt - transAmt
   bAmt = bAmt +  transAmt
   stub.PutState(a, []byte(strconv.Itoa(aAmt)))
   stub.PutState(b, []byte(strconv.Itoa(bAmt)))
    return shim.Success([]byte("success init"))
}

編寫完成后,還需要編寫main方法

func main(){
        err := shim.Start(new(mychaincode))
        if err != nil{
                fmt.Println("Error starting Simple chaincode : %s",err)
        }
}

之后,使用go build構(gòu)建,再按照上一節(jié)的方法,安裝,實例化,調(diào)用測試,使用docker logs查詢?nèi)罩?/p>

 << ====[Init] success init it is view in docker ======
aAmt is  100
bAmt is  200

 << ====[Invoke] success init it is view in docker ======
aAmt form fabric is  100
bAmt form fabric is  200
 << ====[Invoke] success init it is view in docker ======
aAmt form fabric is  90
bAmt form fabric is  210
<< ====[Invoke] success init it is view in docker ======
aAmt form fabric is  80
bAmt form fabric is  220

編寫完成Chaincode后,可以執(zhí)行go build查看是否編譯成功,如果安裝和實例化之后更改了Chaincode程序,需要重新build,然后使用peer chaincode upgrade命令,設(shè)置最新的版本號,更新chaincode

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容