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