github.com/kchristidis/fabric@v1.0.4-0.20171028114726-837acd08cde1/examples/chaincode/go/chaincode_example04/chaincode_example04.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 "fmt" 21 "strconv" 22 23 "github.com/hyperledger/fabric/common/util" 24 "github.com/hyperledger/fabric/core/chaincode/shim" 25 pb "github.com/hyperledger/fabric/protos/peer" 26 ) 27 28 // This chaincode is a test for chaincode invoking another chaincode - invokes chaincode_example02 29 30 // SimpleChaincode example simple Chaincode implementation 31 type SimpleChaincode struct { 32 } 33 34 // Init takes two arguments, a string and int. These are stored in the key/value pair in the state 35 func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { 36 var event string // Indicates whether event has happened. Initially 0 37 var eventVal int // State of event 38 var err error 39 _, args := stub.GetFunctionAndParameters() 40 if len(args) != 2 { 41 return shim.Error("Incorrect number of arguments. Expecting 2") 42 } 43 44 // Initialize the chaincode 45 event = args[0] 46 eventVal, err = strconv.Atoi(args[1]) 47 if err != nil { 48 return shim.Error("Expecting integer value for event status") 49 } 50 fmt.Printf("eventVal = %d\n", eventVal) 51 52 err = stub.PutState(event, []byte(strconv.Itoa(eventVal))) 53 if err != nil { 54 return shim.Error(err.Error()) 55 } 56 57 return shim.Success(nil) 58 } 59 60 // Invoke invokes another chaincode - chaincode_example02, upon receipt of an event and changes event state 61 func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response { 62 var event string // Event entity 63 var eventVal int // State of event 64 var err error 65 66 if len(args) != 3 && len(args) != 4 { 67 return shim.Error("Incorrect number of arguments. Expecting 3 or 4") 68 } 69 70 chainCodeToCall := args[0] 71 event = args[1] 72 eventVal, err = strconv.Atoi(args[2]) 73 if err != nil { 74 return shim.Error("Expected integer value for event state change") 75 } 76 channelID := "" 77 if len(args) == 4 { 78 channelID = args[3] 79 } 80 81 if eventVal != 1 { 82 fmt.Printf("Unexpected event. Doing nothing\n") 83 return shim.Success(nil) 84 } 85 86 f := "invoke" 87 invokeArgs := util.ToChaincodeArgs(f, "a", "b", "10") 88 response := stub.InvokeChaincode(chainCodeToCall, invokeArgs, channelID) 89 if response.Status != shim.OK { 90 errStr := fmt.Sprintf("Failed to invoke chaincode. Got error: %s", string(response.Payload)) 91 fmt.Printf(errStr) 92 return shim.Error(errStr) 93 } 94 95 fmt.Printf("Invoke chaincode successful. Got response %s", string(response.Payload)) 96 97 // Write the event state back to the ledger 98 err = stub.PutState(event, []byte(strconv.Itoa(eventVal))) 99 if err != nil { 100 return shim.Error(err.Error()) 101 } 102 103 return response 104 } 105 106 func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response { 107 var event string // Event entity 108 var err error 109 110 if len(args) < 1 { 111 return shim.Error("Incorrect number of arguments. Expecting entity to query") 112 } 113 114 event = args[0] 115 var jsonResp string 116 117 // Get the state from the ledger 118 eventValbytes, err := stub.GetState(event) 119 if err != nil { 120 jsonResp = "{\"Error\":\"Failed to get state for " + event + "\"}" 121 return shim.Error(jsonResp) 122 } 123 124 if eventValbytes == nil { 125 jsonResp = "{\"Error\":\"Nil value for " + event + "\"}" 126 return shim.Error(jsonResp) 127 } 128 129 if len(args) > 3 { 130 chainCodeToCall := args[1] 131 queryKey := args[2] 132 channel := args[3] 133 f := "query" 134 invokeArgs := util.ToChaincodeArgs(f, queryKey) 135 response := stub.InvokeChaincode(chainCodeToCall, invokeArgs, channel) 136 if response.Status != shim.OK { 137 errStr := fmt.Sprintf("Failed to invoke chaincode. Got error: %s", err.Error()) 138 fmt.Printf(errStr) 139 return shim.Error(errStr) 140 } 141 jsonResp = string(response.Payload) 142 } else { 143 jsonResp = "{\"Name\":\"" + event + "\",\"Amount\":\"" + string(eventValbytes) + "\"}" 144 } 145 fmt.Printf("Query Response: %s\n", jsonResp) 146 147 return shim.Success([]byte(jsonResp)) 148 } 149 150 // Invoke is called by fabric to execute a transaction 151 func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { 152 function, args := stub.GetFunctionAndParameters() 153 if function == "invoke" { 154 return t.invoke(stub, args) 155 } else if function == "query" { 156 return t.query(stub, args) 157 } 158 159 return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"query\"") 160 } 161 162 func main() { 163 err := shim.Start(new(SimpleChaincode)) 164 if err != nil { 165 fmt.Printf("Error starting Simple chaincode: %s", err) 166 } 167 }