github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/examples/chaincode/go/chaincode_example05/chaincode_example05.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  import (
    20  	"fmt"
    21  	"strconv"
    22  
    23  	"github.com/hyperledger/fabric/common/util"
    24  	"github.com/hyperledger/fabric/core/chaincode/shim"
    25  	pb "github.com/hyperledger/fabric/protos/peer"
    26  )
    27  
    28  // This chaincode is a test for chaincode querying another chaincode - invokes chaincode_example02 and computes the sum of a and b and stores it as state
    29  
    30  // SimpleChaincode example simple Chaincode implementation
    31  type SimpleChaincode struct {
    32  }
    33  
    34  // Init takes two arguments, a string and int. The string will be a key with
    35  // the int as a value.
    36  func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
    37  	var sum string // Sum of asset holdings across accounts. Initially 0
    38  	var sumVal int // Sum of holdings
    39  	var err error
    40  	_, args := stub.GetFunctionAndParameters()
    41  	if len(args) != 2 {
    42  		return shim.Error("Incorrect number of arguments. Expecting 2")
    43  	}
    44  
    45  	// Initialize the chaincode
    46  	sum = args[0]
    47  	sumVal, err = strconv.Atoi(args[1])
    48  	if err != nil {
    49  		return shim.Error("Expecting integer value for sum")
    50  	}
    51  	fmt.Printf("sumVal = %d\n", sumVal)
    52  
    53  	// Write the state to the ledger
    54  	err = stub.PutState(sum, []byte(strconv.Itoa(sumVal)))
    55  	if err != nil {
    56  		return shim.Error(err.Error())
    57  	}
    58  
    59  	return shim.Success(nil)
    60  }
    61  
    62  // Invoke queries another chaincode and updates its own state
    63  func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response {
    64  	var sum, channelName string // Sum entity
    65  	var Aval, Bval, sumVal int  // value of sum entity - to be computed
    66  	var err error
    67  
    68  	if len(args) < 2 {
    69  		return shim.Error("Incorrect number of arguments. Expecting atleast 2")
    70  	}
    71  
    72  	chaincodeName := args[0] // Expecting name of the chaincode you would like to call, this name would be given during chaincode install time
    73  	sum = args[1]
    74  
    75  	if len(args) > 2 {
    76  		channelName = args[2]
    77  	} else {
    78  		channelName = ""
    79  	}
    80  
    81  	// Query chaincode_example02
    82  	f := "query"
    83  	queryArgs := util.ToChaincodeArgs(f, "a")
    84  
    85  	//   if chaincode being invoked is on the same channel,
    86  	//   then channel defaults to the current channel and args[2] can be "".
    87  	//   If the chaincode being called is on a different channel,
    88  	//   then you must specify the channel name in args[2]
    89  
    90  	response := stub.InvokeChaincode(chaincodeName, queryArgs, channelName)
    91  	if response.Status != shim.OK {
    92  		errStr := fmt.Sprintf("Failed to query chaincode. Got error: %s", response.Payload)
    93  		fmt.Printf(errStr)
    94  		return shim.Error(errStr)
    95  	}
    96  	Aval, err = strconv.Atoi(string(response.Payload))
    97  	if err != nil {
    98  		errStr := fmt.Sprintf("Error retrieving state from ledger for queried chaincode: %s", err.Error())
    99  		fmt.Printf(errStr)
   100  		return shim.Error(errStr)
   101  	}
   102  
   103  	queryArgs = util.ToChaincodeArgs(f, "b")
   104  	response = stub.InvokeChaincode(chaincodeName, queryArgs, channelName)
   105  	if response.Status != shim.OK {
   106  		errStr := fmt.Sprintf("Failed to query chaincode. Got error: %s", response.Payload)
   107  		fmt.Printf(errStr)
   108  		return shim.Error(errStr)
   109  	}
   110  	Bval, err = strconv.Atoi(string(response.Payload))
   111  	if err != nil {
   112  		errStr := fmt.Sprintf("Error retrieving state from ledger for queried chaincode: %s", err.Error())
   113  		fmt.Printf(errStr)
   114  		return shim.Error(errStr)
   115  	}
   116  
   117  	// Compute sum
   118  	sumVal = Aval + Bval
   119  
   120  	// Write sumVal back to the ledger
   121  	err = stub.PutState(sum, []byte(strconv.Itoa(sumVal)))
   122  	if err != nil {
   123  		return shim.Error(err.Error())
   124  	}
   125  
   126  	fmt.Printf("Invoke chaincode successful. Got sum %d\n", sumVal)
   127  	return shim.Success([]byte(strconv.Itoa(sumVal)))
   128  }
   129  
   130  func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response {
   131  	var sum, channelName string // Sum entity
   132  	var Aval, Bval, sumVal int  // value of sum entity - to be computed
   133  	var err error
   134  
   135  	if len(args) < 2 {
   136  		return shim.Error("Incorrect number of arguments. Expecting atleast 2")
   137  	}
   138  
   139  	chaincodeName := args[0] // Expecting name of the chaincode you would like to call, this name would be given during chaincode install time
   140  	sum = args[1]
   141  
   142  	if len(args) > 2 {
   143  		channelName = args[2]
   144  	} else {
   145  		channelName = ""
   146  	}
   147  
   148  	// Query chaincode_example02
   149  	f := "query"
   150  	queryArgs := util.ToChaincodeArgs(f, "a")
   151  
   152  	//   if chaincode being invoked is on the same channel,
   153  	//   then channel defaults to the current channel and args[2] can be "".
   154  	//   If the chaincode being called is on a different channel,
   155  	//   then you must specify the channel name in args[2]
   156  	response := stub.InvokeChaincode(chaincodeName, queryArgs, channelName)
   157  	if response.Status != shim.OK {
   158  		errStr := fmt.Sprintf("Failed to query chaincode. Got error: %s", response.Payload)
   159  		fmt.Printf(errStr)
   160  		return shim.Error(errStr)
   161  	}
   162  	Aval, err = strconv.Atoi(string(response.Payload))
   163  	if err != nil {
   164  		errStr := fmt.Sprintf("Error retrieving state from ledger for queried chaincode: %s", err.Error())
   165  		fmt.Printf(errStr)
   166  		return shim.Error(errStr)
   167  	}
   168  
   169  	queryArgs = util.ToChaincodeArgs(f, "b")
   170  	response = stub.InvokeChaincode(chaincodeName, queryArgs, channelName)
   171  	if response.Status != shim.OK {
   172  		errStr := fmt.Sprintf("Failed to query chaincode. Got error: %s", response.Payload)
   173  		fmt.Printf(errStr)
   174  		return shim.Error(errStr)
   175  	}
   176  	Bval, err = strconv.Atoi(string(response.Payload))
   177  	if err != nil {
   178  		errStr := fmt.Sprintf("Error retrieving state from ledger for queried chaincode: %s", err.Error())
   179  		fmt.Printf(errStr)
   180  		return shim.Error(errStr)
   181  	}
   182  
   183  	// Compute sum
   184  	sumVal = Aval + Bval
   185  
   186  	fmt.Printf("Query chaincode successful. Got sum %d\n", sumVal)
   187  	jsonResp := "{\"Name\":\"" + sum + "\",\"Value\":\"" + strconv.Itoa(sumVal) + "\"}"
   188  	fmt.Printf("Query Response:%s\n", jsonResp)
   189  	return shim.Success([]byte(strconv.Itoa(sumVal)))
   190  }
   191  
   192  func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
   193  	function, args := stub.GetFunctionAndParameters()
   194  	if function == "invoke" {
   195  		return t.invoke(stub, args)
   196  	} else if function == "query" {
   197  		return t.query(stub, args)
   198  	}
   199  
   200  	return shim.Success([]byte("Invalid invoke function name. Expecting \"invoke\" \"query\""))
   201  }
   202  
   203  func main() {
   204  	err := shim.Start(new(SimpleChaincode))
   205  	if err != nil {
   206  		fmt.Printf("Error starting Simple chaincode: %s", err)
   207  	}
   208  }