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  }