github.com/kchristidis/fabric@v1.0.4-0.20171028114726-837acd08cde1/examples/chaincode/go/chaincode_example02/chaincode_example02.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 //WARNING - this chaincode's ID is hard-coded in chaincode_example04 to illustrate one way of 20 //calling chaincode from a chaincode. If this example is modified, chaincode_example04.go has 21 //to be modified as well with the new ID of chaincode_example02. 22 //chaincode_example05 show's how chaincode ID can be passed in as a parameter instead of 23 //hard-coding. 24 25 import ( 26 "fmt" 27 "strconv" 28 29 "github.com/hyperledger/fabric/core/chaincode/shim" 30 pb "github.com/hyperledger/fabric/protos/peer" 31 ) 32 33 // SimpleChaincode example simple Chaincode implementation 34 type SimpleChaincode struct { 35 } 36 37 func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { 38 fmt.Println("ex02 Init") 39 _, args := stub.GetFunctionAndParameters() 40 var A, B string // Entities 41 var Aval, Bval int // Asset holdings 42 var err error 43 44 if len(args) != 4 { 45 return shim.Error("Incorrect number of arguments. Expecting 4") 46 } 47 48 // Initialize the chaincode 49 A = args[0] 50 Aval, err = strconv.Atoi(args[1]) 51 if err != nil { 52 return shim.Error("Expecting integer value for asset holding") 53 } 54 B = args[2] 55 Bval, err = strconv.Atoi(args[3]) 56 if err != nil { 57 return shim.Error("Expecting integer value for asset holding") 58 } 59 fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) 60 61 // Write the state to the ledger 62 err = stub.PutState(A, []byte(strconv.Itoa(Aval))) 63 if err != nil { 64 return shim.Error(err.Error()) 65 } 66 67 err = stub.PutState(B, []byte(strconv.Itoa(Bval))) 68 if err != nil { 69 return shim.Error(err.Error()) 70 } 71 72 return shim.Success(nil) 73 } 74 75 func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { 76 fmt.Println("ex02 Invoke") 77 function, args := stub.GetFunctionAndParameters() 78 if function == "invoke" { 79 // Make payment of X units from A to B 80 return t.invoke(stub, args) 81 } else if function == "delete" { 82 // Deletes an entity from its state 83 return t.delete(stub, args) 84 } else if function == "query" { 85 // the old "Query" is now implemtned in invoke 86 return t.query(stub, args) 87 } 88 89 return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"") 90 } 91 92 // Transaction makes payment of X units from A to B 93 func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response { 94 var A, B string // Entities 95 var Aval, Bval int // Asset holdings 96 var X int // Transaction value 97 var err error 98 99 if len(args) != 3 { 100 return shim.Error("Incorrect number of arguments. Expecting 3") 101 } 102 103 A = args[0] 104 B = args[1] 105 106 // Get the state from the ledger 107 // TODO: will be nice to have a GetAllState call to ledger 108 Avalbytes, err := stub.GetState(A) 109 if err != nil { 110 return shim.Error("Failed to get state") 111 } 112 if Avalbytes == nil { 113 return shim.Error("Entity not found") 114 } 115 Aval, _ = strconv.Atoi(string(Avalbytes)) 116 117 Bvalbytes, err := stub.GetState(B) 118 if err != nil { 119 return shim.Error("Failed to get state") 120 } 121 if Bvalbytes == nil { 122 return shim.Error("Entity not found") 123 } 124 Bval, _ = strconv.Atoi(string(Bvalbytes)) 125 126 // Perform the execution 127 X, err = strconv.Atoi(args[2]) 128 if err != nil { 129 return shim.Error("Invalid transaction amount, expecting a integer value") 130 } 131 Aval = Aval - X 132 Bval = Bval + X 133 fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) 134 135 // Write the state back to the ledger 136 err = stub.PutState(A, []byte(strconv.Itoa(Aval))) 137 if err != nil { 138 return shim.Error(err.Error()) 139 } 140 141 err = stub.PutState(B, []byte(strconv.Itoa(Bval))) 142 if err != nil { 143 return shim.Error(err.Error()) 144 } 145 146 return shim.Success(nil) 147 } 148 149 // Deletes an entity from state 150 func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response { 151 if len(args) != 1 { 152 return shim.Error("Incorrect number of arguments. Expecting 1") 153 } 154 155 A := args[0] 156 157 // Delete the key from the state in ledger 158 err := stub.DelState(A) 159 if err != nil { 160 return shim.Error("Failed to delete state") 161 } 162 163 return shim.Success(nil) 164 } 165 166 // query callback representing the query of a chaincode 167 func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response { 168 var A string // Entities 169 var err error 170 171 if len(args) != 1 { 172 return shim.Error("Incorrect number of arguments. Expecting name of the person to query") 173 } 174 175 A = args[0] 176 177 // Get the state from the ledger 178 Avalbytes, err := stub.GetState(A) 179 if err != nil { 180 jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}" 181 return shim.Error(jsonResp) 182 } 183 184 if Avalbytes == nil { 185 jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}" 186 return shim.Error(jsonResp) 187 } 188 189 jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}" 190 fmt.Printf("Query Response:%s\n", jsonResp) 191 return shim.Success(Avalbytes) 192 } 193 194 func main() { 195 err := shim.Start(new(SimpleChaincode)) 196 if err != nil { 197 fmt.Printf("Error starting Simple chaincode: %s", err) 198 } 199 }