当前位置:   article > 正文

hyperledger fabric 1.0 源码分析之peer chaincode invoke or query_fabric的invoke命令和query命令的区别

fabric的invoke命令和query命令的区别

概述

peer chaincode invoke命令用于调用链码(chaincode)

peer chaincode query命令与invoke实现基本相同,区别在于提交并处理Proposal后,不再创建交易以及广播交易。

实现

命令的定义

  1. func invokeCmd(cf *ChaincodeCmdFactory) *cobra.Command {
  2. chaincodeInvokeCmd = &cobra.Command{
  3. Use: "invoke",
  4. Short: fmt.Sprintf("Invoke the specified %s.", chainFuncName),
  5. Long: fmt.Sprintf("Invoke the specified %s. It will try to commit the endorsed transaction to the network.", chainFuncName),
  6. ValidArgs: []string{"1"},
  7. RunE: func(cmd *cobra.Command, args []string) error {
  8. //执行命令的具体实现
  9. return chaincodeInvoke(cmd, args, cf)
  10. },
  11. }
  12. flagList := []string{
  13. "name",
  14. "ctor",
  15. "channelID",
  16. }
  17. //invoke添加命令标记
  18. attachFlags(chaincodeInvokeCmd, flagList)
  19. return chaincodeInvokeCmd
  20. }

chaincodeInvoke实现

invoke或query子命令入口

  1. func chaincodeInvoke(cmd *cobra.Command, args []string, cf *ChaincodeCmdFactory) error {
  2. var err error
  3. if cf == nil {
  4. //获取ChaincodeCmdFactory,已多次介绍,这里不在介绍
  5. cf, err = InitCmdFactory(true, true)
  6. if err != nil {
  7. return err
  8. }
  9. }
  10. defer cf.BroadcastClient.Close()
  11. //chaincode invoke 和 chaincode query都执行这个方法
  12. return chaincodeInvokeOrQuery(cmd, args, true, cf)
  13. }

chaincodeInvokeOrQuery实现

invoke和query具体实现方法

  1. func chaincodeInvokeOrQuery(cmd *cobra.Command, args []string, invoke bool, cf *ChaincodeCmdFactory) (err error) {
  2. //获取ChaincodeSpec
  3. spec, err := getChaincodeSpec(cmd)
  4. if err != nil {
  5. return err
  6. }
  7. //调用或查询链码,成功返回提案响应ProposalResponse
  8. proposalResp, err := ChaincodeInvokeOrQuery(
  9. spec, //ChaincodeSpec
  10. chainID, //链id
  11. invoke, //invoke时为true,query是为false
  12. cf.Signer, //ChaincodeCmdFactory.Signer msp签名身份
  13. cf.EndorserClient, //背书端
  14. cf.BroadcastClient) //广播端
  15. if err != nil {
  16. return fmt.Errorf("%s - %v", err, proposalResp)
  17. }
  18. if invoke {
  19. //invoke操作
  20. //shim.ERROR默认值500
  21. //putils.GetProposalResponsePayload()获取提案响应中的payload
  22. //putils.GetChaincodeAction()获取读写集
  23. if proposalResp.Response.Status >= shim.ERROR {
  24. logger.Debugf("ESCC invoke result: %v", proposalResp)
  25. pRespPayload, err := putils.GetProposalResponsePayload(proposalResp.Payload)
  26. if err != nil {
  27. return fmt.Errorf("Error while unmarshaling proposal response payload: %s", err)
  28. }
  29. ca, err := putils.GetChaincodeAction(pRespPayload.Extension)
  30. if err != nil {
  31. return fmt.Errorf("Error while unmarshaling chaincode action: %s", err)
  32. }
  33. logger.Warningf("Endorsement failure during invoke. chaincode result: %v", ca.Response)
  34. } else {
  35. logger.Debugf("ESCC invoke result: %v", proposalResp)
  36. pRespPayload, err := putils.GetProposalResponsePayload(proposalResp.Payload)
  37. if err != nil {
  38. return fmt.Errorf("Error while unmarshaling proposal response payload: %s", err)
  39. }
  40. ca, err := putils.GetChaincodeAction(pRespPayload.Extension)
  41. if err != nil {
  42. return fmt.Errorf("Error while unmarshaling chaincode action: %s", err)
  43. }
  44. logger.Infof("Chaincode invoke successful. result: %v", ca.Response)
  45. }
  46. } else {
  47. //query操作
  48. //查询成功返回结果
  49. if proposalResp == nil {
  50. return fmt.Errorf("Error query %s by endorsing: %s", chainFuncName, err)
  51. }
  52. if chaincodeQueryRaw {
  53. if chaincodeQueryHex {
  54. return fmt.Errorf("Options --raw (-r) and --hex (-x) are not compatible")
  55. }
  56. fmt.Print("Query Result (Raw): ")
  57. os.Stdout.Write(proposalResp.Response.Payload)
  58. } else {
  59. if chaincodeQueryHex {
  60. fmt.Printf("Query Result: %x\n", proposalResp.Response.Payload)
  61. } else {
  62. fmt.Printf("Query Result: %s\n", string(proposalResp.Response.Payload))
  63. }
  64. }
  65. }
  66. return nil
  67. }

