github.com/suchongming/fabric@v2.1.1+incompatible/integration/lifecycle/testdata/chaincode/simple-v14/chaincode.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package main
     8  
     9  import (
    10  	"fmt"
    11  	"os"
    12  	"strconv"
    13  
    14  	"github.com/hyperledger/fabric/core/chaincode/shim"
    15  	pb "github.com/hyperledger/fabric/protos/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("SimpleChaincode Invoke")
    63  	function, args := stub.GetFunctionAndParameters()
    64  	switch function {
    65  	case "invoke":
    66  		// Make payment of X units from A to B
    67  		return t.invoke(stub, args)
    68  	case "delete":
    69  		// Deletes an entity from its state
    70  		return t.delete(stub, args)
    71  	case "query":
    72  		// the old "Query" is now implemtned in invoke
    73  		return t.query(stub, args)
    74  	case "respond":
    75  		// return with an error
    76  		return t.respond(stub, args)
    77  	default:
    78  		return shim.Error(`Invalid invoke function name. Expecting "invoke", "delete", "query", or "respond"`)
    79  	}
    80  }
    81  
    82  // Transaction makes payment of X units from A to B
    83  func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response {
    84  	var A, B string    // Entities
    85  	var Aval, Bval int // Asset holdings
    86  	var X int          // Transaction value
    87  	var err error
    88  
    89  	if len(args) != 3 {
    90  		return shim.Error("Incorrect number of arguments. Expecting 3")
    91  	}
    92  
    93  	A = args[0]
    94  	B = args[1]
    95  
    96  	// Get the state from the ledger
    97  	// TODO: will be nice to have a GetAllState call to ledger
    98  	Avalbytes, err := stub.GetState(A)
    99  	if err != nil {
   100  		return shim.Error("Failed to get state")
   101  	}
   102  	if Avalbytes == nil {
   103  		return shim.Error("Entity not found")
   104  	}
   105  	Aval, _ = strconv.Atoi(string(Avalbytes))
   106  
   107  	Bvalbytes, err := stub.GetState(B)
   108  	if err != nil {
   109  		return shim.Error("Failed to get state")
   110  	}
   111  	if Bvalbytes == nil {
   112  		return shim.Error("Entity not found")
   113  	}
   114  	Bval, _ = strconv.Atoi(string(Bvalbytes))
   115  
   116  	// Perform the execution
   117  	X, err = strconv.Atoi(args[2])
   118  	if err != nil {
   119  		return shim.Error("Invalid transaction amount, expecting a integer value")
   120  	}
   121  	Aval = Aval - X
   122  	Bval = Bval + X
   123  	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
   124  
   125  	// Write the state back to the ledger
   126  	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
   127  	if err != nil {
   128  		return shim.Error(err.Error())
   129  	}
   130  
   131  	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
   132  	if err != nil {
   133  		return shim.Error(err.Error())
   134  	}
   135  
   136  	return shim.Success(nil)
   137  }
   138  
   139  // Deletes an entity from state
   140  func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response {
   141  	if len(args) != 1 {
   142  		return shim.Error("Incorrect number of arguments. Expecting 1")
   143  	}
   144  
   145  	A := args[0]
   146  
   147  	// Delete the key from the state in ledger
   148  	err := stub.DelState(A)
   149  	if err != nil {
   150  		return shim.Error("Failed to delete state")
   151  	}
   152  
   153  	return shim.Success(nil)
   154  }
   155  
   156  // query callback representing the query of a chaincode
   157  func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response {
   158  	var A string // Entities
   159  	var err error
   160  
   161  	if len(args) != 1 {
   162  		return shim.Error("Incorrect number of arguments. Expecting name of the person to query")
   163  	}
   164  
   165  	A = args[0]
   166  
   167  	// Get the state from the ledger
   168  	Avalbytes, err := stub.GetState(A)
   169  	if err != nil {
   170  		jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
   171  		return shim.Error(jsonResp)
   172  	}
   173  
   174  	if Avalbytes == nil {
   175  		jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
   176  		return shim.Error(jsonResp)
   177  	}
   178  
   179  	jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
   180  	fmt.Printf("Query Response:%s\n", jsonResp)
   181  	return shim.Success(Avalbytes)
   182  }
   183  
   184  // respond simply generates a response payload from the args
   185  func (t *SimpleChaincode) respond(stub shim.ChaincodeStubInterface, args []string) pb.Response {
   186  	if len(args) != 3 {
   187  		return shim.Error("expected three arguments")
   188  	}
   189  
   190  	status, err := strconv.ParseInt(args[0], 10, 32)
   191  	if err != nil {
   192  		return shim.Error(err.Error())
   193  	}
   194  	message := args[1]
   195  	payload := []byte(args[2])
   196  
   197  	return pb.Response{
   198  		Status:  int32(status),
   199  		Message: message,
   200  		Payload: payload,
   201  	}
   202  }
   203  
   204  func main() {
   205  	err := shim.Start(new(SimpleChaincode))
   206  	if err != nil {
   207  		fmt.Fprintf(os.Stderr, "Exiting SimpleChaincode: %s", err)
   208  		os.Exit(2)
   209  	}
   210  }