github.com/anjalikarhana/fabric@v2.1.1+incompatible/integration/chaincode/kvexecutor/chaincode.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package kvexecutor
     8  
     9  import (
    10  	"encoding/base64"
    11  	"encoding/json"
    12  	"fmt"
    13  
    14  	"github.com/hyperledger/fabric-chaincode-go/shim"
    15  	pb "github.com/hyperledger/fabric-protos-go/peer"
    16  	"github.com/pkg/errors"
    17  )
    18  
    19  // KVExcutor is a chaincode implementation that takes a KVData array as read parameter
    20  // and a a KVData array as write parameter, and then calls GetXXX/PutXXX methods to read and write
    21  // state/collection data. Both input params should be marshalled json data and then base64 encoded.
    22  type KVExcutor struct {
    23  }
    24  
    25  // KVData contains the data to read/write a key.
    26  // Key is required. Value is required for write and ignored for read.
    27  // When Collection is empty string "", it will read/write state data.
    28  // When Collection is not empty string "", it will read/write private data in the collection.
    29  type KVData struct {
    30  	Collection string `json:"collection"` // optional
    31  	Key        string `json:"key"`        // required
    32  	Value      string `json:"value"`      // required for read, ignored for write
    33  }
    34  
    35  // Init initializes chaincode
    36  // ===========================
    37  func (t *KVExcutor) Init(stub shim.ChaincodeStubInterface) pb.Response {
    38  	return shim.Success(nil)
    39  }
    40  
    41  // Invoke - Our entry point for Invocations
    42  // ========================================
    43  func (t *KVExcutor) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
    44  	function, args := stub.GetFunctionAndParameters()
    45  	fmt.Println("invoke is running " + function)
    46  
    47  	switch function {
    48  	case "readWriteKVs":
    49  		return t.readWriteKVs(stub, args)
    50  	default:
    51  		//error
    52  		fmt.Println("invoke did not find func: " + function)
    53  		return shim.Error("Received unknown function invocation")
    54  	}
    55  }
    56  
    57  // both params should be marshalled json data and base64 encoded
    58  func (t *KVExcutor) readWriteKVs(stub shim.ChaincodeStubInterface, args []string) pb.Response {
    59  	if len(args) != 2 {
    60  		return shim.Error("Incorrect number of arguments. Expecting 2 (readInputs and writeInputs)")
    61  	}
    62  	readInputs, err := parseArg(args[0])
    63  	if err != nil {
    64  		return shim.Error(err.Error())
    65  	}
    66  	writeInputs, err := parseArg(args[1])
    67  	if err != nil {
    68  		return shim.Error(err.Error())
    69  	}
    70  
    71  	results := make([]*KVData, 0)
    72  	var val []byte
    73  	for _, input := range readInputs {
    74  		if input.Collection == "" {
    75  			val, err = stub.GetState(input.Key)
    76  		} else {
    77  			val, err = stub.GetPrivateData(input.Collection, input.Key)
    78  		}
    79  		if err != nil {
    80  			return shim.Error(fmt.Sprintf("failed to read data for %+v: %s", input, err))
    81  		}
    82  		result := KVData{Collection: input.Collection, Key: input.Key, Value: string(val)}
    83  		results = append(results, &result)
    84  	}
    85  
    86  	for _, input := range writeInputs {
    87  		if input.Collection == "" {
    88  			err = stub.PutState(input.Key, []byte(input.Value))
    89  		} else {
    90  			err = stub.PutPrivateData(input.Collection, input.Key, []byte(input.Value))
    91  		}
    92  		if err != nil {
    93  			return shim.Error(fmt.Sprintf("failed to write data for %+v: %s", input, err))
    94  		}
    95  	}
    96  
    97  	resultBytes, err := json.Marshal(results)
    98  	if err != nil {
    99  		return shim.Error(fmt.Sprintf("failed to marshal results %+v: %s", results, err))
   100  	}
   101  	return shim.Success(resultBytes)
   102  }
   103  
   104  func parseArg(inputParam string) ([]*KVData, error) {
   105  	kvdata := make([]*KVData, 0)
   106  	inputBytes, err := base64.StdEncoding.DecodeString(inputParam)
   107  	if inputParam == "" {
   108  		return kvdata, nil
   109  	}
   110  	if err != nil {
   111  		return nil, errors.WithMessagef(err, "failed to base64 decode input %s", inputParam)
   112  	}
   113  	if err = json.Unmarshal(inputBytes, &kvdata); err != nil {
   114  		return nil, errors.WithMessagef(err, "failed to unmarshal kvdata %s", string(inputBytes))
   115  	}
   116  	return kvdata, nil
   117  }