github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/integration/chaincode/simple/chaincode.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package simple 8 9 import ( 10 "fmt" 11 "os" 12 "strconv" 13 14 "github.com/hyperledger/fabric-chaincode-go/shim" 15 pb "github.com/hyperledger/fabric-protos-go/peer" 16 ) 17 18 // SimpleChaincode example simple Chaincode implementation 19 type SimpleChaincode struct { 20 } 21 22 func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { 23 fmt.Println("Init invoked") 24 _, args := stub.GetFunctionAndParameters() 25 var A, B string // Entities 26 var Aval, Bval int // Asset holdings 27 var err error 28 29 if len(args) != 4 { 30 return shim.Error("Incorrect number of arguments. Expecting 4") 31 } 32 33 // Initialize the chaincode 34 A = args[0] 35 Aval, err = strconv.Atoi(args[1]) 36 if err != nil { 37 return shim.Error("Expecting integer value for asset holding") 38 } 39 B = args[2] 40 Bval, err = strconv.Atoi(args[3]) 41 if err != nil { 42 return shim.Error("Expecting integer value for asset holding") 43 } 44 fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) 45 46 // Write the state to the ledger 47 err = stub.PutState(A, []byte(strconv.Itoa(Aval))) 48 if err != nil { 49 return shim.Error(err.Error()) 50 } 51 52 err = stub.PutState(B, []byte(strconv.Itoa(Bval))) 53 if err != nil { 54 return shim.Error(err.Error()) 55 } 56 57 fmt.Println("Init returning with success") 58 return shim.Success(nil) 59 } 60 61 func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { 62 fmt.Println("ex02 Invoke") 63 if os.Getenv("DEVMODE_ENABLED") != "" { 64 fmt.Println("invoking in devmode") 65 } 66 function, args := stub.GetFunctionAndParameters() 67 switch function { 68 case "invoke": 69 // Make payment of X units from A to B 70 return t.invoke(stub, args) 71 case "delete": 72 // Deletes an entity from its state 73 return t.delete(stub, args) 74 case "query": 75 // the old "Query" is now implemtned in invoke 76 return t.query(stub, args) 77 case "respond": 78 // return with an error 79 return t.respond(stub, args) 80 case "mspid": 81 // Checks the shim's GetMSPID() API 82 return t.mspid(args) 83 default: 84 return shim.Error(`Invalid invoke function name. Expecting "invoke", "delete", "query", "respond", or "mspid"`) 85 } 86 } 87 88 // Transaction makes payment of X units from A to B 89 func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response { 90 var A, B string // Entities 91 var Aval, Bval int // Asset holdings 92 var X int // Transaction value 93 var err error 94 95 if len(args) != 3 { 96 return shim.Error("Incorrect number of arguments. Expecting 3") 97 } 98 99 A = args[0] 100 B = args[1] 101 102 // Get the state from the ledger 103 // TODO: will be nice to have a GetAllState call to ledger 104 Avalbytes, err := stub.GetState(A) 105 if err != nil { 106 return shim.Error("Failed to get state") 107 } 108 if Avalbytes == nil { 109 return shim.Error("Entity not found") 110 } 111 Aval, _ = strconv.Atoi(string(Avalbytes)) 112 113 Bvalbytes, err := stub.GetState(B) 114 if err != nil { 115 return shim.Error("Failed to get state") 116 } 117 if Bvalbytes == nil { 118 return shim.Error("Entity not found") 119 } 120 Bval, _ = strconv.Atoi(string(Bvalbytes)) 121 122 // Perform the execution 123 X, err = strconv.Atoi(args[2]) 124 if err != nil { 125 return shim.Error("Invalid transaction amount, expecting a integer value") 126 } 127 Aval = Aval - X 128 Bval = Bval + X 129 fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) 130 131 // Write the state back to the ledger 132 err = stub.PutState(A, []byte(strconv.Itoa(Aval))) 133 if err != nil { 134 return shim.Error(err.Error()) 135 } 136 137 err = stub.PutState(B, []byte(strconv.Itoa(Bval))) 138 if err != nil { 139 return shim.Error(err.Error()) 140 } 141 142 return shim.Success(nil) 143 } 144 145 // Deletes an entity from state 146 func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response { 147 if len(args) != 1 { 148 return shim.Error("Incorrect number of arguments. Expecting 1") 149 } 150 151 A := args[0] 152 153 // Delete the key from the state in ledger 154 err := stub.DelState(A) 155 if err != nil { 156 return shim.Error("Failed to delete state") 157 } 158 159 return shim.Success(nil) 160 } 161 162 // query callback representing the query of a chaincode 163 func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response { 164 var A string // Entities 165 var err error 166 167 if len(args) != 1 { 168 return shim.Error("Incorrect number of arguments. Expecting name of the person to query") 169 } 170 171 A = args[0] 172 173 // Get the state from the ledger 174 Avalbytes, err := stub.GetState(A) 175 if err != nil { 176 jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}" 177 return shim.Error(jsonResp) 178 } 179 180 if Avalbytes == nil { 181 jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}" 182 return shim.Error(jsonResp) 183 } 184 185 jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}" 186 fmt.Printf("Query Response:%s\n", jsonResp) 187 return shim.Success(Avalbytes) 188 } 189 190 // respond simply generates a response payload from the args 191 func (t *SimpleChaincode) respond(stub shim.ChaincodeStubInterface, args []string) pb.Response { 192 if len(args) != 3 { 193 return shim.Error("expected three arguments") 194 } 195 196 status, err := strconv.ParseInt(args[0], 10, 32) 197 if err != nil { 198 return shim.Error(err.Error()) 199 } 200 message := args[1] 201 payload := []byte(args[2]) 202 203 return pb.Response{ 204 Status: int32(status), 205 Message: message, 206 Payload: payload, 207 } 208 } 209 210 // mspid simply calls shim.GetMSPID() to verify the mspid was properly passed from the peer 211 // via the CORE_PEER_LOCALMSPID env var 212 func (t *SimpleChaincode) mspid(args []string) pb.Response { 213 if len(args) != 0 { 214 return shim.Error("expected no arguments") 215 } 216 217 // Get the mspid from the env var 218 mspid, err := shim.GetMSPID() 219 if err != nil { 220 jsonResp := "{\"Error\":\"Failed to get mspid\"}" 221 return shim.Error(jsonResp) 222 } 223 224 if mspid == "" { 225 jsonResp := "{\"Error\":\"Empty mspid\"}" 226 return shim.Error(jsonResp) 227 } 228 229 fmt.Printf("MSPID:%s\n", mspid) 230 return shim.Success([]byte(mspid)) 231 }