commit 5f8c9bbcc6787211aa4dacf7198cfe8b76a57c92 Author: Crazy Hackerman Date: Sun Nov 11 19:34:56 2018 +0100 add example chaincode diff --git a/chaincode_example02.go b/chaincode_example02.go new file mode 100644 index 0000000..e509d6d --- /dev/null +++ b/chaincode_example02.go @@ -0,0 +1,226 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +package main + +import ( + "errors" + "fmt" + "strconv" + + "github.com/hyperledger/fabric/core/chaincode/shim" +) + +// SimpleChaincode example simple Chaincode implementation +type SimpleChaincode struct { +} + +func (t *SimpleChaincode) Init(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) { + fmt.Printf("Init called, initializing chaincode") + + var A, B string // Entities + var Aval, Bval int // Asset holdings + var err error + + if len(args) != 4 { + return nil, errors.New("Incorrect number of arguments. Expecting 4") + } + + // Initialize the chaincode + A = args[0] + Aval, err = strconv.Atoi(args[1]) + if err != nil { + return nil, errors.New("Expecting integer value for asset holding") + } + B = args[2] + Bval, err = strconv.Atoi(args[3]) + if err != nil { + return nil, errors.New("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 nil, err + } + + err = stub.PutState(B, []byte(strconv.Itoa(Bval))) + if err != nil { + return nil, err + } + + return nil, nil +} + +// Transaction makes payment of X units from A to B +func (t *SimpleChaincode) invoke(stub *shim.ChaincodeStub, args []string) ([]byte, error) { + fmt.Printf("Running invoke") + + var A, B string // Entities + var Aval, Bval int // Asset holdings + var X int // Transaction value + var err error + + if len(args) != 3 { + return nil, errors.New("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 nil, errors.New("Failed to get state") + } + if Avalbytes == nil { + return nil, errors.New("Entity not found") + } + Aval, _ = strconv.Atoi(string(Avalbytes)) + + Bvalbytes, err := stub.GetState(B) + if err != nil { + return nil, errors.New("Failed to get state") + } + if Bvalbytes == nil { + return nil, errors.New("Entity not found") + } + Bval, _ = strconv.Atoi(string(Bvalbytes)) + + // Perform the execution + X, err = strconv.Atoi(args[2]) + 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 nil, err + } + + err = stub.PutState(B, []byte(strconv.Itoa(Bval))) + if err != nil { + return nil, err + } + + return nil, nil +} + +// Deletes an entity from state +func (t *SimpleChaincode) delete(stub *shim.ChaincodeStub, args []string) ([]byte, error) { + fmt.Printf("Running delete") + + if len(args) != 1 { + return nil, errors.New("Incorrect number of arguments. Expecting 3") + } + + A := args[0] + + // Delete the key from the state in ledger + err := stub.DelState(A) + if err != nil { + return nil, errors.New("Failed to delete state") + } + + return nil, nil +} + +// Invoke callback representing the invocation of a chaincode +// This chaincode will manage two accounts A and B and will transfer X units from A to B upon invoke +func (t *SimpleChaincode) Invoke(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) { + fmt.Printf("Invoke called, determining function") + + // Handle different functions + if function == "invoke" { + // Transaction makes payment of X units from A to B + fmt.Printf("Function is invoke") + return t.invoke(stub, args) + } else if function == "init" { + fmt.Printf("Function is init") + return t.Init(stub, function, args) + } else if function == "delete" { + // Deletes an entity from its state + fmt.Printf("Function is delete") + return t.delete(stub, args) + } + + return nil, errors.New("Received unknown function invocation") +} + +func (t* SimpleChaincode) Run(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) { + fmt.Printf("Run called, passing through to Invoke (same function)") + + // Handle different functions + if function == "invoke" { + // Transaction makes payment of X units from A to B + fmt.Printf("Function is invoke") + return t.invoke(stub, args) + } else if function == "init" { + fmt.Printf("Function is init") + return t.Init(stub, function, args) + } else if function == "delete" { + // Deletes an entity from its state + fmt.Printf("Function is delete") + return t.delete(stub, args) + } + + return nil, errors.New("Received unknown function invocation") +} + +// Query callback representing the query of a chaincode +func (t *SimpleChaincode) Query(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) { + fmt.Printf("Query called, determining function") + + if function != "query" { + fmt.Printf("Function is query") + return nil, errors.New("Invalid query function name. Expecting \"query\"") + } + var A string // Entities + var err error + + if len(args) != 1 { + return nil, errors.New("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 nil, errors.New(jsonResp) + } + + if Avalbytes == nil { + jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}" + return nil, errors.New(jsonResp) + } + + jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}" + fmt.Printf("Query Response:%s\n", jsonResp) + return Avalbytes, nil +} + +func main() { + err := shim.Start(new(SimpleChaincode)) + if err != nil { + fmt.Printf("Error starting Simple chaincode: %s", err) + } +} \ No newline at end of file