github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/examples/chaincode/go/chaincode_example05/chaincode_example05.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 querying another chaincode - invokes chaincode_example02 and computes the sum of a and b and stores it as state 29 30 // SimpleChaincode example simple Chaincode implementation 31 type SimpleChaincode struct { 32 } 33 34 // Init takes two arguments, a string and int. The string will be a key with 35 // the int as a value. 36 func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { 37 var sum string // Sum of asset holdings across accounts. Initially 0 38 var sumVal int // Sum of holdings 39 var err error 40 _, args := stub.GetFunctionAndParameters() 41 if len(args) != 2 { 42 return shim.Error("Incorrect number of arguments. Expecting 2") 43 } 44 45 // Initialize the chaincode 46 sum = args[0] 47 sumVal, err = strconv.Atoi(args[1]) 48 if err != nil { 49 return shim.Error("Expecting integer value for sum") 50 } 51 fmt.Printf("sumVal = %d\n", sumVal) 52 53 // Write the state to the ledger 54 err = stub.PutState(sum, []byte(strconv.Itoa(sumVal))) 55 if err != nil { 56 return shim.Error(err.Error()) 57 } 58 59 return shim.Success(nil) 60 } 61 62 // Invoke queries another chaincode and updates its own state 63 func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response { 64 var sum, channelName string // Sum entity 65 var Aval, Bval, sumVal int // value of sum entity - to be computed 66 var err error 67 68 if len(args) < 2 { 69 return shim.Error("Incorrect number of arguments. Expecting atleast 2") 70 } 71 72 chaincodeName := args[0] // Expecting name of the chaincode you would like to call, this name would be given during chaincode install time 73 sum = args[1] 74 75 if len(args) > 2 { 76 channelName = args[2] 77 } else { 78 channelName = "" 79 } 80 81 // Query chaincode_example02 82 f := "query" 83 queryArgs := util.ToChaincodeArgs(f, "a") 84 85 // if chaincode being invoked is on the same channel, 86 // then channel defaults to the current channel and args[2] can be "". 87 // If the chaincode being called is on a different channel, 88 // then you must specify the channel name in args[2] 89 90 response := stub.InvokeChaincode(chaincodeName, queryArgs, channelName) 91 if response.Status != shim.OK { 92 errStr := fmt.Sprintf("Failed to query chaincode. Got error: %s", response.Payload) 93 fmt.Printf(errStr) 94 return shim.Error(errStr) 95 } 96 Aval, err = strconv.Atoi(string(response.Payload)) 97 if err != nil { 98 errStr := fmt.Sprintf("Error retrieving state from ledger for queried chaincode: %s", err.Error()) 99 fmt.Printf(errStr) 100 return shim.Error(errStr) 101 } 102 103 queryArgs = util.ToChaincodeArgs(f, "b") 104 response = stub.InvokeChaincode(chaincodeName, queryArgs, channelName) 105 if response.Status != shim.OK { 106 errStr := fmt.Sprintf("Failed to query chaincode. Got error: %s", response.Payload) 107 fmt.Printf(errStr) 108 return shim.Error(errStr) 109 } 110 Bval, err = strconv.Atoi(string(response.Payload)) 111 if err != nil { 112 errStr := fmt.Sprintf("Error retrieving state from ledger for queried chaincode: %s", err.Error()) 113 fmt.Printf(errStr) 114 return shim.Error(errStr) 115 } 116 117 // Compute sum 118 sumVal = Aval + Bval 119 120 // Write sumVal back to the ledger 121 err = stub.PutState(sum, []byte(strconv.Itoa(sumVal))) 122 if err != nil { 123 return shim.Error(err.Error()) 124 } 125 126 fmt.Printf("Invoke chaincode successful. Got sum %d\n", sumVal) 127 return shim.Success([]byte(strconv.Itoa(sumVal))) 128 } 129 130 func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response { 131 var sum, channelName string // Sum entity 132 var Aval, Bval, sumVal int // value of sum entity - to be computed 133 var err error 134 135 if len(args) < 2 { 136 return shim.Error("Incorrect number of arguments. Expecting atleast 2") 137 } 138 139 chaincodeName := args[0] // Expecting name of the chaincode you would like to call, this name would be given during chaincode install time 140 sum = args[1] 141 142 if len(args) > 2 { 143 channelName = args[2] 144 } else { 145 channelName = "" 146 } 147 148 // Query chaincode_example02 149 f := "query" 150 queryArgs := util.ToChaincodeArgs(f, "a") 151 152 // if chaincode being invoked is on the same channel, 153 // then channel defaults to the current channel and args[2] can be "". 154 // If the chaincode being called is on a different channel, 155 // then you must specify the channel name in args[2] 156 response := stub.InvokeChaincode(chaincodeName, queryArgs, channelName) 157 if response.Status != shim.OK { 158 errStr := fmt.Sprintf("Failed to query chaincode. Got error: %s", response.Payload) 159 fmt.Printf(errStr) 160 return shim.Error(errStr) 161 } 162 Aval, err = strconv.Atoi(string(response.Payload)) 163 if err != nil { 164 errStr := fmt.Sprintf("Error retrieving state from ledger for queried chaincode: %s", err.Error()) 165 fmt.Printf(errStr) 166 return shim.Error(errStr) 167 } 168 169 queryArgs = util.ToChaincodeArgs(f, "b") 170 response = stub.InvokeChaincode(chaincodeName, queryArgs, channelName) 171 if response.Status != shim.OK { 172 errStr := fmt.Sprintf("Failed to query chaincode. Got error: %s", response.Payload) 173 fmt.Printf(errStr) 174 return shim.Error(errStr) 175 } 176 Bval, err = strconv.Atoi(string(response.Payload)) 177 if err != nil { 178 errStr := fmt.Sprintf("Error retrieving state from ledger for queried chaincode: %s", err.Error()) 179 fmt.Printf(errStr) 180 return shim.Error(errStr) 181 } 182 183 // Compute sum 184 sumVal = Aval + Bval 185 186 fmt.Printf("Query chaincode successful. Got sum %d\n", sumVal) 187 jsonResp := "{\"Name\":\"" + sum + "\",\"Value\":\"" + strconv.Itoa(sumVal) + "\"}" 188 fmt.Printf("Query Response:%s\n", jsonResp) 189 return shim.Success([]byte(strconv.Itoa(sumVal))) 190 } 191 192 func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { 193 function, args := stub.GetFunctionAndParameters() 194 if function == "invoke" { 195 return t.invoke(stub, args) 196 } else if function == "query" { 197 return t.query(stub, args) 198 } 199 200 return shim.Success([]byte("Invalid invoke function name. Expecting \"invoke\" \"query\"")) 201 } 202 203 func main() { 204 err := shim.Start(new(SimpleChaincode)) 205 if err != nil { 206 fmt.Printf("Error starting Simple chaincode: %s", err) 207 } 208 }