首先,让我们添加Invoke函数的签名。

  //Invokeiscalledpertransactiononthechaincode.Eachtransactionis

  //eithera'get'ora'set'ontheassetcreatedbyInitfunction.The'set'

  //methodmaycreateanewassetbyspecifyinganewkey-valuepair.

  func(t*SimpleAsset)Invoke(stubshim.ChaincodeStubInterface)peer.Response{

  }

  与上面的Init函数一样,我们需要从ChaincodeStubInterface中提取参数。 Invoke函数的参数将是要调用的链代码应用程序函数的名称。 在我们的例子中,我们的应用程序将只有两个函数:set和get,它们允许设置资产的值或检索其当前状态。 我们首先调用ChaincodeStubInterface.GetFunctionAndParameters来为该链代码应用程序函数提取函数名称和参数。

  //Invokeiscalledpertransactiononthechaincode.Eachtransactionis

  //eithera'get'ora'set'ontheassetcreatedbyInitfunction.TheSet

  //methodmaycreateanewassetbyspecifyinganewkey-valuepair.

  func(t*SimpleAsset)Invoke(stubshim.ChaincodeStubInterface)peer.Response{

  //Extractthefunctionandargsfromthetransactionproposal

  fn,args:=stub.GetFunctionAndParameters()

  }

  接下来,我们将函数名称验证为set或get,并调用这些chaincode应用程序函数,通过shim.Success或shim.Error函数返回适当的响应,这些函数将响应序列化为gRPC protobuf消息。

  //Invokeiscalledpertransactiononthechaincode.Eachtransactionis

  //eithera'get'ora'set'ontheassetcreatedbyInitfunction.TheSet

  //methodmaycreateanewassetbyspecifyinganewkey-valuepair.

  func(t*SimpleAsset)Invoke(stubshim.ChaincodeStubInterface)peer.Response{

  //Extractthefunctionandargsfromthetransactionproposal

  fn,args:=stub.GetFunctionAndParameters()

  varresultstring

  varerrerror

  iffn=="set"{

  result,err=set(stub,args)

  }else{

  result,err=get(stub,args)

  }

  iferr!=nil{

  returnshim.Error(err.Error())

  }

  //Returntheresultassuccesspayload

  returnshim.Success([]byte(result))

  }

  实现Chaincode应用程序

  如上所述,我们的chaincode应用程序实现了两个可以通过Invoke函数调用的函数。 我们现在实现这些功能。 请注意,正如我们上面提到的,为了访问分类帐的状态,我们将利用chaincode shim API的ChaincodeStubInterface.PutState和ChaincodeStubInterface.GetState函数。

  //Setstorestheasset(bothkeyandvalue)ontheledger.Ifthekeyexists,

  //itwilloverridethevaluewiththenewone

  funcset(stubshim.ChaincodeStubInterface,args[]string)(string,error){

  iflen(args)!=2{

  return"",fmt.Errorf("Incorrectarguments.Expectingakeyandavalue")

  }

  err:=stub.PutState(args[0],[]byte(args[1]))

  iferr!=nil{

  return"",fmt.Errorf("Failedtosetasset:%s",args[0])

  }

  returnargs[1],nil

  }

  //Getreturnsthevalueofthespecifiedassetkey

  funcget(stubshim.ChaincodeStubInterface,args[]string)(string,error){

  iflen(args)!=1{

  return"",fmt.Errorf("Incorrectarguments.Expectingakey")

  }

  value,err:=stub.GetState(args[0])

  iferr!=nil{

  return"",fmt.Errorf("Failedtogetasset:%switherror:%s",args[0],err)

  }

  ifvalue==nil{

  return"",fmt.Errorf("Assetnotfound:%s",args[0])

  }

  returnstring(value),nil