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