github.com/inklabsfoundation/inkchain@v0.17.1-0.20181025012015-c3cef8062f19/examples/map/map.go (about) 1 // +build !experimental 2 3 /* 4 Copyright IBM Corp. All Rights Reserved. 5 6 SPDX-License-Identifier: Apache-2.0 7 */ 8 9 package main 10 11 import ( 12 "encoding/json" 13 "fmt" 14 "strconv" 15 "time" 16 17 "github.com/inklabsfoundation/inkchain/core/chaincode/shim" 18 pb "github.com/inklabsfoundation/inkchain/protos/peer" 19 ) 20 21 // This chaincode implements a simple map that is stored in the state. 22 // The following operations are available. 23 24 // Invoke operations 25 // put - requires two arguments, a key and value 26 // remove - requires a key 27 // get - requires one argument, a key, and returns a value 28 // keys - requires no arguments, returns all keys 29 30 // SimpleChaincode example simple Chaincode implementation 31 type SimpleChaincode struct { 32 } 33 34 // Init is a no-op 35 func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { 36 return shim.Success(nil) 37 } 38 39 // Invoke has two functions 40 // put - takes two arguments, a key and value, and stores them in the state 41 // remove - takes one argument, a key, and removes if from the state 42 func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { 43 function, args := stub.GetFunctionAndParameters() 44 switch function { 45 46 case "put": 47 if len(args) < 2 { 48 return shim.Error("put operation must include two arguments: [key, value]") 49 } 50 key := args[0] 51 value := args[1] 52 53 if err := stub.PutState(key, []byte(value)); err != nil { 54 fmt.Printf("Error putting state %s", err) 55 return shim.Error(fmt.Sprintf("put operation failed. Error updating state: %s", err)) 56 } 57 58 indexName := "compositeKeyTest" 59 compositeKeyTestIndex, err := stub.CreateCompositeKey(indexName, []string{key}) 60 if err != nil { 61 return shim.Error(err.Error()) 62 } 63 64 valueByte := []byte{0x00} 65 if err := stub.PutState(compositeKeyTestIndex, valueByte); err != nil { 66 fmt.Printf("Error putting state with compositeKey %s", err) 67 return shim.Error(fmt.Sprintf("put operation failed. Error updating state with compositeKey: %s", err)) 68 } 69 70 return shim.Success(nil) 71 72 case "remove": 73 if len(args) < 1 { 74 return shim.Error("remove operation must include one argument: [key]") 75 } 76 key := args[0] 77 78 err := stub.DelState(key) 79 if err != nil { 80 return shim.Error(fmt.Sprintf("remove operation failed. Error updating state: %s", err)) 81 } 82 return shim.Success(nil) 83 84 case "get": 85 if len(args) < 1 { 86 return shim.Error("get operation must include one argument, a key") 87 } 88 key := args[0] 89 value, err := stub.GetState(key) 90 if err != nil { 91 return shim.Error(fmt.Sprintf("get operation failed. Error accessing state: %s", err)) 92 } 93 jsonVal, err := json.Marshal(string(value)) 94 return shim.Success(jsonVal) 95 96 case "keys": 97 if len(args) < 2 { 98 return shim.Error("put operation must include two arguments, a key and value") 99 } 100 startKey := args[0] 101 endKey := args[1] 102 103 //sleep needed to test peer's timeout behavior when using iterators 104 stime := 0 105 if len(args) > 2 { 106 stime, _ = strconv.Atoi(args[2]) 107 } 108 109 keysIter, err := stub.GetStateByRange(startKey, endKey) 110 if err != nil { 111 return shim.Error(fmt.Sprintf("keys operation failed. Error accessing state: %s", err)) 112 } 113 defer keysIter.Close() 114 115 var keys []string 116 for keysIter.HasNext() { 117 //if sleeptime is specied, take a nap 118 if stime > 0 { 119 time.Sleep(time.Duration(stime) * time.Millisecond) 120 } 121 122 response, iterErr := keysIter.Next() 123 if iterErr != nil { 124 return shim.Error(fmt.Sprintf("keys operation failed. Error accessing state: %s", err)) 125 } 126 keys = append(keys, response.Key) 127 } 128 129 for key, value := range keys { 130 fmt.Printf("key %d contains %s\n", key, value) 131 } 132 133 jsonKeys, err := json.Marshal(keys) 134 if err != nil { 135 return shim.Error(fmt.Sprintf("keys operation failed. Error marshaling JSON: %s", err)) 136 } 137 138 return shim.Success(jsonKeys) 139 case "query": 140 query := args[0] 141 keysIter, err := stub.GetQueryResult(query) 142 if err != nil { 143 return shim.Error(fmt.Sprintf("query operation failed. Error accessing state: %s", err)) 144 } 145 defer keysIter.Close() 146 147 var keys []string 148 for keysIter.HasNext() { 149 response, iterErr := keysIter.Next() 150 if iterErr != nil { 151 return shim.Error(fmt.Sprintf("query operation failed. Error accessing state: %s", err)) 152 } 153 keys = append(keys, response.Key) 154 } 155 156 jsonKeys, err := json.Marshal(keys) 157 if err != nil { 158 return shim.Error(fmt.Sprintf("query operation failed. Error marshaling JSON: %s", err)) 159 } 160 161 return shim.Success(jsonKeys) 162 case "history": 163 key := args[0] 164 keysIter, err := stub.GetHistoryForKey(key) 165 if err != nil { 166 return shim.Error(fmt.Sprintf("query operation failed. Error accessing state: %s", err)) 167 } 168 defer keysIter.Close() 169 170 var keys []string 171 for keysIter.HasNext() { 172 response, iterErr := keysIter.Next() 173 if iterErr != nil { 174 return shim.Error(fmt.Sprintf("query operation failed. Error accessing state: %s", err)) 175 } 176 keys = append(keys, response.TxId) 177 } 178 179 for key, txID := range keys { 180 fmt.Printf("key %d contains %s\n", key, txID) 181 } 182 183 jsonKeys, err := json.Marshal(keys) 184 if err != nil { 185 return shim.Error(fmt.Sprintf("query operation failed. Error marshaling JSON: %s", err)) 186 } 187 188 return shim.Success(jsonKeys) 189 190 default: 191 return shim.Success([]byte("Unsupported operation")) 192 } 193 } 194 195 func main() { 196 err := shim.Start(new(SimpleChaincode)) 197 if err != nil { 198 fmt.Printf("Error starting chaincode: %s", err) 199 } 200 }