下面的gbivcc.go的chaincode,分别实现了方法:Init,Invoke,verify,storeResult,getResult方法。通过invoke方法,可以分别调用verify,storeResult,getResult方法。Gbivcc的代码见文章最后,下面按照启动fabric-samples的终端个数来说明如何安装chaincode。
1号终端
启动fabric-samples示例
docker-compose -f docker-compose-simple.yaml up |
docker exec –it chaincode bash
root@d2629980e76b:/opt/gopath/src/chaincode# mkdir gbivcc && cd gbivcc touch gbivcc.go (拷贝文件末尾的chaincode到该文件中) go build gbivcc.go 运行chaincode CORE_PEER_ADDRESS=peer:7052 CORE_CHAINCODE_ID_NAME=gbivcc:0 ./gbivcc |
docker exec –it cli bash
安装chaincode peer chaincode install -p chaincodedev/chaincode/gb_chaincode/ -n gbivcc -v 0 peer chaincode instantiate -n gbivcc -v 0 -c '{"Args":[]}' -C myc 调用getResult方法 peer chaincode invoke -n gbivcc -c '{"Args":["getResult", "request_id"]}' -C myc |
在2号终端中,修改gbivcc.go的源码为新版本的chaincode代码,或者新添加一个文件也可以。修改完执行如下操作编译chaincode代码,如意命令行中的红色字体,代表版本号的变化(0→1)。
vim gbivcc.go go build gbivcc.go CORE_PEER_ADDRESS=peer:7052 CORE_CHAINCODE_ID_NAME=gbivcc:1 ./gbivcc |
在3号终端中,安装并升级新的chaincode,注意命令中的红色字体部分,代表版本号的变化(0→1)。
peer chaincode install -p chaincodedev/chaincode/gb_chaincode/ -n gbivcc -v 1 peer chaincode upgrade -n gbivcc -v 1 -c '{"Args":[]}' -C myc |
在3号终端中,调用chaincode中的方法,验证方法是否运行正常。调用方法时没有版本号的修改。
peer chaincode invoke -n gbivcc -c '{"Args":["getResult", "request_id"]}' -C myc peer chaincode invoke -n gbivcc -c '{"Args":["storeResult", "request_id", "verify_result"]}' -C myc |
三、 gbivcc.go的chaincode完整代码
下载地址:gbivcc.go
package main
import (
"encoding/json"
"encoding/hex"
"crypto/md5"
"strings"
"fmt"
"math/rand"
"time"
"net/http"
"io/ioutil"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/protos/peer"
"log"
)
const (
//LVWANCenterURL = "http://127.0.0.1:8080"
LVWANCenterURL = "http://www.baidu.com"
REQUEST_PARAMS_HASH = "params_hash"
REQUEST_VERIFY_RESULT = "verify_result"
SUCCESS = "success"
FAILURE = "failure"
)
//GBIdcardVerify implements a simple chaincode to manage an idcard verify
type GBIdcardVerify struct{
}
// Init is called during chaincode instantiation to initialize any
// data. Note that chaincode upgrade also calls this function to reset
// or to migrate data.
func (t *GBIdcardVerify) Init(stub shim.ChaincodeStubInterface) peer.Response{
// Get the args from the transaction proposal
args := stub.GetStringArgs()
log.SetFlags(log.Lshortfile | log.LstdFlags)
log.Printf("Init receive args: %s\n", args)
return shim.Success(nil)
}
// Invoke is called per transaction on the chaincode. Each transaction is
// either a query or verify on a varify idcard created by Init function.
func(t * GBIdcardVerify) Invoke(stub shim.ChaincodeStubInterface) peer.Response{
fn, args := stub.GetFunctionAndParameters()
var result string
var err error
log.Printf("fn: %s, args: %s", fn, args)
//1.validate right
//2.execute function
if fn == "verify"{
result, err = verify(stub, args)
}else if fn =="storeResult"{
result, err = storeResult(stub, args)
}else if fn=="getResult"{
result, err = getResult(stub,args)
}else{
desc :=[]string{"没有实现函数:", fn}
shim.Error(strings.Join(desc, ""))
}
//3.judge error
if err !=nil{
return shim.Error(fmt.Sprintf("function executer error. %s , err: %s", fn, err))
}
// Return the result as success payload
return shim.Success([]byte(result))
}
//Post parameters to lvwan data center.
//return request_id,error
func verify(stub shim.ChaincodeStubInterface, args []string) (string, error){
request_id := stub.GetTxID()
args = append(args,"request_id", request_id)
log.Println("verify receive args: %s", args)
//1.hypteledger
var stateMap map[string]interface{}
stateMap = make(map[string]interface{})
stateMap["REQUEST_PARAMS_HASH"] = getHash(args)
marshaledData, err := json.Marshal(stateMap)
if err !=nil{
return request_id,fmt.Errorf("json marshal failed.request_id: %s, err: %s", request_id, err)
}
err = stub.PutState(request_id, marshaledData)
if err !=nil{
return request_id, fmt.Errorf("put state failed. request_id: %s, err: %s", request_id, err)
}
//2.do request
verifyUrl := getVerifyUrl()
log.Printf("verifyUrl: %s", verifyUrl)
paramsMap :=converArrayToMap(args)
_, err = postData2LvwanCenter(verifyUrl, paramsMap)
if err !=nil{
return request_id, fmt.Errorf("post data to lvwan center failed. request_id: %s, err: %s", request_id, err)
}
return request_id, nil
}
//store task result to state
//return store_result, error
func storeResult(stub shim.ChaincodeStubInterface, args []string) (string,error){
//1.get request_id
if len(args)<2{
return FAILURE,fmt.Errorf("require request_id param.")
}
request_id := args[0]
byteValue, err := stub.GetState(request_id)
log.Printf("store result, receive request_id: %s, byteValue: %s, new result: %s", request_id, byteValue, args[1])
if err !=nil{
return FAILURE, fmt.Errorf("get state failed. request_id: %s, err: %s", request_id, err)
}
var r map[string]interface{}
r = make(map[string]interface{})
json.Unmarshal(byteValue, &r)
r[REQUEST_VERIFY_RESULT] = args[1]
//store result
marshaledData, err := json.Marshal(r)
if err !=nil{
return request_id,fmt.Errorf("store result,json marshal failed.request_id: %s, err: %s", request_id, err)
}
err = stub.PutState(request_id, marshaledData)
if err !=nil{
return request_id, fmt.Errorf("store result,put state failed. request_id: %s, err: %s", request_id, err)
}
return SUCCESS, nil
}
//get task result by request_id,return result, error
func getResult(stub shim.ChaincodeStubInterface, args []string)(string, error){
//1.get request_id
log.Printf("getResult receive args: %s\n", args)
log.Printf("stub.GetTxID is %s\n", stub.GetTxID())
if len(args)<1{
return "",fmt.Errorf("require request_id param.")
}
request_id := args[0]
byteValue, err := stub.GetState(request_id)
log.Printf("receive request_id: %s", request_id)
log.Printf("getSate result, byteValue: %s", byteValue)
log.Printf("getSate result, err: %s", err)
if err !=nil{
return "", fmt.Errorf("get state failed. request_id: %s, err: %s", request_id, err)
}
if byteValue == nil{
return "",nil
}
var r map[string]interface{}
json.Unmarshal(byteValue, &r)
fmt.Printf("result map: %s\n", r)
if r[REQUEST_VERIFY_RESULT] ==nil{
return "",nil
}
return (r[REQUEST_VERIFY_RESULT]).(string), nil
}
//conver string[] to map
func converArrayToMap(params []string) map[string]string{
if params ==nil || len(params) <=0{
return nil
}
if len(params)%2 !=0{
log.Fatalf("length of params is invalid. length: %d", len(params))
}
var paramMap map[string]string
paramMap = make(map[string]string)
for i:=0; i