github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/peer/channel/create.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 channel 18 19 import ( 20 "fmt" 21 "io/ioutil" 22 23 "errors" 24 25 "github.com/golang/protobuf/proto" 26 "github.com/hyperledger/fabric/common/configtx" 27 genesisconfig "github.com/hyperledger/fabric/common/configtx/tool/localconfig" 28 localsigner "github.com/hyperledger/fabric/common/localmsp" 29 "github.com/hyperledger/fabric/common/util" 30 mspmgmt "github.com/hyperledger/fabric/msp/mgmt" 31 "github.com/hyperledger/fabric/peer/common" 32 cb "github.com/hyperledger/fabric/protos/common" 33 "github.com/hyperledger/fabric/protos/utils" 34 "github.com/spf13/cobra" 35 ) 36 37 //ConfigTxFileNotFound channel create configuration tx file not found 38 type ConfigTxFileNotFound string 39 40 const createCmdDescription = "Create a channel" 41 42 func (e ConfigTxFileNotFound) Error() string { 43 return fmt.Sprintf("channel create configuration tx file not found %s", string(e)) 44 } 45 46 //InvalidCreateTx invalid channel create transaction 47 type InvalidCreateTx string 48 49 func (e InvalidCreateTx) Error() string { 50 return fmt.Sprintf("Invalid channel create transaction : %s", string(e)) 51 } 52 53 func createCmd(cf *ChannelCmdFactory) *cobra.Command { 54 createCmd := &cobra.Command{ 55 Use: "create", 56 Short: createCmdDescription, 57 Long: createCmdDescription, 58 RunE: func(cmd *cobra.Command, args []string) error { 59 return create(cmd, args, cf) 60 }, 61 } 62 flagList := []string{ 63 "channelID", 64 "file", 65 "timeout", 66 } 67 attachFlags(createCmd, flagList) 68 69 return createCmd 70 } 71 72 func createChannelFromDefaults(cf *ChannelCmdFactory) (*cb.Envelope, error) { 73 signer, err := mspmgmt.GetLocalMSP().GetDefaultSigningIdentity() 74 if err != nil { 75 return nil, err 76 } 77 78 chCrtEnv, err := configtx.MakeChainCreationTransaction(chainID, genesisconfig.SampleConsortiumName, signer) 79 80 if err != nil { 81 return nil, err 82 } 83 84 return chCrtEnv, nil 85 } 86 87 func createChannelFromConfigTx(configTxFileName string) (*cb.Envelope, error) { 88 cftx, err := ioutil.ReadFile(configTxFileName) 89 if err != nil { 90 return nil, ConfigTxFileNotFound(err.Error()) 91 } 92 93 return utils.UnmarshalEnvelope(cftx) 94 } 95 96 func sanityCheckAndSignConfigTx(envConfigUpdate *cb.Envelope) (*cb.Envelope, error) { 97 payload, err := utils.ExtractPayload(envConfigUpdate) 98 if err != nil { 99 return nil, InvalidCreateTx("bad payload") 100 } 101 102 if payload.Header == nil || payload.Header.ChannelHeader == nil { 103 return nil, InvalidCreateTx("bad header") 104 } 105 106 ch, err := utils.UnmarshalChannelHeader(payload.Header.ChannelHeader) 107 if err != nil { 108 return nil, InvalidCreateTx("could not unmarshall channel header") 109 } 110 111 if ch.Type != int32(cb.HeaderType_CONFIG_UPDATE) { 112 return nil, InvalidCreateTx("bad type") 113 } 114 115 if ch.ChannelId == "" { 116 return nil, InvalidCreateTx("empty channel id") 117 } 118 119 if ch.ChannelId != chainID { 120 return nil, InvalidCreateTx(fmt.Sprintf("mismatched channel ID %s != %s", ch.ChannelId, chainID)) 121 } 122 123 configUpdateEnv, err := configtx.UnmarshalConfigUpdateEnvelope(payload.Data) 124 if err != nil { 125 return nil, InvalidCreateTx("Bad config update env") 126 } 127 128 signer := localsigner.NewSigner() 129 sigHeader, err := signer.NewSignatureHeader() 130 if err != nil { 131 return nil, err 132 } 133 134 configSig := &cb.ConfigSignature{ 135 SignatureHeader: utils.MarshalOrPanic(sigHeader), 136 } 137 138 configSig.Signature, err = signer.Sign(util.ConcatenateBytes(configSig.SignatureHeader, configUpdateEnv.ConfigUpdate)) 139 140 configUpdateEnv.Signatures = append(configUpdateEnv.Signatures, configSig) 141 142 return utils.CreateSignedEnvelope(cb.HeaderType_CONFIG_UPDATE, chainID, signer, configUpdateEnv, 0, 0) 143 } 144 145 func sendCreateChainTransaction(cf *ChannelCmdFactory) error { 146 var err error 147 var chCrtEnv *cb.Envelope 148 149 if channelTxFile != "" { 150 if chCrtEnv, err = createChannelFromConfigTx(channelTxFile); err != nil { 151 return err 152 } 153 } else { 154 if chCrtEnv, err = createChannelFromDefaults(cf); err != nil { 155 return err 156 } 157 } 158 159 if chCrtEnv, err = sanityCheckAndSignConfigTx(chCrtEnv); err != nil { 160 return err 161 } 162 163 var broadcastClient common.BroadcastClient 164 broadcastClient, err = cf.BroadcastFactory() 165 if err != nil { 166 return fmt.Errorf("Error getting broadcast client: %s", err) 167 } 168 169 defer broadcastClient.Close() 170 err = broadcastClient.Send(chCrtEnv) 171 172 return err 173 } 174 175 func executeCreate(cf *ChannelCmdFactory) error { 176 var err error 177 178 if err = sendCreateChainTransaction(cf); err != nil { 179 return err 180 } 181 182 var block *cb.Block 183 if block, err = getGenesisBlock(cf); err != nil { 184 return err 185 } 186 187 b, err := proto.Marshal(block) 188 if err != nil { 189 return err 190 } 191 192 file := chainID + ".block" 193 if err = ioutil.WriteFile(file, b, 0644); err != nil { 194 return err 195 } 196 197 return nil 198 } 199 200 func create(cmd *cobra.Command, args []string, cf *ChannelCmdFactory) error { 201 //the global chainID filled by the "-c" command 202 if chainID == common.UndefinedParamValue { 203 return errors.New("Must supply channel ID") 204 } 205 206 var err error 207 if cf == nil { 208 cf, err = InitCmdFactory(EndorserNotRequired, OrdererRequired) 209 if err != nil { 210 return err 211 } 212 } 213 return executeCreate(cf) 214 }