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  }