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 }