/* Copyright IBM Corp. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ package chaincode import ( "context" "encoding/json" "fmt" "io" "github.com/golang/protobuf/proto" pb "github.com/hyperledger/fabric-protos-go/peer" "github.com/hyperledger/fabric/common/policydsl" "github.com/hyperledger/fabric/internal/peer/chaincode" "github.com/hyperledger/fabric/protoutil" "github.com/pkg/errors" "google.golang.org/grpc" ) // EndorserClient defines the interface for sending a proposal // to an endorser type EndorserClient interface { ProcessProposal(ctx context.Context, in *pb.SignedProposal, opts ...grpc.CallOption) (*pb.ProposalResponse, error) } // PeerDeliverClient defines the interface for a peer deliver client type PeerDeliverClient interface { Deliver(ctx context.Context, opts ...grpc.CallOption) (pb.Deliver_DeliverClient, error) DeliverFiltered(ctx context.Context, opts ...grpc.CallOption) (pb.Deliver_DeliverClient, error) } // Signer defines the interface needed for signing messages type Signer interface { Sign(msg []byte) ([]byte, error) Serialize() ([]byte, error) } // Writer defines the interface needed for writing a file type Writer interface { WriteFile(string, string, []byte) error } func signProposal(proposal *pb.Proposal, signer Signer) (*pb.SignedProposal, error) { // check for nil argument if proposal == nil { return nil, errors.New("proposal cannot be nil") } if signer == nil { return nil, errors.New("signer cannot be nil") } proposalBytes, err := proto.Marshal(proposal) if err != nil { return nil, errors.Wrap(err, "error marshaling proposal") } signature, err := signer.Sign(proposalBytes) if err != nil { return nil, err } return &pb.SignedProposal{ ProposalBytes: proposalBytes, Signature: signature, }, nil } func createPolicyBytes(signaturePolicy, channelConfigPolicy string) ([]byte, error) { if signaturePolicy == "" && channelConfigPolicy == "" { // no policy, no problem return nil, nil } if signaturePolicy != "" && channelConfigPolicy != "" { // mo policies, mo problems return nil, errors.New("cannot specify both \"--signature-policy\" and \"--channel-config-policy\"") } var applicationPolicy *pb.ApplicationPolicy if signaturePolicy != "" { signaturePolicyEnvelope, err := policydsl.FromString(signaturePolicy) if err != nil { return nil, errors.Errorf("invalid signature policy: %s", signaturePolicy) } applicationPolicy = &pb.ApplicationPolicy{ Type: &pb.ApplicationPolicy_SignaturePolicy{ SignaturePolicy: signaturePolicyEnvelope, }, } } if channelConfigPolicy != "" { applicationPolicy = &pb.ApplicationPolicy{ Type: &pb.ApplicationPolicy_ChannelConfigPolicyReference{ ChannelConfigPolicyReference: channelConfigPolicy, }, } } policyBytes := protoutil.MarshalOrPanic(applicationPolicy) return policyBytes, nil } func createCollectionConfigPackage(collectionsConfigFile string) (*pb.CollectionConfigPackage, error) { var ccp *pb.CollectionConfigPackage if collectionsConfigFile != "" { var err error ccp, _, err = chaincode.GetCollectionConfigFromFile(collectionsConfigFile) if err != nil { return nil, errors.WithMessagef(err, "invalid collection configuration in file %s", collectionsConfigFile) } } return ccp, nil } func printResponseAsJSON(proposalResponse *pb.ProposalResponse, msg proto.Message, out io.Writer) error { err := proto.Unmarshal(proposalResponse.Response.Payload, msg) if err != nil { return errors.Wrapf(err, "failed to unmarshal proposal response's response payload as type %T", msg) } bytes, err := json.MarshalIndent(msg, "", "\t") if err != nil { return errors.Wrap(err, "failed to marshal output") } fmt.Fprintf(out, "%s\n", string(bytes)) return nil }