github.com/kchristidis/fabric@v1.0.4-0.20171028114726-837acd08cde1/examples/chaincode/go/chaincode_example02/chaincode_example02.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  //WARNING - this chaincode's ID is hard-coded in chaincode_example04 to illustrate one way of
    20  //calling chaincode from a chaincode. If this example is modified, chaincode_example04.go has
    21  //to be modified as well with the new ID of chaincode_example02.
    22  //chaincode_example05 show's how chaincode ID can be passed in as a parameter instead of
    23  //hard-coding.
    24  
    25  import (
    26  	"fmt"
    27  	"strconv"
    28  
    29  	"github.com/hyperledger/fabric/core/chaincode/shim"
    30  	pb "github.com/hyperledger/fabric/protos/peer"
    31  )
    32  
    33  // SimpleChaincode example simple Chaincode implementation
    34  type SimpleChaincode struct {
    35  }
    36  
    37  func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
    38  	fmt.Println("ex02 Init")
    39  	_, args := stub.GetFunctionAndParameters()
    40  	var A, B string    // Entities
    41  	var Aval, Bval int // Asset holdings
    42  	var err error
    43  
    44  	if len(args) != 4 {
    45  		return shim.Error("Incorrect number of arguments. Expecting 4")
    46  	}
    47  
    48  	// Initialize the chaincode
    49  	A = args[0]
    50  	Aval, err = strconv.Atoi(args[1])
    51  	if err != nil {
    52  		return shim.Error("Expecting integer value for asset holding")
    53  	}
    54  	B = args[2]
    55  	Bval, err = strconv.Atoi(args[3])
    56  	if err != nil {
    57  		return shim.Error("Expecting integer value for asset holding")
    58  	}
    59  	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
    60  
    61  	// Write the state to the ledger
    62  	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
    63  	if err != nil {
    64  		return shim.Error(err.Error())
    65  	}
    66  
    67  	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
    68  	if err != nil {
    69  		return shim.Error(err.Error())
    70  	}
    71  
    72  	return shim.Success(nil)
    73  }
    74  
    75  func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
    76  	fmt.Println("ex02 Invoke")
    77  	function, args := stub.GetFunctionAndParameters()
    78  	if function == "invoke" {
    79  		// Make payment of X units from A to B
    80  		return t.invoke(stub, args)
    81  	} else if function == "delete" {
    82  		// Deletes an entity from its state
    83  		return t.delete(stub, args)
    84  	} else if function == "query" {
    85  		// the old "Query" is now implemtned in invoke
    86  		return t.query(stub, args)
    87  	}
    88  
    89  	return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"")
    90  }
    91  
    92  // Transaction makes payment of X units from A to B
    93  func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response {
    94  	var A, B string    // Entities
    95  	var Aval, Bval int // Asset holdings
    96  	var X int          // Transaction value
    97  	var err error
    98  
    99  	if len(args) != 3 {
   100  		return shim.Error("Incorrect number of arguments. Expecting 3")
   101  	}
   102  
   103  	A = args[0]
   104  	B = args[1]
   105  
   106  	// Get the state from the ledger
   107  	// TODO: will be nice to have a GetAllState call to ledger
   108  	Avalbytes, err := stub.GetState(A)
   109  	if err != nil {
   110  		return shim.Error("Failed to get state")
   111  	}
   112  	if Avalbytes == nil {
   113  		return shim.Error("Entity not found")
   114  	}
   115  	Aval, _ = strconv.Atoi(string(Avalbytes))
   116  
   117  	Bvalbytes, err := stub.GetState(B)
   118  	if err != nil {
   119  		return shim.Error("Failed to get state")
   120  	}
   121  	if Bvalbytes == nil {
   122  		return shim.Error("Entity not found")
   123  	}
   124  	Bval, _ = strconv.Atoi(string(Bvalbytes))
   125  
   126  	// Perform the execution
   127  	X, err = strconv.Atoi(args[2])
   128  	if err != nil {
   129  		return shim.Error("Invalid transaction amount, expecting a integer value")
   130  	}
   131  	Aval = Aval - X
   132  	Bval = Bval + X
   133  	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
   134  
   135  	// Write the state back to the ledger
   136  	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
   137  	if err != nil {
   138  		return shim.Error(err.Error())
   139  	}
   140  
   141  	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
   142  	if err != nil {
   143  		return shim.Error(err.Error())
   144  	}
   145  
   146  	return shim.Success(nil)
   147  }
   148  
   149  // Deletes an entity from state
   150  func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response {
   151  	if len(args) != 1 {
   152  		return shim.Error("Incorrect number of arguments. Expecting 1")
   153  	}
   154  
   155  	A := args[0]
   156  
   157  	// Delete the key from the state in ledger
   158  	err := stub.DelState(A)
   159  	if err != nil {
   160  		return shim.Error("Failed to delete state")
   161  	}
   162  
   163  	return shim.Success(nil)
   164  }
   165  
   166  // query callback representing the query of a chaincode
   167  func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response {
   168  	var A string // Entities
   169  	var err error
   170  
   171  	if len(args) != 1 {
   172  		return shim.Error("Incorrect number of arguments. Expecting name of the person to query")
   173  	}
   174  
   175  	A = args[0]
   176  
   177  	// Get the state from the ledger
   178  	Avalbytes, err := stub.GetState(A)
   179  	if err != nil {
   180  		jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
   181  		return shim.Error(jsonResp)
   182  	}
   183  
   184  	if Avalbytes == nil {
   185  		jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
   186  		return shim.Error(jsonResp)
   187  	}
   188  
   189  	jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
   190  	fmt.Printf("Query Response:%s\n", jsonResp)
   191  	return shim.Success(Avalbytes)
   192  }
   193  
   194  func main() {
   195  	err := shim.Start(new(SimpleChaincode))
   196  	if err != nil {
   197  		fmt.Printf("Error starting Simple chaincode: %s", err)
   198  	}
   199  }