github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/integration/chaincode/kvexecutor/chaincode.go (about)

     1  /*
     2  Copyright hechain. 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  // KVExecutor 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 KVExecutor struct{}
    23  
    24  // KVData contains the data to read/write a key.
    25  // Key is required. Value is required for write and ignored for read.
    26  // When Collection is empty string "", it will read/write state data.
    27  // When Collection is not empty string "", it will read/write private data in the collection.
    28  type KVData struct {
    29  	Collection string `json:"collection"` // optional
    30  	Key        string `json:"key"`        // required
    31  	Value      string `json:"value"`      // required for read, ignored for write
    32  }
    33  
    34  // Init initializes chaincode
    35  // ===========================
    36  func (t *KVExecutor) Init(stub shim.ChaincodeStubInterface) pb.Response {
    37  	return shim.Success(nil)
    38  }
    39  
    40  // Invoke - Our entry point for Invocations
    41  // ========================================
    42  func (t *KVExecutor) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
    43  	function, args := stub.GetFunctionAndParameters()
    44  	fmt.Println("invoke is running " + function)
    45  
    46  	switch function {
    47  	case "readWriteKVs":
    48  		return t.readWriteKVs(stub, args)
    49  	default:
    50  		// error
    51  		fmt.Println("invoke did not find func: " + function)
    52  		return shim.Error("Received unknown function invocation")
    53  	}
    54  }
    55  
    56  // both params should be marshalled json data and base64 encoded
    57  func (t *KVExecutor) readWriteKVs(stub shim.ChaincodeStubInterface, args []string) pb.Response {
    58  	if len(args) != 2 {
    59  		return shim.Error("Incorrect number of arguments. Expecting 2 (readInputs and writeInputs)")
    60  	}
    61  	readInputs, err := parseArg(args[0])
    62  	if err != nil {
    63  		return shim.Error(err.Error())
    64  	}
    65  	writeInputs, err := parseArg(args[1])
    66  	if err != nil {
    67  		return shim.Error(err.Error())
    68  	}
    69  
    70  	results := make([]*KVData, 0)
    71  	var val []byte
    72  	for _, input := range readInputs {
    73  		if input.Collection == "" {
    74  			val, err = stub.GetState(input.Key)
    75  		} else {
    76  			val, err = stub.GetPrivateData(input.Collection, input.Key)
    77  		}
    78  		if err != nil {
    79  			return shim.Error(fmt.Sprintf("failed to read data for %+v: %s", input, err))
    80  		}
    81  		result := KVData{Collection: input.Collection, Key: input.Key, Value: string(val)}
    82  		results = append(results, &result)
    83  	}
    84  
    85  	for _, input := range writeInputs {
    86  		if input.Collection == "" {
    87  			err = stub.PutState(input.Key, []byte(input.Value))
    88  		} else {
    89  			err = stub.PutPrivateData(input.Collection, input.Key, []byte(input.Value))
    90  		}
    91  		if err != nil {
    92  			return shim.Error(fmt.Sprintf("failed to write data for %+v: %s", input, err))
    93  		}
    94  	}
    95  
    96  	resultBytes, err := json.Marshal(results)
    97  	if err != nil {
    98  		return shim.Error(fmt.Sprintf("failed to marshal results %+v: %s", results, err))
    99  	}
   100  	return shim.Success(resultBytes)
   101  }
   102  
   103  func parseArg(inputParam string) ([]*KVData, error) {
   104  	kvdata := make([]*KVData, 0)
   105  	inputBytes, err := base64.StdEncoding.DecodeString(inputParam)
   106  	if inputParam == "" {
   107  		return kvdata, nil
   108  	}
   109  	if err != nil {
   110  		return nil, errors.WithMessagef(err, "failed to base64 decode input %s", inputParam)
   111  	}
   112  	if err = json.Unmarshal(inputBytes, &kvdata); err != nil {
   113  		return nil, errors.WithMessagef(err, "failed to unmarshal kvdata %s", string(inputBytes))
   114  	}
   115  	return kvdata, nil
   116  }