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