Hyperledger fabric Hyperledger Fabric评估事务是否返回签名的查询结果?

Hyperledger fabric Hyperledger Fabric评估事务是否返回签名的查询结果?,hyperledger-fabric,blockchain,hyperledger,hyperledger-composer,hyperledger-chaincode,Hyperledger Fabric,Blockchain,Hyperledger,Hyperledger Composer,Hyperledger Chaincode,当交易提交到链码时,读写集连同背书对等方的签名一起返回,然后交易建议连同背书信号一起发送到订购服务。我想知道当对链码发出查询请求时会发生什么 假设我要查询资产的世界状态。我称之为evaluateTransaction方法。此方法的输出是否也由认可的同行签名?对于问题的第一段 参考,我们简单地将发送流程分为两个步骤,建议和订购,当您查询链码时,只需要建议而不涉及订购,建议成功后,您将得到结果 关于你问题的第二段 在fabric v1.4.2源代码中,在peer/chaincode/common.g

当交易提交到链码时,读写集连同背书对等方的签名一起返回,然后交易建议连同背书信号一起发送到订购服务。我想知道当对链码发出查询请求时会发生什么


假设我要查询资产的世界状态。我称之为evaluateTransaction方法。此方法的输出是否也由认可的同行签名?

对于问题的第一段

参考,我们简单地将发送流程分为两个步骤,建议和订购,当您查询链码时,只需要建议而不涉及订购,建议成功后,您将得到结果

关于你问题的第二段

在fabric v1.4.2源代码中,在
peer/chaincode/common.go
处,函数
chaincodeInvokeOrQuery
用作chaicode查询或调用,此方法将调用方法
chaincodeInvokeOrQuery

// ChaincodeInvokeOrQuery invokes or queries the chaincode. If successful, the
// INVOKE form prints the ProposalResponse to STDOUT, and the QUERY form prints
// the query result on STDOUT. 
在方法
ChaincodeInvokeOrQuery

// ChaincodeInvokeOrQuery invokes or queries the chaincode. If successful, the
// INVOKE form prints the ProposalResponse to STDOUT, and the QUERY form prints
// the query result on STDOUT. 
这意味着,如果在cli或终端中调用chaincode查询,它将在标准输出上输出结果(资产值),chaincode调用将输出ProposalResponse

但您可以观察到,ChaincodeInvokeOrQuery返回与您所调用的查询或调用相同的格式结果(ProposalResponse),这意味着查询结果也包括背书签名,但我们选择不输出它

func ChaincodeInvokeOrQuery(
    spec *pb.ChaincodeSpec,
    cID string,
    txID string,
    invoke bool,
    signer msp.SigningIdentity,
    certificate tls.Certificate,
    endorserClients []pb.EndorserClient,
    deliverClients []api.PeerDeliverClient,
    bc common.BroadcastClient,
) (*pb.ProposalResponse, error) {
    // Build the ChaincodeInvocationSpec message
    invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}

    creator, err := signer.Serialize()
    if err != nil {
        return nil, errors.WithMessage(err, fmt.Sprintf("error serializing identity for %s", signer.GetIdentifier()))
    }

    funcName := "invoke"
    if !invoke {
        funcName = "query"
    }

    // extract the transient field if it exists
    var tMap map[string][]byte
    if transient != "" {
        if err := json.Unmarshal([]byte(transient), &tMap); err != nil {
            return nil, errors.Wrap(err, "error parsing transient string")
        }
    }

    prop, txid, err := putils.CreateChaincodeProposalWithTxIDAndTransient(pcommon.HeaderType_ENDORSER_TRANSACTION, cID, invocation, creator, txID, tMap)
    if err != nil {
        return nil, errors.WithMessage(err, fmt.Sprintf("error creating proposal for %s", funcName))
    }

    signedProp, err := putils.GetSignedProposal(prop, signer)
    if err != nil {
        return nil, errors.WithMessage(err, fmt.Sprintf("error creating signed proposal for %s", funcName))
    }
    var responses []*pb.ProposalResponse
    for _, endorser := range endorserClients {
        proposalResp, err := endorser.ProcessProposal(context.Background(), signedProp)
        if err != nil {
            return nil, errors.WithMessage(err, fmt.Sprintf("error endorsing %s", funcName))
        }
        responses = append(responses, proposalResp)
    }

    if len(responses) == 0 {
        // this should only happen if some new code has introduced a bug
        return nil, errors.New("no proposal responses received - this might indicate a bug")
    }
    // all responses will be checked when the signed transaction is created.
    // for now, just set this so we check the first response's status
    proposalResp := responses[0]
   
    //till here,query and invoke almost same,if invoke ,it will continue execution 
      ordering step,if query ,it will return 

    if invoke {
        if proposalResp != nil {
            if proposalResp.Response.Status >= shim.ERRORTHRESHOLD {
                return proposalResp, nil
            }
            // assemble a signed transaction (it's an Envelope message)
            env, err := putils.CreateSignedTx(prop, signer, responses...)
            if err != nil {
                return proposalResp, errors.WithMessage(err, "could not assemble transaction")
            }
            var dg *deliverGroup
            var ctx context.Context
            if waitForEvent {
                var cancelFunc context.CancelFunc
                ctx, cancelFunc = context.WithTimeout(context.Background(), waitForEventTimeout)
                defer cancelFunc()

                dg = newDeliverGroup(deliverClients, peerAddresses, certificate, channelID, txid)
                // connect to deliver service on all peers
                err := dg.Connect(ctx)
                if err != nil {
                    return nil, err
                }
            }

            // send the envelope for ordering
            if err = bc.Send(env); err != nil {
                return proposalResp, errors.WithMessage(err, fmt.Sprintf("error sending transaction for %s", funcName))
            }

            if dg != nil && ctx != nil {
                // wait for event that contains the txid from all peers
                err = dg.Wait(ctx)
                if err != nil {
                    return nil, err
                }
            }
        }
    }

    return proposalResp, nil
}