2016-09-15 72 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()); 
      } 
     } 
     }); 
    }); 


} 

無論如何,我知道它遠非完美的方法,但它幫助了我,所以我希望它會幫助你:)

相關問題