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  }