github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/examples/chaincode/go/asset_management_interactive/app3/app3.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  	"fmt"
    22  	"os"
    23  	"reflect"
    24  
    25  	"strings"
    26  
    27  	"github.com/hyperledger/fabric/core/crypto"
    28  	pb "github.com/hyperledger/fabric/protos"
    29  	"github.com/op/go-logging"
    30  	"google.golang.org/grpc"
    31  )
    32  
    33  var (
    34  	// Logging
    35  	appLogger = logging.MustGetLogger("app")
    36  
    37  	// NVP related objects
    38  	peerClientConn *grpc.ClientConn
    39  	serverClient   pb.PeerClient
    40  
    41  	// Charlie, Dave, and Edwina are owners
    42  	charlie     crypto.Client
    43  	charlieCert crypto.CertificateHandler
    44  
    45  	dave     crypto.Client
    46  	daveCert crypto.CertificateHandler
    47  
    48  	edwina     crypto.Client
    49  	edwinaCert crypto.CertificateHandler
    50  
    51  	assets  map[string]string
    52  	lotNums []string
    53  
    54  	clients map[string]crypto.Client
    55  	certs   map[string]crypto.CertificateHandler
    56  
    57  	myClient crypto.Client
    58  	myCert   crypto.CertificateHandler
    59  )
    60  
    61  func transferOwnership(lotNum string, newOwner string) (err error) {
    62  	if !isAssetKnown(lotNum) {
    63  		appLogger.Errorf("Error -- asset '%s' does not exist.", lotNum)
    64  		return
    65  	}
    66  
    67  	if !isUserKnown(newOwner) {
    68  		appLogger.Errorf("Error -- user '%s' is not known.", newOwner)
    69  		return
    70  	}
    71  
    72  	assetName := assets[lotNum]
    73  
    74  	appLogger.Debugf("------------- '%s' wants to transfer the ownership of '%s: %s' to '%s'...", user, lotNum, assetName, newOwner)
    75  
    76  	if !isOwner(assetName, user) {
    77  		appLogger.Debugf("'%s' is not the owner of '%s: %s' -- transfer not allowed.", user, lotNum, assetName)
    78  		return
    79  	}
    80  
    81  	resp, err := transferOwnershipInternal(myClient, myCert, assetName, certs[newOwner])
    82  	if err != nil {
    83  		appLogger.Debugf("Failed to transfer '%s: %s' to '%s'", lotNum, assetName, newOwner)
    84  		return err
    85  	}
    86  	appLogger.Debugf("Resp [%s]", resp.String())
    87  
    88  	appLogger.Debugf("'%s' is the new owner of '%s: %s'!", newOwner, lotNum, assetName)
    89  	appLogger.Debug("------------- Done!")
    90  	return
    91  }
    92  
    93  func listOwnedAssets() {
    94  	ownedAssets := make([]string, 0, len(assets))
    95  
    96  	for _, lotNum := range lotNums {
    97  		assetName := assets[lotNum]
    98  
    99  		if isOwner(assetName, user) {
   100  			ownedAsset := "'" + lotNum + ": " + assetName + "'"
   101  			ownedAssets = append(ownedAssets, ownedAsset)
   102  		}
   103  	}
   104  
   105  	appLogger.Debugf("'%s' owns the following %d assets:", user, len(ownedAssets))
   106  
   107  	for _, asset := range ownedAssets {
   108  		appLogger.Debug(asset)
   109  	}
   110  }
   111  
   112  func isOwner(assetName string, user string) (isOwner bool) {
   113  	appLogger.Debug("Query....")
   114  	queryTx, theOwnerIs, err := whoIsTheOwner(myClient, assetName)
   115  	if err != nil {
   116  		return false
   117  	}
   118  	appLogger.Debugf("Resp [%s]", theOwnerIs.String())
   119  	appLogger.Debug("Query....done")
   120  
   121  	var res []byte
   122  	if confidentialityOn {
   123  		// Decrypt result
   124  		res, err = myClient.DecryptQueryResult(queryTx, theOwnerIs.Msg)
   125  		if err != nil {
   126  			appLogger.Errorf("Failed decrypting result [%s]", err)
   127  			return false
   128  		}
   129  	} else {
   130  		res = theOwnerIs.Msg
   131  	}
   132  
   133  	if !reflect.DeepEqual(res, certs[user].GetCertificate()) {
   134  		appLogger.Errorf("'%s' is not the owner.", user)
   135  
   136  		appLogger.Debugf("Query result  : [% x]", res)
   137  		appLogger.Debugf("%s's cert: [% x]", certs[user].GetCertificate(), user)
   138  
   139  		return false
   140  	} else {
   141  		return true
   142  	}
   143  }
   144  
   145  func isUserKnown(userName string) (ok bool) {
   146  	_, ok = clients[userName]
   147  	return ok
   148  }
   149  
   150  func isAssetKnown(assetName string) (ok bool) {
   151  	_, ok = assets[assetName]
   152  	return ok
   153  }
   154  
   155  func main() {
   156  	if len(os.Args) != 3 {
   157  		appLogger.Error("Error -- A ChaincodeName and username must be specified.")
   158  		os.Exit(-1)
   159  	}
   160  
   161  	chaincodeName = os.Args[1]
   162  	user = os.Args[2]
   163  
   164  	// Initialize a non-validating peer whose role is to submit
   165  	// transactions to the fabric network.
   166  	// A 'core.yaml' file is assumed to be available in the working directory.
   167  	if err := initNVP(); err != nil {
   168  		appLogger.Debugf("Failed initiliazing NVP [%s]", err)
   169  		os.Exit(-1)
   170  	}
   171  
   172  	if !isUserKnown(user) {
   173  		appLogger.Errorf("Error -- user '%s' is not known.", user)
   174  		os.Exit(-1)
   175  	}
   176  
   177  	// Enable fabric 'confidentiality'
   178  	confidentiality(true)
   179  
   180  	reader := bufio.NewReader(os.Stdin)
   181  
   182  	for {
   183  		fmt.Printf("%s$ ", user)
   184  		line, _ := reader.ReadString('\n')
   185  		command := strings.Split(strings.TrimRight(line, "\n"), " ")
   186  
   187  		if command[0] == "transfer" {
   188  			transferOwnership(command[1], command[2])
   189  		} else if command[0] == "list" {
   190  			listOwnedAssets()
   191  		} else if command[0] == "exit" {
   192  			os.Exit(0)
   193  		}
   194  	}
   195  }