2016-09-15 54 views
0

我明白Chaincode调用函数是异步的,除非达成共识完成无法传达台账修改的成功/失败。然而,在调用任何链式代码存根API之前捕获的简单验证错误呢?在验证失败的情况下,应该有一种方法可以将错误返回给调用者。否则,函数的返回值有什么用处。例如Hyperledger面料chaincode调用函数的返回值

func (t *MyChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { 

     if len(args) == 0 { 
      return nil, errors.New("Incorrect number of arguments. Expecting greater than 0") 
     } 

     err = stub.PutState("Somevalue", args[0]) 
     if err != nil { 
      return nil, err 
     } 
     return nil, nil 
} 

现在,如果我在调用时没有向REST API传递参数,我仍然获得成功作为响应。

+0

什么你的问题? –

+0

如果我通过传递0参数通过REST调用上面的函数,我得到以下(类似)响应:“jsonrpc”:“2.0” “result”:{ “status”:“OK” “message”:“ bf4f2e2c-ed0f-4240-aae5-1dc295515b3f” } - “ID”:4 }'理想的情况下,它应该返回错误响应,而不是OK响应 – JavaD

回答

1

{ "jsonrpc": "2.0" "result": { "status": "OK" "message": "bf4f2e2c-ed0f-4240-aae5-1dc295515b3f" }, "id": 4 }。仅意味着交易已成功提交。它没有给出任何指示链代码功能是否成功或失败。

它确实如果你使用Node.js的HFC客户端发送的交易,这是发送事务的推荐方法返回一个错误消息。

+0

我观察一样,显然hyperledger旨在从不Inovke返回错误信息(你也不能拒绝chaincode中的交易)。不直观。 – tribbloid

0

喜来我所知,确实没有办法对一个调用的事务返回取决于chaincode执行的值。看到这个职位的更多细节https://github.com/IBM-Blockchain/ibm-blockchain-issues/issues/85

但是,你可以做的是发射一个事件从你的chaincode的情况下出现错误的执行或如果一切按计划进行。例如,您可以有:

func (t *SimpleChaincode) publish(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { 
... 
//Execution of chaincode finished successfully 
         tosend := "Tx chaincode finished OK." + stub.GetTxID() 
         err = stub.SetEvent("evtsender", []byte(tosend)) 
         if err != nil { 
          return nil, err 
         } 

... 
//transactions cannot return errors this way we have to use an event 
         // return nil, errors.New("No Supplement Found with the given ID") 
         tosend := "Error, No Supplement Found with the given ID" + suplementId + "." + stub.GetTxID() 
         err = stub.SetEvent("evtsender", []byte(tosend)) 
         if err != nil { 
          return nil, err 
         } 
... 

在这些事件中,您可以添加事务标识。因此,在您的SDK应用程序(使用与HFC的NodeJS的情况下),你包的调用事务调用的承诺,并解决它取决于发出的事件拒绝。喜欢的东西:

function invokeWithParams(userObj,invReq) { 

    var txHash="qwe"; 

    return new Promise(function(resolve,reject){ 
     var eh = networkConfig.chain.getEventHub(); 
     // Trigger the invoke transaction 
     var invokeTx = userObj.invoke(invReq); 
     // Print the invoke results 
     invokeTx.on('submitted', function(results) { 
     // Invoke transaction submitted successfully 
     console.log(util.format("\nSuccessfully submitted chaincode invoke transaction: request=%j, response=%j", invReq, results)); 
     txHash = results.uuid; 

     }); 
     invokeTx.on('complete', function(results) { 
     // Invoke transaction completed successfully 
     console.log(util.format("\nSuccessfully completed chaincode invoke transaction: request=%j, response=%j", invReq, results)); 
     // resolve(results); 
     // txHash = results.uuid; 

     }); 
     invokeTx.on('error', function(err) { 
     // Invoke transaction submission failed 
     console.log(util.format("\nFailed to submit chaincode invoke transaction: request=%j, error=%j", invReq, err)); 
     reject(err); 
     }); 

     //Listen to custom events 
     var regid = eh.registerChaincodeEvent(invReq.chaincodeID, "evtsender", function(event) { 
     console.log(util.format("Custom event received, payload: %j\n", event.payload.toString())); 

     if(event.payload.toString().indexOf("Error") >= 0){ 
      let uuid = event.payload.toString().split(".")[1]; 
      eh.unregisterChaincodeEvent(regid); 
      if(uuid === txHash){ //resolve promise only when the current transaction has finished 
      eh.unregisterChaincodeEvent(regid); 
      reject(event.payload.toString()); 
      } 
     } 
     if(event.payload.toString().indexOf("Tx chaincode finished OK") >= 0){ 
      let uuid = event.payload.toString().split(".")[1]; 
      console.log("\nUUID " + uuid); 
      console.log("\ntxHash " + txHash); 
      if(uuid === txHash){ //resolve promise only when the current transaction has finished 
       eh.unregisterChaincodeEvent(regid); 
       resolve(event.payload.toString()); 
      } 
     } 
     }); 
    }); 


} 

无论如何,我知道它远非完美的方法,但它帮助了我,所以我希望它会帮助你:)

相关问题