6 Star 44 Fork 25

Hyperledger / fabric

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
getinstalledpackage.go 5.80 KB
一键复制 编辑 原始数据 按行查看 历史
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package chaincode
import (
"context"
"path/filepath"
"github.com/golang/protobuf/proto"
cb "github.com/hyperledger/fabric-protos-go/common"
pb "github.com/hyperledger/fabric-protos-go/peer"
lb "github.com/hyperledger/fabric-protos-go/peer/lifecycle"
"github.com/hyperledger/fabric/bccsp"
"github.com/hyperledger/fabric/core/chaincode/persistence"
"github.com/hyperledger/fabric/protoutil"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
// InstalledPackageGetter holds the dependencies needed to retrieve
// an installed chaincode package from a peer.
type InstalledPackageGetter struct {
Command *cobra.Command
Input *GetInstalledPackageInput
EndorserClient EndorserClient
Signer Signer
Writer Writer
}
// GetInstalledPackageInput holds all of the input parameters for
// getting an installed chaincode package from a peer.
type GetInstalledPackageInput struct {
PackageID string
OutputDirectory string
}
// Validate checks that the required parameters are provided.
func (i *GetInstalledPackageInput) Validate() error {
if i.PackageID == "" {
return errors.New("The required parameter 'package-id' is empty. Rerun the command with --package-id flag")
}
return nil
}
// GetInstalledPackageCmd returns the cobra command for getting an
// installed chaincode package from a peer.
func GetInstalledPackageCmd(i *InstalledPackageGetter, cryptoProvider bccsp.BCCSP) *cobra.Command {
chaincodeGetInstalledPackageCmd := &cobra.Command{
Use: "getinstalledpackage [outputfile]",
Short: "Get an installed chaincode package from a peer.",
Long: "Get an installed chaincode package from a peer.",
RunE: func(cmd *cobra.Command, args []string) error {
if i == nil {
ccInput := &ClientConnectionsInput{
CommandName: cmd.Name(),
EndorserRequired: true,
ChannelID: channelID,
PeerAddresses: peerAddresses,
TLSRootCertFiles: tlsRootCertFiles,
ConnectionProfilePath: connectionProfilePath,
TLSEnabled: viper.GetBool("peer.tls.enabled"),
}
cc, err := NewClientConnections(ccInput, cryptoProvider)
if err != nil {
return err
}
gipInput := &GetInstalledPackageInput{
PackageID: packageID,
OutputDirectory: outputDirectory,
}
// getinstalledpackage only supports one peer connection,
// which is why we only wire in the first endorser
// client
i = &InstalledPackageGetter{
Command: cmd,
EndorserClient: cc.EndorserClients[0],
Input: gipInput,
Signer: cc.Signer,
Writer: &persistence.FilesystemIO{},
}
}
return i.Get()
},
}
flagList := []string{
"peerAddresses",
"tlsRootCertFiles",
"connectionProfile",
"package-id",
"output-directory",
}
attachFlags(chaincodeGetInstalledPackageCmd, flagList)
return chaincodeGetInstalledPackageCmd
}
// Get retrieves the installed chaincode package from a peer.
func (i *InstalledPackageGetter) Get() error {
if i.Command != nil {
// Parsing of the command line is done so silence cmd usage
i.Command.SilenceUsage = true
}
if err := i.Input.Validate(); err != nil {
return err
}
proposal, err := i.createProposal()
if err != nil {
return errors.WithMessage(err, "failed to create proposal")
}
signedProposal, err := signProposal(proposal, i.Signer)
if err != nil {
return errors.WithMessage(err, "failed to create signed proposal")
}
proposalResponse, err := i.EndorserClient.ProcessProposal(context.Background(), signedProposal)
if err != nil {
return errors.WithMessage(err, "failed to endorse proposal")
}
if proposalResponse == nil {
return errors.New("received nil proposal response")
}
if proposalResponse.Response == nil {
return errors.New("received proposal response with nil response")
}
if proposalResponse.Response.Status != int32(cb.Status_SUCCESS) {
return errors.Errorf("proposal failed with status: %d - %s", proposalResponse.Response.Status, proposalResponse.Response.Message)
}
return i.writePackage(proposalResponse)
}
func (i *InstalledPackageGetter) writePackage(proposalResponse *pb.ProposalResponse) error {
result := &lb.GetInstalledChaincodePackageResult{}
err := proto.Unmarshal(proposalResponse.Response.Payload, result)
if err != nil {
return errors.Wrap(err, "failed to unmarshal proposal response's response payload")
}
outputFile := filepath.Join(i.Input.OutputDirectory, i.Input.PackageID+".tar.gz")
dir, name := filepath.Split(outputFile)
// translate dir into absolute path
if dir, err = filepath.Abs(dir); err != nil {
return err
}
err = i.Writer.WriteFile(dir, name, result.ChaincodeInstallPackage)
if err != nil {
err = errors.Wrapf(err, "failed to write chaincode package to %s", outputFile)
logger.Error(err.Error())
return err
}
return nil
}
func (i *InstalledPackageGetter) createProposal() (*pb.Proposal, error) {
args := &lb.GetInstalledChaincodePackageArgs{
PackageId: i.Input.PackageID,
}
argsBytes, err := proto.Marshal(args)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal args")
}
ccInput := &pb.ChaincodeInput{
Args: [][]byte{[]byte("GetInstalledChaincodePackage"), argsBytes},
}
cis := &pb.ChaincodeInvocationSpec{
ChaincodeSpec: &pb.ChaincodeSpec{
ChaincodeId: &pb.ChaincodeID{Name: lifecycleName},
Input: ccInput,
},
}
signerSerialized, err := i.Signer.Serialize()
if err != nil {
return nil, errors.WithMessage(err, "failed to serialize identity")
}
proposal, _, err := protoutil.CreateProposalFromCIS(cb.HeaderType_ENDORSER_TRANSACTION, "", cis, signerSerialized)
if err != nil {
return nil, errors.WithMessage(err, "failed to create ChaincodeInvocationSpec proposal")
}
return proposal, nil
}
1
https://gitee.com/hyperledger/fabric.git
git@gitee.com:hyperledger/fabric.git
hyperledger
fabric
fabric
v2.1.1

搜索帮助