github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/core/scc/escc/endorser_onevalidsignature.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 escc
    18  
    19  import (
    20  	"fmt"
    21  
    22  	"github.com/hyperledger/fabric/core/chaincode/shim"
    23  	pb "github.com/hyperledger/fabric/protos/peer"
    24  	"github.com/hyperledger/fabric/protos/utils"
    25  	putils "github.com/hyperledger/fabric/protos/utils"
    26  	"github.com/op/go-logging"
    27  
    28  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    29  )
    30  
    31  var logger = logging.MustGetLogger("escc")
    32  
    33  // EndorserOneValidSignature implements the default endorsement policy, which is to
    34  // sign the proposal hash and the read-write set
    35  type EndorserOneValidSignature struct {
    36  }
    37  
    38  // Init is called once when the chaincode started the first time
    39  func (e *EndorserOneValidSignature) Init(stub shim.ChaincodeStubInterface) pb.Response {
    40  	logger.Infof("Successfully initialized ESCC")
    41  
    42  	return shim.Success(nil)
    43  }
    44  
    45  // Invoke is called to endorse the specified Proposal
    46  // For now, we sign the input and return the endorsed result. Later we can expand
    47  // the chaincode to provide more sophisticate policy processing such as enabling
    48  // policy specification to be coded as a transaction of the chaincode and Client
    49  // could select which policy to use for endorsement using parameter
    50  // @return a marshalled proposal response
    51  // Note that Peer calls this function with 4 mandatory arguments (and 2 optional ones):
    52  // args[0] - function name (not used now)
    53  // args[1] - serialized Header object
    54  // args[2] - serialized ChaincodeProposalPayload object
    55  // args[3] - result of executing chaincode
    56  // args[4] - binary blob of simulation results
    57  // args[5] - serialized events
    58  // args[6] - payloadVisibility
    59  //
    60  // NOTE: this chaincode is meant to sign another chaincode's simulation
    61  // results. It should not manipulate state as any state change will be
    62  // silently discarded: the only state changes that will be persisted if
    63  // this endorsement is successful is what we are about to sign, which by
    64  // definition can't be a state change of our own.
    65  func (e *EndorserOneValidSignature) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
    66  	args := stub.GetArgs()
    67  	if len(args) < 5 {
    68  		return shim.Error(fmt.Sprintf("Incorrect number of arguments (expected a minimum of 5, provided %d)", len(args)))
    69  	} else if len(args) > 7 {
    70  		return shim.Error(fmt.Sprintf("Incorrect number of arguments (expected a maximum of 7, provided %d)", len(args)))
    71  	}
    72  
    73  	logger.Debugf("ESCC starts: %d args", len(args))
    74  
    75  	// handle the header
    76  	var hdr []byte
    77  	if args[1] == nil {
    78  		return shim.Error("serialized Header object is null")
    79  	}
    80  
    81  	hdr = args[1]
    82  
    83  	// handle the proposal payload
    84  	var payl []byte
    85  	if args[2] == nil {
    86  		return shim.Error("serialized ChaincodeProposalPayload object is null")
    87  	}
    88  
    89  	payl = args[2]
    90  
    91  	// handle executing chaincode result
    92  	// Status code < 500 can be endorsed
    93  	if args[3] == nil {
    94  		return shim.Error("Response of chaincode executing is null")
    95  	}
    96  
    97  	response, err := putils.GetResponse(args[3])
    98  	if err != nil {
    99  		return shim.Error(fmt.Sprintf("Failed to get Response of executing chaincode: %s", err.Error()))
   100  	}
   101  
   102  	if response.Status >= shim.ERROR {
   103  		return shim.Error(fmt.Sprintf("Status code less than 500 will be endorsed, get status code: %d", response.Status))
   104  	}
   105  
   106  	// handle simulation results
   107  	var results []byte
   108  	if args[4] == nil {
   109  		return shim.Error("simulation results are null")
   110  	}
   111  
   112  	results = args[4]
   113  
   114  	// Handle serialized events if they have been provided
   115  	// they might be nil in case there's no events but there
   116  	// is a visibility field specified as the next arg
   117  	events := []byte("")
   118  	if len(args) > 5 && args[5] != nil {
   119  		events = args[5]
   120  	}
   121  
   122  	// Handle payload visibility (it's an optional argument)
   123  	// currently the fabric only supports full visibility: this means that
   124  	// there are no restrictions on which parts of the proposal payload will
   125  	// be visible in the final transaction; this default approach requires
   126  	// no additional instructions in the PayloadVisibility field; however
   127  	// the fabric may be extended to encode more elaborate visibility
   128  	// mechanisms that shall be encoded in this field (and handled
   129  	// appropriately by the peer)
   130  	var visibility []byte
   131  	if len(args) > 6 {
   132  		visibility = args[6]
   133  	}
   134  
   135  	// obtain the default signing identity for this peer; it will be used to sign this proposal response
   136  	localMsp := mspmgmt.GetLocalMSP()
   137  	if localMsp == nil {
   138  		return shim.Error("Nil local MSP manager")
   139  	}
   140  
   141  	signingEndorser, err := localMsp.GetDefaultSigningIdentity()
   142  	if err != nil {
   143  		return shim.Error(fmt.Sprintf("Could not obtain the default signing identity, err %s", err))
   144  	}
   145  
   146  	// obtain a proposal response
   147  	presp, err := utils.CreateProposalResponse(hdr, payl, response, results, events, visibility, signingEndorser)
   148  	if err != nil {
   149  		return shim.Error(err.Error())
   150  	}
   151  
   152  	// marshall the proposal response so that we return its bytes
   153  	prBytes, err := utils.GetBytesProposalResponse(presp)
   154  	if err != nil {
   155  		return shim.Error(fmt.Sprintf("Could not marshall ProposalResponse: err %s", err))
   156  	}
   157  
   158  	pResp, err := utils.GetProposalResponse(prBytes)
   159  	if err != nil {
   160  		return shim.Error(err.Error())
   161  	}
   162  	if pResp.Response == nil {
   163  		fmt.Println("GetProposalResponse get empty Response")
   164  	}
   165  
   166  	logger.Debugf("ESCC exits successfully")
   167  	return shim.Success(prBytes)
   168  }