docker-compose-files/hyperledger_fabric/v1.4.7/examples/chaincode/go/map/map.go

201 lines
5.3 KiB
Go
Raw Normal View History

2020-05-21 02:24:13 +08:00
// +build !experimental
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package main
import (
"encoding/json"
"fmt"
"strconv"
"time"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
)
// This chaincode implements a simple map that is stored in the state.
// The following operations are available.
// Invoke operations
// put - requires two arguments, a key and value
// remove - requires a key
// get - requires one argument, a key, and returns a value
// keys - requires no arguments, returns all keys
// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}
// Init is a no-op
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
return shim.Success(nil)
}
// Invoke has two functions
// put - takes two arguments, a key and value, and stores them in the state
// remove - takes one argument, a key, and removes if from the state
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
function, args := stub.GetFunctionAndParameters()
switch function {
case "put":
if len(args) < 2 {
return shim.Error("put operation must include two arguments: [key, value]")
}
key := args[0]
value := args[1]
if err := stub.PutState(key, []byte(value)); err != nil {
fmt.Printf("Error putting state %s", err)
return shim.Error(fmt.Sprintf("put operation failed. Error updating state: %s", err))
}
indexName := "compositeKeyTest"
compositeKeyTestIndex, err := stub.CreateCompositeKey(indexName, []string{key})
if err != nil {
return shim.Error(err.Error())
}
valueByte := []byte{0x00}
if err := stub.PutState(compositeKeyTestIndex, valueByte); err != nil {
fmt.Printf("Error putting state with compositeKey %s", err)
return shim.Error(fmt.Sprintf("put operation failed. Error updating state with compositeKey: %s", err))
}
return shim.Success(nil)
case "remove":
if len(args) < 1 {
return shim.Error("remove operation must include one argument: [key]")
}
key := args[0]
err := stub.DelState(key)
if err != nil {
return shim.Error(fmt.Sprintf("remove operation failed. Error updating state: %s", err))
}
return shim.Success(nil)
case "get":
if len(args) < 1 {
return shim.Error("get operation must include one argument, a key")
}
key := args[0]
value, err := stub.GetState(key)
if err != nil {
return shim.Error(fmt.Sprintf("get operation failed. Error accessing state: %s", err))
}
jsonVal, err := json.Marshal(string(value))
return shim.Success(jsonVal)
case "keys":
if len(args) < 2 {
return shim.Error("put operation must include two arguments, a key and value")
}
startKey := args[0]
endKey := args[1]
//sleep needed to test peer's timeout behavior when using iterators
stime := 0
if len(args) > 2 {
stime, _ = strconv.Atoi(args[2])
}
keysIter, err := stub.GetStateByRange(startKey, endKey)
if err != nil {
return shim.Error(fmt.Sprintf("keys operation failed. Error accessing state: %s", err))
}
defer keysIter.Close()
var keys []string
for keysIter.HasNext() {
//if sleeptime is specied, take a nap
if stime > 0 {
time.Sleep(time.Duration(stime) * time.Millisecond)
}
response, iterErr := keysIter.Next()
if iterErr != nil {
return shim.Error(fmt.Sprintf("keys operation failed. Error accessing state: %s", err))
}
keys = append(keys, response.Key)
}
for key, value := range keys {
fmt.Printf("key %d contains %s\n", key, value)
}
jsonKeys, err := json.Marshal(keys)
if err != nil {
return shim.Error(fmt.Sprintf("keys operation failed. Error marshaling JSON: %s", err))
}
return shim.Success(jsonKeys)
case "query":
query := args[0]
keysIter, err := stub.GetQueryResult(query)
if err != nil {
return shim.Error(fmt.Sprintf("query operation failed. Error accessing state: %s", err))
}
defer keysIter.Close()
var keys []string
for keysIter.HasNext() {
response, iterErr := keysIter.Next()
if iterErr != nil {
return shim.Error(fmt.Sprintf("query operation failed. Error accessing state: %s", err))
}
keys = append(keys, response.Key)
}
jsonKeys, err := json.Marshal(keys)
if err != nil {
return shim.Error(fmt.Sprintf("query operation failed. Error marshaling JSON: %s", err))
}
return shim.Success(jsonKeys)
case "history":
key := args[0]
keysIter, err := stub.GetHistoryForKey(key)
if err != nil {
return shim.Error(fmt.Sprintf("query operation failed. Error accessing state: %s", err))
}
defer keysIter.Close()
var keys []string
for keysIter.HasNext() {
response, iterErr := keysIter.Next()
if iterErr != nil {
return shim.Error(fmt.Sprintf("query operation failed. Error accessing state: %s", err))
}
keys = append(keys, response.TxId)
}
for key, txID := range keys {
fmt.Printf("key %d contains %s\n", key, txID)
}
jsonKeys, err := json.Marshal(keys)
if err != nil {
return shim.Error(fmt.Sprintf("query operation failed. Error marshaling JSON: %s", err))
}
return shim.Success(jsonKeys)
default:
return shim.Success([]byte("Unsupported operation"))
}
}
func main() {
err := shim.Start(new(SimpleChaincode))
if err != nil {
fmt.Printf("Error starting chaincode: %s", err)
}
}