github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/internal/peer/lifecycle/chaincode/queryinstalled.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package chaincode
     8  
     9  import (
    10  	"context"
    11  	"fmt"
    12  	"io"
    13  	"os"
    14  	"strings"
    15  
    16  	"github.com/golang/protobuf/proto"
    17  	"github.com/hechain20/hechain/bccsp"
    18  	"github.com/hechain20/hechain/protoutil"
    19  	cb "github.com/hyperledger/fabric-protos-go/common"
    20  	pb "github.com/hyperledger/fabric-protos-go/peer"
    21  	lb "github.com/hyperledger/fabric-protos-go/peer/lifecycle"
    22  	"github.com/pkg/errors"
    23  	"github.com/spf13/cobra"
    24  	"github.com/spf13/viper"
    25  )
    26  
    27  // InstalledQuerier holds the dependencies needed to query
    28  // the installed chaincodes
    29  type InstalledQuerier struct {
    30  	Command        *cobra.Command
    31  	Input          *InstalledQueryInput
    32  	EndorserClient EndorserClient
    33  	Signer         Signer
    34  	Writer         io.Writer
    35  }
    36  
    37  type InstalledQueryInput struct {
    38  	OutputFormat string
    39  }
    40  
    41  // QueryInstalledCmd returns the cobra command for listing
    42  // the installed chaincodes
    43  func QueryInstalledCmd(i *InstalledQuerier, cryptoProvider bccsp.BCCSP) *cobra.Command {
    44  	chaincodeQueryInstalledCmd := &cobra.Command{
    45  		Use:   "queryinstalled",
    46  		Short: "Query the installed chaincodes on a peer.",
    47  		Long:  "Query the installed chaincodes on a peer.",
    48  		RunE: func(cmd *cobra.Command, args []string) error {
    49  			if i == nil {
    50  				ccInput := &ClientConnectionsInput{
    51  					CommandName:           cmd.Name(),
    52  					EndorserRequired:      true,
    53  					PeerAddresses:         peerAddresses,
    54  					TLSRootCertFiles:      tlsRootCertFiles,
    55  					ConnectionProfilePath: connectionProfilePath,
    56  					TargetPeer:            targetPeer,
    57  					TLSEnabled:            viper.GetBool("peer.tls.enabled"),
    58  				}
    59  
    60  				cc, err := NewClientConnections(ccInput, cryptoProvider)
    61  				if err != nil {
    62  					return err
    63  				}
    64  
    65  				iqInput := &InstalledQueryInput{
    66  					OutputFormat: output,
    67  				}
    68  
    69  				// queryinstalled only supports one peer connection,
    70  				// which is why we only wire in the first endorser
    71  				// client
    72  				i = &InstalledQuerier{
    73  					Command:        cmd,
    74  					EndorserClient: cc.EndorserClients[0],
    75  					Input:          iqInput,
    76  					Signer:         cc.Signer,
    77  					Writer:         os.Stdout,
    78  				}
    79  			}
    80  			return i.Query()
    81  		},
    82  	}
    83  
    84  	flagList := []string{
    85  		"peerAddresses",
    86  		"tlsRootCertFiles",
    87  		"connectionProfile",
    88  		"targetPeer",
    89  		"output",
    90  	}
    91  	attachFlags(chaincodeQueryInstalledCmd, flagList)
    92  
    93  	return chaincodeQueryInstalledCmd
    94  }
    95  
    96  // Query returns the chaincodes installed on a peer
    97  func (i *InstalledQuerier) Query() error {
    98  	if i.Command != nil {
    99  		// Parsing of the command line is done so silence cmd usage
   100  		i.Command.SilenceUsage = true
   101  	}
   102  
   103  	proposal, err := i.createProposal()
   104  	if err != nil {
   105  		return errors.WithMessage(err, "failed to create proposal")
   106  	}
   107  
   108  	signedProposal, err := signProposal(proposal, i.Signer)
   109  	if err != nil {
   110  		return errors.WithMessage(err, "failed to create signed proposal")
   111  	}
   112  
   113  	proposalResponse, err := i.EndorserClient.ProcessProposal(context.Background(), signedProposal)
   114  	if err != nil {
   115  		return errors.WithMessage(err, "failed to endorse proposal")
   116  	}
   117  
   118  	if proposalResponse == nil {
   119  		return errors.New("received nil proposal response")
   120  	}
   121  
   122  	if proposalResponse.Response == nil {
   123  		return errors.New("received proposal response with nil response")
   124  	}
   125  
   126  	if proposalResponse.Response.Status != int32(cb.Status_SUCCESS) {
   127  		return errors.Errorf("query failed with status: %d - %s", proposalResponse.Response.Status, proposalResponse.Response.Message)
   128  	}
   129  
   130  	if strings.ToLower(i.Input.OutputFormat) == "json" {
   131  		return printResponseAsJSON(proposalResponse, &lb.QueryInstalledChaincodesResult{}, i.Writer)
   132  	}
   133  	return i.printResponse(proposalResponse)
   134  }
   135  
   136  // printResponse prints the information included in the response
   137  // from the server.
   138  func (i *InstalledQuerier) printResponse(proposalResponse *pb.ProposalResponse) error {
   139  	qicr := &lb.QueryInstalledChaincodesResult{}
   140  	err := proto.Unmarshal(proposalResponse.Response.Payload, qicr)
   141  	if err != nil {
   142  		return errors.Wrap(err, "failed to unmarshal proposal response's response payload")
   143  	}
   144  	fmt.Fprintln(i.Writer, "Installed chaincodes on peer:")
   145  	for _, chaincode := range qicr.InstalledChaincodes {
   146  		fmt.Fprintf(i.Writer, "Package ID: %s, Label: %s\n", chaincode.PackageId, chaincode.Label)
   147  	}
   148  	return nil
   149  }
   150  
   151  func (i *InstalledQuerier) createProposal() (*pb.Proposal, error) {
   152  	args := &lb.QueryInstalledChaincodesArgs{}
   153  
   154  	argsBytes, err := proto.Marshal(args)
   155  	if err != nil {
   156  		return nil, errors.Wrap(err, "failed to marshal args")
   157  	}
   158  
   159  	ccInput := &pb.ChaincodeInput{
   160  		Args: [][]byte{[]byte("QueryInstalledChaincodes"), argsBytes},
   161  	}
   162  
   163  	cis := &pb.ChaincodeInvocationSpec{
   164  		ChaincodeSpec: &pb.ChaincodeSpec{
   165  			ChaincodeId: &pb.ChaincodeID{Name: lifecycleName},
   166  			Input:       ccInput,
   167  		},
   168  	}
   169  
   170  	signerSerialized, err := i.Signer.Serialize()
   171  	if err != nil {
   172  		return nil, errors.WithMessage(err, "failed to serialize identity")
   173  	}
   174  
   175  	proposal, _, err := protoutil.CreateProposalFromCIS(cb.HeaderType_ENDORSER_TRANSACTION, "", cis, signerSerialized)
   176  	if err != nil {
   177  		return nil, errors.WithMessage(err, "failed to create ChaincodeInvocationSpec proposal")
   178  	}
   179  
   180  	return proposal, nil
   181  }