github.com/defanghe/fabric@v2.1.1+incompatible/core/chaincode/testdata/src/chaincodes/map/map.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package main 8 9 import ( 10 "encoding/json" 11 "fmt" 12 "strconv" 13 "time" 14 15 "github.com/hyperledger/fabric-chaincode-go/shim" 16 pb "github.com/hyperledger/fabric-protos-go/peer" 17 ) 18 19 // This chaincode implements a simple map that is stored in the state. 20 // The following operations are available. 21 22 // Invoke operations 23 // put - requires two arguments, a key and value 24 // remove - requires a key 25 // get - requires one argument, a key, and returns a value 26 // keys - requires no arguments, returns all keys 27 28 // SimpleChaincode example simple Chaincode implementation 29 type SimpleChaincode struct { 30 } 31 32 type PageResponse struct { 33 Bookmark string `json:"bookmark"` 34 Keys []string `json:"keys"` 35 } 36 37 // Init is a no-op 38 func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { 39 return shim.Success(nil) 40 } 41 42 // Invoke has two functions 43 // put - takes two arguments, a key and value, and stores them in the state 44 // remove - takes one argument, a key, and removes if from the state 45 func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { 46 function, args := stub.GetFunctionAndParameters() 47 switch function { 48 49 case "putPrivate": 50 return t.putPrivate(stub, args) 51 52 case "removePrivate": 53 return t.removePrivate(stub, args) 54 55 case "getPrivate": 56 return t.getPrivate(stub, args) 57 58 case "keysPrivate": 59 return t.keysPrivate(stub, args) 60 61 case "queryPrivate": 62 return t.queryPrivate(stub, args) 63 64 case "put": 65 return t.put(stub, args) 66 67 case "remove": 68 return t.remove(stub, args) 69 70 case "get": 71 return t.get(stub, args) 72 73 case "keys": 74 return t.keys(stub, args) 75 76 case "keysByPage": 77 return t.keysByPage(stub, args) 78 79 case "query": 80 return t.query(stub, args) 81 82 case "queryByPage": 83 return t.queryByPage(stub, args) 84 85 case "history": 86 return t.history(stub, args) 87 88 case "getPut": 89 return t.getPut(stub, args) 90 91 case "getPutPrivate": 92 return t.getPutPrivate(stub, args) 93 94 default: 95 return shim.Error("Unsupported operation") 96 } 97 } 98 99 func (t *SimpleChaincode) putPrivate(stub shim.ChaincodeStubInterface, args []string) pb.Response { 100 if len(args) < 3 { 101 return shim.Error("put operation on private data must include three arguments: [collection, key, value]") 102 } 103 collection := args[0] 104 key := args[1] 105 value := args[2] 106 107 if err := stub.PutPrivateData(collection, key, []byte(value)); err != nil { 108 fmt.Printf("Error putting private data%s", err) 109 return shim.Error(fmt.Sprintf("put operation failed. Error updating state: %s", err)) 110 } 111 112 return shim.Success(nil) 113 } 114 func (t *SimpleChaincode) removePrivate(stub shim.ChaincodeStubInterface, args []string) pb.Response { 115 if len(args) < 2 { 116 return shim.Error("remove operation on private data must include two arguments: [collection, key]") 117 } 118 collection := args[0] 119 key := args[1] 120 121 err := stub.DelPrivateData(collection, key) 122 if err != nil { 123 return shim.Error(fmt.Sprintf("remove operation on private data failed. Error updating state: %s", err)) 124 } 125 return shim.Success(nil) 126 } 127 func (t *SimpleChaincode) getPrivate(stub shim.ChaincodeStubInterface, args []string) pb.Response { 128 if len(args) < 2 { 129 return shim.Error("get operation on private data must include two arguments: [collection, key]") 130 } 131 collection := args[0] 132 key := args[1] 133 value, err := stub.GetPrivateData(collection, key) 134 if err != nil { 135 return shim.Error(fmt.Sprintf("get operation on private data failed. Error accessing state: %s", err)) 136 } 137 jsonVal, err := json.Marshal(string(value)) 138 return shim.Success(jsonVal) 139 140 } 141 func (t *SimpleChaincode) keysPrivate(stub shim.ChaincodeStubInterface, args []string) pb.Response { 142 if len(args) < 3 { 143 return shim.Error("range query operation on private data must include three arguments, a collection, key and value") 144 } 145 collection := args[0] 146 startKey := args[1] 147 endKey := args[2] 148 149 //sleep needed to test peer's timeout behavior when using iterators 150 stime := 0 151 if len(args) > 3 { 152 stime, _ = strconv.Atoi(args[3]) 153 } 154 155 keysIter, err := stub.GetPrivateDataByRange(collection, startKey, endKey) 156 if err != nil { 157 return shim.Error(fmt.Sprintf("keys operation failed on private data. Error accessing state: %s", err)) 158 } 159 defer keysIter.Close() 160 161 var keys []string 162 for keysIter.HasNext() { 163 //if sleeptime is specied, take a nap 164 if stime > 0 { 165 time.Sleep(time.Duration(stime) * time.Millisecond) 166 } 167 168 response, iterErr := keysIter.Next() 169 if iterErr != nil { 170 return shim.Error(fmt.Sprintf("keys operation on private data failed. Error accessing state: %s", err)) 171 } 172 keys = append(keys, response.Key) 173 } 174 175 for key, value := range keys { 176 fmt.Printf("key %d contains %s\n", key, value) 177 } 178 179 jsonKeys, err := json.Marshal(keys) 180 if err != nil { 181 return shim.Error(fmt.Sprintf("keys operation on private data failed. Error marshaling JSON: %s", err)) 182 } 183 184 return shim.Success(jsonKeys) 185 } 186 187 func (t *SimpleChaincode) queryPrivate(stub shim.ChaincodeStubInterface, args []string) pb.Response { 188 collection := args[0] 189 query := args[1] 190 keysIter, err := stub.GetPrivateDataQueryResult(collection, query) 191 if err != nil { 192 return shim.Error(fmt.Sprintf("query operation on private data failed. Error accessing state: %s", err)) 193 } 194 defer keysIter.Close() 195 196 var keys []string 197 for keysIter.HasNext() { 198 response, iterErr := keysIter.Next() 199 if iterErr != nil { 200 return shim.Error(fmt.Sprintf("query operation on private data failed. Error accessing state: %s", err)) 201 } 202 keys = append(keys, response.Key) 203 } 204 205 jsonKeys, err := json.Marshal(keys) 206 if err != nil { 207 return shim.Error(fmt.Sprintf("query operation on private data failed. Error marshaling JSON: %s", err)) 208 } 209 210 return shim.Success(jsonKeys) 211 } 212 func (t *SimpleChaincode) put(stub shim.ChaincodeStubInterface, args []string) pb.Response { 213 if len(args) < 2 { 214 return shim.Error("put operation must include two arguments: [key, value]") 215 } 216 key := args[0] 217 value := args[1] 218 219 if err := stub.PutState(key, []byte(value)); err != nil { 220 fmt.Printf("Error putting state %s", err) 221 return shim.Error(fmt.Sprintf("put operation failed. Error updating state: %s", err)) 222 } 223 224 indexName := "compositeKeyTest" 225 compositeKeyTestIndex, err := stub.CreateCompositeKey(indexName, []string{key}) 226 if err != nil { 227 return shim.Error(err.Error()) 228 } 229 230 valueByte := []byte{0x00} 231 if err := stub.PutState(compositeKeyTestIndex, valueByte); err != nil { 232 fmt.Printf("Error putting state with compositeKey %s", err) 233 return shim.Error(fmt.Sprintf("put operation failed. Error updating state with compositeKey: %s", err)) 234 } 235 236 return shim.Success(nil) 237 } 238 func (t *SimpleChaincode) remove(stub shim.ChaincodeStubInterface, args []string) pb.Response { 239 if len(args) < 1 { 240 return shim.Error("remove operation must include one argument: [key]") 241 } 242 key := args[0] 243 244 err := stub.DelState(key) 245 if err != nil { 246 return shim.Error(fmt.Sprintf("remove operation failed. Error updating state: %s", err)) 247 } 248 return shim.Success(nil) 249 } 250 func (t *SimpleChaincode) get(stub shim.ChaincodeStubInterface, args []string) pb.Response { 251 if len(args) < 1 { 252 return shim.Error("get operation must include one argument, a key") 253 } 254 key := args[0] 255 value, err := stub.GetState(key) 256 if err != nil { 257 return shim.Error(fmt.Sprintf("get operation failed. Error accessing state: %s", err)) 258 } 259 jsonVal, err := json.Marshal(string(value)) 260 return shim.Success(jsonVal) 261 } 262 func (t *SimpleChaincode) keys(stub shim.ChaincodeStubInterface, args []string) pb.Response { 263 if len(args) < 2 { 264 return shim.Error("keys operation must include two arguments, a key and value") 265 } 266 startKey := args[0] 267 endKey := args[1] 268 269 //sleep needed to test peer's timeout behavior when using iterators 270 stime := 0 271 if len(args) > 2 { 272 stime, _ = strconv.Atoi(args[2]) 273 } 274 275 keysIter, err := stub.GetStateByRange(startKey, endKey) 276 if err != nil { 277 return shim.Error(fmt.Sprintf("keys operation failed. Error accessing state: %s", err)) 278 } 279 defer keysIter.Close() 280 281 var keys []string 282 for keysIter.HasNext() { 283 //if sleeptime is specied, take a nap 284 if stime > 0 { 285 time.Sleep(time.Duration(stime) * time.Millisecond) 286 } 287 288 response, iterErr := keysIter.Next() 289 if iterErr != nil { 290 return shim.Error(fmt.Sprintf("keys operation failed. Error accessing state: %s", err)) 291 } 292 keys = append(keys, response.Key) 293 } 294 295 for key, value := range keys { 296 fmt.Printf("key %d contains %s\n", key, value) 297 } 298 299 jsonKeys, err := json.Marshal(keys) 300 if err != nil { 301 return shim.Error(fmt.Sprintf("keys operation failed. Error marshaling JSON: %s", err)) 302 } 303 304 return shim.Success(jsonKeys) 305 } 306 307 func (t *SimpleChaincode) keysByPage(stub shim.ChaincodeStubInterface, args []string) pb.Response { 308 if len(args) < 4 { 309 return shim.Error("paginated range query operation must include four arguments, a key, value, pageSize and a bookmark") 310 } 311 startKey := args[0] 312 endKey := args[1] 313 pageSize, parserr := strconv.ParseInt(args[2], 10, 32) 314 if parserr != nil { 315 return shim.Error(fmt.Sprintf("error parsing range pagesize: %s", parserr)) 316 } 317 bookmark := args[3] 318 319 //sleep needed to test peer's timeout behavior when using iterators 320 stime := 0 321 if len(args) > 4 { 322 stime, _ = strconv.Atoi(args[4]) 323 } 324 325 keysIter, resp, err := stub.GetStateByRangeWithPagination(startKey, endKey, int32(pageSize), bookmark) 326 if err != nil { 327 return shim.Error(fmt.Sprintf("keysByPage operation failed. Error accessing state: %s", err)) 328 } 329 defer keysIter.Close() 330 331 var keys []string 332 for keysIter.HasNext() { 333 //if sleeptime is specied, take a nap 334 if stime > 0 { 335 time.Sleep(time.Duration(stime) * time.Millisecond) 336 } 337 338 response, iterErr := keysIter.Next() 339 if iterErr != nil { 340 return shim.Error(fmt.Sprintf("keysByPage operation failed. Error accessing state: %s", err)) 341 } 342 keys = append(keys, response.Key) 343 } 344 345 for index, value := range keys { 346 fmt.Printf("key %d contains %s\n", index, value) 347 } 348 349 jsonResp := PageResponse{ 350 Bookmark: resp.Bookmark, 351 Keys: keys, 352 } 353 354 queryResp, err := json.Marshal(jsonResp) 355 if err != nil { 356 return shim.Error(fmt.Sprintf("keysByPage operation failed. Error marshaling JSON: %s", err)) 357 } 358 359 return shim.Success(queryResp) 360 } 361 func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response { 362 query := args[0] 363 keysIter, err := stub.GetQueryResult(query) 364 if err != nil { 365 return shim.Error(fmt.Sprintf("query operation failed. Error accessing state: %s", err)) 366 } 367 defer keysIter.Close() 368 369 var keys []string 370 for keysIter.HasNext() { 371 response, iterErr := keysIter.Next() 372 if iterErr != nil { 373 return shim.Error(fmt.Sprintf("query operation failed. Error accessing state: %s", err)) 374 } 375 keys = append(keys, response.Key) 376 } 377 378 jsonKeys, err := json.Marshal(keys) 379 if err != nil { 380 return shim.Error(fmt.Sprintf("query operation failed. Error marshaling JSON: %s", err)) 381 } 382 383 return shim.Success(jsonKeys) 384 } 385 func (t *SimpleChaincode) queryByPage(stub shim.ChaincodeStubInterface, args []string) pb.Response { 386 query := args[0] 387 pageSize, parserr := strconv.ParseInt(args[1], 10, 32) 388 if parserr != nil { 389 return shim.Error(fmt.Sprintf("error parsing query pagesize: %s", parserr)) 390 } 391 bookmark := args[2] 392 393 keysIter, resp, err := stub.GetQueryResultWithPagination(query, int32(pageSize), bookmark) 394 if err != nil { 395 return shim.Error(fmt.Sprintf("queryByPage operation failed. Error accessing state: %s", err)) 396 } 397 defer keysIter.Close() 398 399 var keys []string 400 for keysIter.HasNext() { 401 response, iterErr := keysIter.Next() 402 if iterErr != nil { 403 return shim.Error(fmt.Sprintf("queryByPage operation failed. Error accessing state: %s", err)) 404 } 405 keys = append(keys, response.Key) 406 } 407 408 for key, value := range keys { 409 fmt.Printf("key %d contains %s\n", key, value) 410 } 411 412 jsonResp := PageResponse{ 413 Bookmark: resp.Bookmark, 414 Keys: keys, 415 } 416 417 queryResp, err := json.Marshal(jsonResp) 418 if err != nil { 419 return shim.Error(fmt.Sprintf("queryByPage operation failed. Error marshaling JSON: %s", err)) 420 } 421 422 return shim.Success(queryResp) 423 } 424 func (t *SimpleChaincode) history(stub shim.ChaincodeStubInterface, args []string) pb.Response { 425 key := args[0] 426 keysIter, err := stub.GetHistoryForKey(key) 427 if err != nil { 428 return shim.Error(fmt.Sprintf("get history operation failed. Error accessing state: %s", err)) 429 } 430 defer keysIter.Close() 431 432 var keys []string 433 for keysIter.HasNext() { 434 response, iterErr := keysIter.Next() 435 if iterErr != nil { 436 return shim.Error(fmt.Sprintf("get history operation failed. Error accessing state: %s", err)) 437 } 438 keys = append(keys, response.TxId) 439 } 440 441 for key, txID := range keys { 442 fmt.Printf("key %d contains %s\n", key, txID) 443 } 444 445 jsonKeys, err := json.Marshal(keys) 446 if err != nil { 447 return shim.Error(fmt.Sprintf("get history operation failed. Error marshaling JSON: %s", err)) 448 } 449 450 return shim.Success(jsonKeys) 451 } 452 func (t *SimpleChaincode) getPut(stub shim.ChaincodeStubInterface, args []string) pb.Response { 453 _ = t.get(stub, args) 454 return t.put(stub, args) 455 } 456 func (t *SimpleChaincode) getPutPrivate(stub shim.ChaincodeStubInterface, args []string) pb.Response { 457 _ = t.getPrivate(stub, args) 458 return t.putPrivate(stub, args) 459 } 460 func main() { 461 err := shim.Start(new(SimpleChaincode)) 462 if err != nil { 463 fmt.Printf("Error starting chaincode: %s", err) 464 } 465 }