github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/examples/chaincode/go/asset_management_interactive/app1/app1_internal.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 main 18 19 import ( 20 "encoding/base64" 21 "errors" 22 "fmt" 23 24 "github.com/golang/protobuf/proto" 25 "github.com/hyperledger/fabric/common/util" 26 "github.com/hyperledger/fabric/core/chaincode" 27 "github.com/hyperledger/fabric/core/chaincode/platforms" 28 "github.com/hyperledger/fabric/core/config" 29 "github.com/hyperledger/fabric/core/container" 30 "github.com/hyperledger/fabric/core/crypto" 31 "github.com/hyperledger/fabric/core/peer" 32 pb "github.com/hyperledger/fabric/protos" 33 "github.com/op/go-logging" 34 "github.com/spf13/viper" 35 "golang.org/x/net/context" 36 ) 37 38 var ( 39 confidentialityOn bool 40 41 chaincodeName string 42 ) 43 44 func initNVP() (err error) { 45 if err = initPeerClient(); err != nil { 46 appLogger.Debugf("Failed deploying [%s]", err) 47 return 48 49 } 50 if err = initCryptoClients(); err != nil { 51 appLogger.Debugf("Failed deploying [%s]", err) 52 return 53 } 54 55 return 56 } 57 58 func initPeerClient() (err error) { 59 config.SetupTestConfig(".") 60 viper.Set("ledger.blockchain.deploy-system-chaincode", "false") 61 viper.Set("peer.validator.validity-period.verification", "false") 62 63 peerClientConn, err = peer.NewPeerClientConnection() 64 if err != nil { 65 fmt.Printf("error connection to server at host:port = %s\n", viper.GetString("peer.address")) 66 return 67 } 68 serverClient = pb.NewPeerClient(peerClientConn) 69 70 // Logging 71 var formatter = logging.MustStringFormatter( 72 `%{color}[%{module}] %{shortfunc} [%{shortfile}] -> %{level:.4s} %{id:03x}%{color:reset} %{message}`, 73 ) 74 logging.SetFormatter(formatter) 75 76 return 77 } 78 79 func initCryptoClients() error { 80 crypto.Init() 81 82 // Initialize the clients mapping alice, bob, charlie and dave 83 // to identities already defined in 'membersrvc.yaml' 84 85 // Alice as jim 86 if err := crypto.RegisterClient("jim", nil, "jim", "6avZQLwcUe9b"); err != nil { 87 return err 88 } 89 var err error 90 alice, err = crypto.InitClient("jim", nil) 91 if err != nil { 92 return err 93 } 94 95 // Bob as lukas 96 if err := crypto.RegisterClient("lukas", nil, "lukas", "NPKYL39uKbkj"); err != nil { 97 return err 98 } 99 bob, err = crypto.InitClient("lukas", nil) 100 if err != nil { 101 return err 102 } 103 104 bobCert, err = bob.GetEnrollmentCertificateHandler() 105 if err != nil { 106 appLogger.Errorf("Failed getting Bob TCert [%s]", err) 107 return err 108 } 109 110 return nil 111 } 112 113 func closeCryptoClient(client crypto.Client) { 114 crypto.CloseClient(client) 115 } 116 117 func processTransaction(tx *pb.Transaction) (*pb.Response, error) { 118 return serverClient.ProcessTransaction(context.Background(), tx) 119 } 120 121 func confidentiality(enabled bool) { 122 confidentialityOn = enabled 123 } 124 125 func deployInternal(deployer crypto.Client, adminCert crypto.CertificateHandler) (resp *pb.Response, err error) { 126 // Prepare the spec. The metadata includes the identity of the administrator 127 spec := &pb.ChaincodeSpec{ 128 Type: 1, 129 ChaincodeId: &pb.ChaincodeID{Path: "github.com/hyperledger/fabric/examples/chaincode/go/asset_management"}, 130 //ChaincodeID: &pb.ChaincodeID{Name: chaincodeName}, 131 Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs("init")}, 132 Metadata: adminCert.GetCertificate(), 133 } 134 135 // First build the deployment spec 136 cds, err := getChaincodeBytes(spec) 137 if err != nil { 138 return nil, fmt.Errorf("Error getting deployment spec: %s ", err) 139 } 140 141 // Now create the Transactions message and send to Peer. 142 transaction, err := deployer.NewChaincodeDeployTransaction(cds, cds.ChaincodeSpec.ChaincodeId.Name) 143 if err != nil { 144 return nil, fmt.Errorf("Error deploying chaincode: %s ", err) 145 } 146 147 resp, err = processTransaction(transaction) 148 149 appLogger.Debugf("resp [%s]", resp.String()) 150 151 chaincodeName = cds.ChaincodeSpec.ChaincodeId.Name 152 appLogger.Debugf("ChaincodeName [%s]", chaincodeName) 153 154 return 155 } 156 157 func assignOwnershipInternal(invoker crypto.Client, invokerCert crypto.CertificateHandler, asset string, newOwnerCert crypto.CertificateHandler) (resp *pb.Response, err error) { 158 // Get a transaction handler to be used to submit the execute transaction 159 // and bind the chaincode access control logic using the binding 160 submittingCertHandler, err := invoker.GetTCertificateHandlerNext() 161 if err != nil { 162 return nil, err 163 } 164 txHandler, err := submittingCertHandler.GetTransactionHandler() 165 if err != nil { 166 return nil, err 167 } 168 binding, err := txHandler.GetBinding() 169 if err != nil { 170 return nil, err 171 } 172 173 chaincodeInput := &pb.ChaincodeInput{ 174 Args: util.ToChaincodeArgs("assign", asset, base64.StdEncoding.EncodeToString(newOwnerCert.GetCertificate())), 175 } 176 chaincodeInputRaw, err := proto.Marshal(chaincodeInput) 177 if err != nil { 178 return nil, err 179 } 180 181 // Access control. Administrator signs chaincodeInputRaw || binding to confirm his identity 182 sigma, err := invokerCert.Sign(append(chaincodeInputRaw, binding...)) 183 if err != nil { 184 return nil, err 185 } 186 187 // Prepare spec and submit 188 spec := &pb.ChaincodeSpec{ 189 Type: 1, 190 ChaincodeId: &pb.ChaincodeID{Name: chaincodeName}, 191 CtorMsg: chaincodeInput, 192 Metadata: sigma, // Proof of identity 193 } 194 195 chaincodeInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} 196 197 // Now create the Transactions message and send to Peer. 198 transaction, err := txHandler.NewChaincodeExecute(chaincodeInvocationSpec, util.GenerateUUID()) 199 if err != nil { 200 return nil, fmt.Errorf("Error deploying chaincode: %s ", err) 201 } 202 203 return processTransaction(transaction) 204 } 205 206 func transferOwnershipInternal(owner crypto.Client, ownerCert crypto.CertificateHandler, asset string, newOwnerCert crypto.CertificateHandler) (resp *pb.Response, err error) { 207 // Get a transaction handler to be used to submit the execute transaction 208 // and bind the chaincode access control logic using the binding 209 210 submittingCertHandler, err := owner.GetTCertificateHandlerNext() 211 if err != nil { 212 return nil, err 213 } 214 txHandler, err := submittingCertHandler.GetTransactionHandler() 215 if err != nil { 216 return nil, err 217 } 218 binding, err := txHandler.GetBinding() 219 if err != nil { 220 return nil, err 221 } 222 223 chaincodeInput := &pb.ChaincodeInput{ 224 Args: util.ToChaincodeArgs("transfer", asset, base64.StdEncoding.EncodeToString(newOwnerCert.GetCertificate())), 225 } 226 chaincodeInputRaw, err := proto.Marshal(chaincodeInput) 227 if err != nil { 228 return nil, err 229 } 230 231 // Access control. Owner signs chaincodeInputRaw || binding to confirm his identity 232 sigma, err := ownerCert.Sign(append(chaincodeInputRaw, binding...)) 233 if err != nil { 234 return nil, err 235 } 236 237 // Prepare spec and submit 238 spec := &pb.ChaincodeSpec{ 239 Type: 1, 240 ChaincodeId: &pb.ChaincodeID{Name: chaincodeName}, 241 CtorMsg: chaincodeInput, 242 Metadata: sigma, // Proof of identity 243 } 244 245 chaincodeInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} 246 247 // Now create the Transactions message and send to Peer. 248 transaction, err := txHandler.NewChaincodeExecute(chaincodeInvocationSpec, util.GenerateUUID()) 249 if err != nil { 250 return nil, fmt.Errorf("Error deploying chaincode: %s ", err) 251 } 252 253 return processTransaction(transaction) 254 255 } 256 257 func whoIsTheOwner(invoker crypto.Client, asset string) (transaction *pb.Transaction, resp *pb.Response, err error) { 258 chaincodeInput := &pb.ChaincodeInput{Args: util.ToChaincodeArgs("query", asset)} 259 260 // Prepare spec and submit 261 spec := &pb.ChaincodeSpec{ 262 Type: 1, 263 ChaincodeId: &pb.ChaincodeID{Name: chaincodeName}, 264 CtorMsg: chaincodeInput, 265 } 266 267 chaincodeInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} 268 269 // Now create the Transactions message and send to Peer. 270 transaction, err = invoker.NewChaincodeQuery(chaincodeInvocationSpec, util.GenerateUUID()) 271 if err != nil { 272 return nil, nil, fmt.Errorf("Error deploying chaincode: %s ", err) 273 } 274 275 resp, err = processTransaction(transaction) 276 return 277 } 278 279 func getChaincodeBytes(spec *pb.ChaincodeSpec) (*pb.ChaincodeDeploymentSpec, error) { 280 mode := viper.GetString("chaincode.mode") 281 var codePackageBytes []byte 282 if mode != chaincode.DevModeUserRunsChaincode { 283 appLogger.Debugf("Received build request for chaincode spec: %v", spec) 284 var err error 285 if err = checkSpec(spec); err != nil { 286 return nil, err 287 } 288 289 codePackageBytes, err = container.GetChaincodePackageBytes(spec) 290 if err != nil { 291 err = fmt.Errorf("Error getting chaincode package bytes: %s", err) 292 appLogger.Errorf("%s", err) 293 return nil, err 294 } 295 } 296 chaincodeDeploymentSpec := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackageBytes} 297 return chaincodeDeploymentSpec, nil 298 } 299 300 func checkSpec(spec *pb.ChaincodeSpec) error { 301 // Don't allow nil value 302 if spec == nil { 303 return errors.New("Expected chaincode specification, nil received") 304 } 305 306 platform, err := platforms.Find(spec.Type) 307 if err != nil { 308 return fmt.Errorf("Failed to determine platform type: %s", err) 309 } 310 311 return platform.ValidateSpec(spec) 312 }