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 }