github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/protos/utils/commonutils.go (about) 1 /* 2 Copyright IBM Corp. 2016 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 utils 18 19 import ( 20 "errors" 21 "fmt" 22 "time" 23 24 "github.com/golang/protobuf/proto" 25 "github.com/golang/protobuf/ptypes/timestamp" 26 "github.com/hyperledger/fabric/common/crypto" 27 cb "github.com/hyperledger/fabric/protos/common" 28 pb "github.com/hyperledger/fabric/protos/peer" 29 ) 30 31 // MarshalOrPanic serializes a protobuf message and panics if this operation fails. 32 func MarshalOrPanic(pb proto.Message) []byte { 33 data, err := proto.Marshal(pb) 34 if err != nil { 35 panic(err) 36 } 37 return data 38 } 39 40 // Marshal serializes a protobuf message. 41 func Marshal(pb proto.Message) ([]byte, error) { 42 return proto.Marshal(pb) 43 } 44 45 // CreateNonceOrPanic generates a nonce using the common/crypto package 46 // and panics if this operation fails. 47 func CreateNonceOrPanic() []byte { 48 nonce, err := crypto.GetRandomNonce() 49 if err != nil { 50 panic(fmt.Errorf("Cannot generate random nonce: %s", err)) 51 } 52 return nonce 53 } 54 55 // CreateNonce generates a nonce using the common/crypto package. 56 func CreateNonce() ([]byte, error) { 57 nonce, err := crypto.GetRandomNonce() 58 if err != nil { 59 return nil, fmt.Errorf("Cannot generate random nonce: %s", err) 60 } 61 return nonce, nil 62 } 63 64 // UnmarshalPayloadOrPanic unmarshals bytes to a Payload structure or panics on error 65 func UnmarshalPayloadOrPanic(encoded []byte) *cb.Payload { 66 payload, err := UnmarshalPayload(encoded) 67 if err != nil { 68 panic(fmt.Errorf("Error unmarshaling data to payload: %s", err)) 69 } 70 return payload 71 } 72 73 // UnmarshalPayload unmarshals bytes to a Payload structure 74 func UnmarshalPayload(encoded []byte) (*cb.Payload, error) { 75 payload := &cb.Payload{} 76 err := proto.Unmarshal(encoded, payload) 77 if err != nil { 78 return nil, err 79 } 80 return payload, err 81 } 82 83 // UnmarshalEnvelopeOrPanic unmarshals bytes to an Envelope structure or panics on error 84 func UnmarshalEnvelopeOrPanic(encoded []byte) *cb.Envelope { 85 envelope, err := UnmarshalEnvelope(encoded) 86 if err != nil { 87 panic(fmt.Errorf("Error unmarshaling data to envelope: %s", err)) 88 } 89 return envelope 90 } 91 92 // UnmarshalEnvelope unmarshals bytes to an Envelope structure 93 func UnmarshalEnvelope(encoded []byte) (*cb.Envelope, error) { 94 envelope := &cb.Envelope{} 95 err := proto.Unmarshal(encoded, envelope) 96 if err != nil { 97 return nil, err 98 } 99 return envelope, err 100 } 101 102 // UnmarshalEnvelopeOfType unmarshals an envelope of the specified type, including 103 // the unmarshaling the payload data 104 func UnmarshalEnvelopeOfType(envelope *cb.Envelope, headerType cb.HeaderType, message proto.Message) (*cb.ChannelHeader, error) { 105 payload, err := UnmarshalPayload(envelope.Payload) 106 if err != nil { 107 return nil, err 108 } 109 110 if payload.Header == nil { 111 return nil, fmt.Errorf("Envelope must have a Header") 112 } 113 114 chdr, err := UnmarshalChannelHeader(payload.Header.ChannelHeader) 115 if err != nil { 116 return nil, fmt.Errorf("Invalid ChannelHeader") 117 } 118 119 if chdr.Type != int32(headerType) { 120 return nil, fmt.Errorf("Not a tx of type %v", headerType) 121 } 122 123 if err = proto.Unmarshal(payload.Data, message); err != nil { 124 return nil, fmt.Errorf("Error unmarshaling message for type %v: %s", headerType, err) 125 } 126 127 return chdr, nil 128 } 129 130 // ExtractEnvelopeOrPanic retrieves the requested envelope from a given block and unmarshals it -- it panics if either of these operation fail. 131 func ExtractEnvelopeOrPanic(block *cb.Block, index int) *cb.Envelope { 132 envelope, err := ExtractEnvelope(block, index) 133 if err != nil { 134 panic(err) 135 } 136 return envelope 137 } 138 139 // ExtractEnvelope retrieves the requested envelope from a given block and unmarshals it. 140 func ExtractEnvelope(block *cb.Block, index int) (*cb.Envelope, error) { 141 if block.Data == nil { 142 return nil, fmt.Errorf("No data in block") 143 } 144 145 envelopeCount := len(block.Data.Data) 146 if index < 0 || index >= envelopeCount { 147 return nil, fmt.Errorf("Envelope index out of bounds") 148 } 149 marshaledEnvelope := block.Data.Data[index] 150 envelope, err := GetEnvelopeFromBlock(marshaledEnvelope) 151 if err != nil { 152 return nil, fmt.Errorf("Block data does not carry an envelope at index %d: %s", index, err) 153 } 154 return envelope, nil 155 } 156 157 // ExtractPayloadOrPanic retrieves the payload of a given envelope and unmarshals it -- it panics if either of these operations fail. 158 func ExtractPayloadOrPanic(envelope *cb.Envelope) *cb.Payload { 159 payload, err := ExtractPayload(envelope) 160 if err != nil { 161 panic(err) 162 } 163 return payload 164 } 165 166 // ExtractPayload retrieves the payload of a given envelope and unmarshals it. 167 func ExtractPayload(envelope *cb.Envelope) (*cb.Payload, error) { 168 payload := &cb.Payload{} 169 if err := proto.Unmarshal(envelope.Payload, payload); err != nil { 170 return nil, fmt.Errorf("Envelope does not carry a Payload: %s", err) 171 } 172 return payload, nil 173 } 174 175 // MakeChannelHeader creates a ChannelHeader. 176 func MakeChannelHeader(headerType cb.HeaderType, version int32, chainID string, epoch uint64) *cb.ChannelHeader { 177 return &cb.ChannelHeader{ 178 Type: int32(headerType), 179 Version: version, 180 Timestamp: ×tamp.Timestamp{ 181 Seconds: time.Now().Unix(), 182 Nanos: 0, 183 }, 184 ChannelId: chainID, 185 Epoch: epoch, 186 } 187 } 188 189 // MakeSignatureHeader creates a SignatureHeader. 190 func MakeSignatureHeader(serializedCreatorCertChain []byte, nonce []byte) *cb.SignatureHeader { 191 return &cb.SignatureHeader{ 192 Creator: serializedCreatorCertChain, 193 Nonce: nonce, 194 } 195 } 196 197 func SetTxID(channelHeader *cb.ChannelHeader, signatureHeader *cb.SignatureHeader) error { 198 txid, err := ComputeProposalTxID( 199 signatureHeader.Nonce, 200 signatureHeader.Creator, 201 ) 202 if err != nil { 203 return err 204 } 205 channelHeader.TxId = txid 206 return nil 207 } 208 209 // MakePayloadHeader creates a Payload Header. 210 func MakePayloadHeader(ch *cb.ChannelHeader, sh *cb.SignatureHeader) *cb.Header { 211 return &cb.Header{ 212 ChannelHeader: MarshalOrPanic(ch), 213 SignatureHeader: MarshalOrPanic(sh), 214 } 215 } 216 217 // NewSignatureHeaderOrPanic returns a signature header and panics on error. 218 func NewSignatureHeaderOrPanic(signer crypto.LocalSigner) *cb.SignatureHeader { 219 if signer == nil { 220 panic(errors.New("Invalid signer. Must be different from nil.")) 221 } 222 223 signatureHeader, err := signer.NewSignatureHeader() 224 if err != nil { 225 panic(fmt.Errorf("Failed generating a new SignatureHeader [%s]", err)) 226 } 227 return signatureHeader 228 } 229 230 // SignOrPanic signs a message and panics on error. 231 func SignOrPanic(signer crypto.LocalSigner, msg []byte) []byte { 232 if signer == nil { 233 panic(errors.New("Invalid signer. Must be different from nil.")) 234 } 235 236 sigma, err := signer.Sign(msg) 237 if err != nil { 238 panic(fmt.Errorf("Failed generting signature [%s]", err)) 239 } 240 return sigma 241 } 242 243 // UnmarshalChannelHeader returns a ChannelHeader from bytes 244 func UnmarshalChannelHeader(bytes []byte) (*cb.ChannelHeader, error) { 245 chdr := &cb.ChannelHeader{} 246 err := proto.Unmarshal(bytes, chdr) 247 if err != nil { 248 return nil, fmt.Errorf("UnmarshalChannelHeader failed, err %s", err) 249 } 250 251 return chdr, nil 252 } 253 254 // UnmarshalChaincodeID returns a ChaincodeID from bytes 255 func UnmarshalChaincodeID(bytes []byte) (*pb.ChaincodeID, error) { 256 ccid := &pb.ChaincodeID{} 257 err := proto.Unmarshal(bytes, ccid) 258 if err != nil { 259 return nil, fmt.Errorf("UnmarshalChaincodeID failed, err %s", err) 260 } 261 262 return ccid, nil 263 } 264 265 // IsConfigBlock validates whenever given block contains configuration 266 // update transaction 267 func IsConfigBlock(block *cb.Block) bool { 268 envelope, err := ExtractEnvelope(block, 0) 269 if err != nil { 270 return false 271 } 272 273 payload, err := GetPayload(envelope) 274 if err != nil { 275 return false 276 } 277 278 if payload.Header == nil { 279 return false 280 } 281 282 hdr, err := UnmarshalChannelHeader(payload.Header.ChannelHeader) 283 if err != nil { 284 return false 285 } 286 287 return cb.HeaderType(hdr.Type) == cb.HeaderType_CONFIG 288 }