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