方法详解

getChaincodeSpec()

  1. func getChaincodeSpec(cmd *cobra.Command) (*pb.ChaincodeSpec, error) {
  2. spec := &pb.ChaincodeSpec{}
  3. //checkChaincodeCmdParams进行参数验证
  4. //验证chinacodename、版本、escc、vscc、policy、参数(chaincodeCtorJSON)是否定义
  5. if err := checkChaincodeCmdParams(cmd); err != nil {
  6. return spec, err
  7. }
  8. // Build the spec
  9. input := &pb.ChaincodeInput{}
  10. if err := json.Unmarshal([]byte(chaincodeCtorJSON), &input); err != nil {
  11. return spec, fmt.Errorf("Chaincode argument error: %s", err)
  12. }
  13. //语言验证,链码不允许是java
  14. chaincodeLang = strings.ToUpper(chaincodeLang)
  15. if pb.ChaincodeSpec_Type_value[chaincodeLang] == int32(pb.ChaincodeSpec_JAVA) {
  16. return nil, fmt.Errorf("Java chaincode is work-in-progress and disabled")
  17. }
  18. //返回ChaincodeSpec
  19. spec = &pb.ChaincodeSpec{
  20. Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value[chaincodeLang]),
  21. ChaincodeId: &pb.ChaincodeID{Path: chaincodePath, Name: chaincodeName, Version: chaincodeVersion},
  22. Input: input,
  23. }
  24. return spec, nil
  25. }

ChaincodeInvokeOrQuery()

  1. func ChaincodeInvokeOrQuery(
  2. spec *pb.ChaincodeSpec,
  3. cID string,
  4. invoke bool,
  5. signer msp.SigningIdentity,
  6. endorserClient pb.EndorserClient,
  7. bc common.BroadcastClient,
  8. ) (*pb.ProposalResponse, error) {
  9. // Build the ChaincodeInvocationSpec message
  10. invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}
  11. if customIDGenAlg != common.UndefinedParamValue {
  12. invocation.IdGenerationAlg = customIDGenAlg
  13. }
  14. //获取签名身份(所有人)
  15. creator, err := signer.Serialize()
  16. if err != nil {
  17. return nil, fmt.Errorf("Error serializing identity for %s: %s", signer.GetIdentifier(), err)
  18. }
  19. funcName := "invoke"
  20. if !invoke {
  21. funcName = "query"
  22. }
  23. //创建Proposal
  24. var prop *pb.Proposal
  25. prop, _, err = putils.CreateProposalFromCIS(pcommon.HeaderType_ENDORSER_TRANSACTION, cID, invocation, creator)
  26. if err != nil {
  27. return nil, fmt.Errorf("Error creating proposal %s: %s", funcName, err)
  28. }
  29. //Proposal签名
  30. var signedProp *pb.SignedProposal
  31. signedProp, err = putils.GetSignedProposal(prop, signer)
  32. if err != nil {
  33. return nil, fmt.Errorf("Error creating signed proposal %s: %s", funcName, err)
  34. }
  35. //提交处理签名提案signedProp
  36. var proposalResp *pb.ProposalResponse
  37. proposalResp, err = endorserClient.ProcessProposal(context.Background(), signedProp)
  38. if err != nil {
  39. return nil, fmt.Errorf("Error endorsing %s: %s", funcName, err)
  40. }
  41. //invoke操作执行,query操作直接返回
  42. if invoke {
  43. if proposalResp != nil {
  44. if proposalResp.Response.Status >= shim.ERROR {
  45. return proposalResp, nil
  46. }
  47. // assemble a signed transaction (it's an Envelope message)
  48. //创建签名交易
  49. env, err := putils.CreateSignedTx(prop, signer, proposalResp)
  50. if err != nil {
  51. return proposalResp, fmt.Errorf("Could not assemble transaction, err %s", err)
  52. }
  53. // send the envelope for ordering
  54. if err = bc.Send(env); err != nil {
  55. return proposalResp, fmt.Errorf("Error sending transaction %s: %s", funcName, err)
  56. }
  57. }
  58. }
  59. return proposalResp, nil
  60. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/225383
推荐阅读
相关标签
  

闽ICP备14008679号