github.com/suchongming/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 }