github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/peer/chaincode/package.go (about) 1 /* 2 Copyright IBM Corp. 2017 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package chaincode 18 19 import ( 20 "fmt" 21 22 "io/ioutil" 23 24 "github.com/golang/protobuf/proto" 25 "github.com/spf13/cobra" 26 27 "github.com/hyperledger/fabric/common/cauthdsl" 28 "github.com/hyperledger/fabric/core/common/ccpackage" 29 "github.com/hyperledger/fabric/msp" 30 mspmgmt "github.com/hyperledger/fabric/msp/mgmt" 31 pcommon "github.com/hyperledger/fabric/protos/common" 32 pb "github.com/hyperledger/fabric/protos/peer" 33 "github.com/hyperledger/fabric/protos/utils" 34 ) 35 36 var chaincodePackageCmd *cobra.Command 37 var createSignedCCDepSpec bool 38 var signCCDepSpec bool 39 var instantiationPolicy string 40 41 const packageCmdName = "package" 42 const packageDesc = "Package the specified chaincode into a deployment spec." 43 44 type ccDepSpecFactory func(spec *pb.ChaincodeSpec) (*pb.ChaincodeDeploymentSpec, error) 45 46 func defaultCDSFactory(spec *pb.ChaincodeSpec) (*pb.ChaincodeDeploymentSpec, error) { 47 return getChaincodeDeploymentSpec(spec, true) 48 } 49 50 // deployCmd returns the cobra command for Chaincode Deploy 51 func packageCmd(cf *ChaincodeCmdFactory, cdsFact ccDepSpecFactory) *cobra.Command { 52 chaincodePackageCmd = &cobra.Command{ 53 Use: "package", 54 Short: packageDesc, 55 Long: packageDesc, 56 ValidArgs: []string{"1"}, 57 RunE: func(cmd *cobra.Command, args []string) error { 58 if len(args) != 1 { 59 return fmt.Errorf("output file not specified or invalid number of args (filename should be the only arg)") 60 } 61 //UT will supply its own mock factory 62 if cdsFact == nil { 63 cdsFact = defaultCDSFactory 64 } 65 return chaincodePackage(cmd, args, cdsFact, cf) 66 }, 67 } 68 flagList := []string{ 69 "lang", 70 "ctor", 71 "path", 72 "name", 73 "version", 74 } 75 attachFlags(chaincodePackageCmd, flagList) 76 77 chaincodePackageCmd.Flags().BoolVarP(&createSignedCCDepSpec, "cc-package", "s", false, "create CC deployment spec for owner endorsements instead of raw CC deployment spec") 78 chaincodePackageCmd.Flags().BoolVarP(&signCCDepSpec, "sign", "S", false, "if creating CC deployment spec package for owner endorsements, also sign it with local MSP") 79 chaincodePackageCmd.Flags().StringVarP(&instantiationPolicy, "instantiate-policy", "i", "", "instantiation policy for the chaincode") 80 81 return chaincodePackageCmd 82 } 83 84 func getInstantiationPolicy(policy string) (*pcommon.SignaturePolicyEnvelope, error) { 85 p, err := cauthdsl.FromString(policy) 86 if err != nil { 87 return nil, fmt.Errorf("Invalid policy %s, err %s", policy, err) 88 } 89 return p, nil 90 } 91 92 //getChaincodeInstallPackage returns either a raw ChaincodeDeploymentSpec or 93 //a Envelope with ChaincodeDeploymentSpec and (optional) signature 94 func getChaincodeInstallPackage(cds *pb.ChaincodeDeploymentSpec, cf *ChaincodeCmdFactory) ([]byte, error) { 95 //this can be raw ChaincodeDeploymentSpec or Envelope with signatures 96 var objToWrite proto.Message 97 98 //start with default cds 99 objToWrite = cds 100 101 var err error 102 103 var owner msp.SigningIdentity 104 105 //create a chaincode package... 106 if createSignedCCDepSpec { 107 //...and optionally get the signer so the package can be signed 108 //by the local MSP. This package can be given to other owners 109 //to sign using "peer chaincode sign <package file>" 110 if signCCDepSpec { 111 if cf.Signer == nil { 112 return nil, fmt.Errorf("Error getting signer") 113 } 114 owner = cf.Signer 115 } 116 } 117 118 ip := instantiationPolicy 119 if ip == "" { 120 //if an instantiation policy is not given, default 121 //to "admin must sign chaincode instantiation proposals" 122 mspid, err := mspmgmt.GetLocalMSP().GetIdentifier() 123 if err != nil { 124 return nil, err 125 } 126 ip = "AND('" + mspid + ".admin')" 127 } 128 129 sp, err := getInstantiationPolicy(ip) 130 if err != nil { 131 return nil, err 132 } 133 134 //we get the Envelope of type CHAINCODE_PACKAGE 135 objToWrite, err = ccpackage.OwnerCreateSignedCCDepSpec(cds, sp, owner) 136 if err != nil { 137 return nil, err 138 } 139 140 //convert the proto object to bytes 141 bytesToWrite, err := proto.Marshal(objToWrite) 142 if err != nil { 143 return nil, fmt.Errorf("Error marshalling chaincode package : %s", err) 144 } 145 146 return bytesToWrite, nil 147 } 148 149 // chaincodePackage creates the chaincode package. On success, the chaincode name 150 // (hash) is printed to STDOUT for use by subsequent chaincode-related CLI 151 // commands. 152 func chaincodePackage(cmd *cobra.Command, args []string, cdsFact ccDepSpecFactory, cf *ChaincodeCmdFactory) error { 153 if cdsFact == nil { 154 return fmt.Errorf("Error chaincode deployment spec factory not specified") 155 } 156 157 var err error 158 if cf == nil { 159 cf, err = InitCmdFactory(false, false) 160 if err != nil { 161 return err 162 } 163 } 164 spec, err := getChaincodeSpec(cmd) 165 if err != nil { 166 return err 167 } 168 169 cds, err := cdsFact(spec) 170 if err != nil { 171 return fmt.Errorf("Error getting chaincode code %s: %s", chainFuncName, err) 172 } 173 174 var bytesToWrite []byte 175 if createSignedCCDepSpec { 176 bytesToWrite, err = getChaincodeInstallPackage(cds, cf) 177 if err != nil { 178 return err 179 } 180 } else { 181 bytesToWrite = utils.MarshalOrPanic(cds) 182 } 183 184 logger.Debugf("Packaged chaincode into deployment spec of size <%d>, with args = %v", len(bytesToWrite), args) 185 fileToWrite := args[0] 186 err = ioutil.WriteFile(fileToWrite, bytesToWrite, 0700) 187 if err != nil { 188 logger.Errorf("Failed writing deployment spec to file [%s]: [%s]", fileToWrite, err) 189 return err 190 } 191 192 return err 193 }