github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/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/common/flogging"
    23  	"github.com/hyperledger/fabric/core/chaincode/shim"
    24  	pb "github.com/hyperledger/fabric/protos/peer"
    25  	"github.com/hyperledger/fabric/protos/utils"
    26  	putils "github.com/hyperledger/fabric/protos/utils"
    27  
    28  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    29  )
    30  
    31  var logger = flogging.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] - ChaincodeID of executing chaincode
    56  // args[4] - result of executing chaincode
    57  // args[5] - binary blob of simulation results
    58  // args[6] - serialized events
    59  // args[7] - payloadVisibility
    60  //
    61  // NOTE: this chaincode is meant to sign another chaincode's simulation
    62  // results. It should not manipulate state as any state change will be
    63  // silently discarded: the only state changes that will be persisted if
    64  // this endorsement is successful is what we are about to sign, which by
    65  // definition can't be a state change of our own.
    66  func (e *EndorserOneValidSignature) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
    67  	args := stub.GetArgs()
    68  	if len(args) < 6 {
    69  		return shim.Error(fmt.Sprintf("Incorrect number of arguments (expected a minimum of 5, provided %d)", len(args)))
    70  	} else if len(args) > 8 {
    71  		return shim.Error(fmt.Sprintf("Incorrect number of arguments (expected a maximum of 7, provided %d)", len(args)))
    72  	}
    73  
    74  	logger.Debugf("ESCC starts: %d args", len(args))
    75  
    76  	// handle the header
    77  	var hdr []byte
    78  	if args[1] == nil {
    79  		return shim.Error("serialized Header object is null")
    80  	}
    81  
    82  	hdr = args[1]
    83  
    84  	// handle the proposal payload
    85  	var payl []byte
    86  	if args[2] == nil {
    87  		return shim.Error("serialized ChaincodeProposalPayload object is null")
    88  	}
    89  
    90  	payl = args[2]
    91  
    92  	// handle ChaincodeID
    93  	if args[3] == nil {
    94  		return shim.Error("ChaincodeID is null")
    95  	}
    96  
    97  	ccid, err := putils.UnmarshalChaincodeID(args[3])
    98  	if err != nil {
    99  		return shim.Error(err.Error())
   100  	}
   101  
   102  	// handle executing chaincode result
   103  	// Status code < shim.ERRORTHRESHOLD can be endorsed
   104  	if args[4] == nil {
   105  		return shim.Error("Response of chaincode executing is null")
   106  	}
   107  
   108  	response, err := putils.GetResponse(args[4])
   109  	if err != nil {
   110  		return shim.Error(fmt.Sprintf("Failed to get Response of executing chaincode: %s", err.Error()))
   111  	}
   112  
   113  	if response.Status >= shim.ERRORTHRESHOLD {
   114  		return shim.Error(fmt.Sprintf("Status code less than %d will be endorsed, received status code: %d", shim.ERRORTHRESHOLD, response.Status))
   115  	}
   116  
   117  	// handle simulation results
   118  	var results []byte
   119  	if args[5] == nil {
   120  		return shim.Error("simulation results are null")
   121  	}
   122  
   123  	results = args[5]
   124  
   125  	// Handle serialized events if they have been provided
   126  	// they might be nil in case there's no events but there
   127  	// is a visibility field specified as the next arg
   128  	events := []byte("")
   129  	if len(args) > 6 && args[6] != nil {
   130  		events = args[6]
   131  	}
   132  
   133  	// Handle payload visibility (it's an optional argument)
   134  	// currently the fabric only supports full visibility: this means that
   135  	// there are no restrictions on which parts of the proposal payload will
   136  	// be visible in the final transaction; this default approach requires
   137  	// no additional instructions in the PayloadVisibility field; however
   138  	// the fabric may be extended to encode more elaborate visibility
   139  	// mechanisms that shall be encoded in this field (and handled
   140  	// appropriately by the peer)
   141  	var visibility []byte
   142  	if len(args) > 7 {
   143  		visibility = args[7]
   144  	}
   145  
   146  	// obtain the default signing identity for this peer; it will be used to sign this proposal response
   147  	localMsp := mspmgmt.GetLocalMSP()
   148  	if localMsp == nil {
   149  		return shim.Error("Nil local MSP manager")
   150  	}
   151  
   152  	signingEndorser, err := localMsp.GetDefaultSigningIdentity()
   153  	if err != nil {
   154  		return shim.Error(fmt.Sprintf("Could not obtain the default signing identity, err %s", err))
   155  	}
   156  
   157  	// obtain a proposal response
   158  	presp, err := utils.CreateProposalResponse(hdr, payl, response, results, events, ccid, visibility, signingEndorser)
   159  	if err != nil {
   160  		return shim.Error(err.Error())
   161  	}
   162  
   163  	// marshall the proposal response so that we return its bytes
   164  	prBytes, err := utils.GetBytesProposalResponse(presp)
   165  	if err != nil {
   166  		return shim.Error(fmt.Sprintf("Could not marshal ProposalResponse: err %s", err))
   167  	}
   168  
   169  	pResp, err := utils.GetProposalResponse(prBytes)
   170  	if err != nil {
   171  		return shim.Error(err.Error())
   172  	}
   173  	if pResp.Response == nil {
   174  		fmt.Println("GetProposalResponse get empty Response")
   175  	}
   176  
   177  	logger.Debugf("ESCC exits successfully")
   178  	return shim.Success(prBytes)
   179  }