diff --git a/integration/lifecycle/testdata/chaincode/simple-v14/chaincode.go b/integration/lifecycle/testdata/chaincode/simple-v14/chaincode.go new file mode 100644 index 00000000000..2d5223ec7c2 --- /dev/null +++ b/integration/lifecycle/testdata/chaincode/simple-v14/chaincode.go @@ -0,0 +1,210 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package main + +import ( + "fmt" + "os" + "strconv" + + "github.com/hyperledger/fabric/core/chaincode/shim" + pb "github.com/hyperledger/fabric/protos/peer" +) + +// SimpleChaincode example simple Chaincode implementation +type SimpleChaincode struct { +} + +func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { + fmt.Println("Init invoked") + _, args := stub.GetFunctionAndParameters() + var A, B string // Entities + var Aval, Bval int // Asset holdings + var err error + + if len(args) != 4 { + return shim.Error("Incorrect number of arguments. Expecting 4") + } + + // Initialize the chaincode + A = args[0] + Aval, err = strconv.Atoi(args[1]) + if err != nil { + return shim.Error("Expecting integer value for asset holding") + } + B = args[2] + Bval, err = strconv.Atoi(args[3]) + if err != nil { + return shim.Error("Expecting integer value for asset holding") + } + fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) + + // Write the state to the ledger + err = stub.PutState(A, []byte(strconv.Itoa(Aval))) + if err != nil { + return shim.Error(err.Error()) + } + + err = stub.PutState(B, []byte(strconv.Itoa(Bval))) + if err != nil { + return shim.Error(err.Error()) + } + + fmt.Println("Init returning with success") + return shim.Success(nil) +} + +func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { + fmt.Println("SimpleChaincode Invoke") + function, args := stub.GetFunctionAndParameters() + switch function { + case "invoke": + // Make payment of X units from A to B + return t.invoke(stub, args) + case "delete": + // Deletes an entity from its state + return t.delete(stub, args) + case "query": + // the old "Query" is now implemented in invoke + return t.query(stub, args) + case "respond": + // return with an error + return t.respond(stub, args) + default: + return shim.Error(`Invalid invoke function name. Expecting "invoke", "delete", "query", or "respond"`) + } +} + +// Transaction makes payment of X units from A to B +func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response { + var A, B string // Entities + var Aval, Bval int // Asset holdings + var X int // Transaction value + var err error + + if len(args) != 3 { + return shim.Error("Incorrect number of arguments. Expecting 3") + } + + A = args[0] + B = args[1] + + // Get the state from the ledger + // TODO: will be nice to have a GetAllState call to ledger + Avalbytes, err := stub.GetState(A) + if err != nil { + return shim.Error("Failed to get state") + } + if Avalbytes == nil { + return shim.Error("Entity not found") + } + Aval, _ = strconv.Atoi(string(Avalbytes)) + + Bvalbytes, err := stub.GetState(B) + if err != nil { + return shim.Error("Failed to get state") + } + if Bvalbytes == nil { + return shim.Error("Entity not found") + } + Bval, _ = strconv.Atoi(string(Bvalbytes)) + + // Perform the execution + X, err = strconv.Atoi(args[2]) + if err != nil { + return shim.Error("Invalid transaction amount, expecting a integer value") + } + Aval = Aval - X + Bval = Bval + X + fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) + + // Write the state back to the ledger + err = stub.PutState(A, []byte(strconv.Itoa(Aval))) + if err != nil { + return shim.Error(err.Error()) + } + + err = stub.PutState(B, []byte(strconv.Itoa(Bval))) + if err != nil { + return shim.Error(err.Error()) + } + + return shim.Success(nil) +} + +// Deletes an entity from state +func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response { + if len(args) != 1 { + return shim.Error("Incorrect number of arguments. Expecting 1") + } + + A := args[0] + + // Delete the key from the state in ledger + err := stub.DelState(A) + if err != nil { + return shim.Error("Failed to delete state") + } + + return shim.Success(nil) +} + +// query callback representing the query of a chaincode +func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response { + var A string // Entities + var err error + + if len(args) != 1 { + return shim.Error("Incorrect number of arguments. Expecting name of the person to query") + } + + A = args[0] + + // Get the state from the ledger + Avalbytes, err := stub.GetState(A) + if err != nil { + jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}" + return shim.Error(jsonResp) + } + + if Avalbytes == nil { + jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}" + return shim.Error(jsonResp) + } + + jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}" + fmt.Printf("Query Response:%s\n", jsonResp) + return shim.Success(Avalbytes) +} + +// respond simply generates a response payload from the args +func (t *SimpleChaincode) respond(stub shim.ChaincodeStubInterface, args []string) pb.Response { + if len(args) != 3 { + return shim.Error("expected three arguments") + } + + status, err := strconv.ParseInt(args[0], 10, 32) + if err != nil { + return shim.Error(err.Error()) + } + message := args[1] + payload := []byte(args[2]) + + return pb.Response{ + Status: int32(status), + Message: message, + Payload: payload, + } +} + +func main() { + err := shim.Start(new(SimpleChaincode)) + if err != nil { + fmt.Fprintf(os.Stderr, "Exiting SimpleChaincode: %s", err) + os.Exit(2) + } +} diff --git a/integration/lifecycle/testdata/docker-compose.yaml b/integration/lifecycle/testdata/docker-compose.yaml new file mode 100644 index 00000000000..abbc1f0fc6c --- /dev/null +++ b/integration/lifecycle/testdata/docker-compose.yaml @@ -0,0 +1,17 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +version: '2' +services: + cli: + container_name: cli + image: hyperledger/fabric-tools:1.4 + tty: true + stdin_open: true + working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer + command: /bin/bash + volumes: + - /var/run/:/host/var/run/ + - ./chaincode/:/opt/gopath/src/github.com/chaincode diff --git a/integration/lifecycle/testdata/mycc-0_0-v14.cds b/integration/lifecycle/testdata/mycc-0_0-v14.cds new file mode 100644 index 00000000000..b53cb4aec10 Binary files /dev/null and b/integration/lifecycle/testdata/mycc-0_0-v14.cds differ