github.com/inklabsfoundation/inkchain@v0.17.1-0.20181025012015-c3cef8062f19/examples/token/token.go (about)

     1  /*
     2  Copyright Ziggurat Corp. 2017 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package main
     8  
     9  import (
    10  	"encoding/json"
    11  	"fmt"
    12  	"math/big"
    13  	"strconv"
    14  	"strings"
    15  
    16  	"github.com/inklabsfoundation/inkchain/core/chaincode/shim"
    17  	pb "github.com/inklabsfoundation/inkchain/protos/peer"
    18  )
    19  
    20  const (
    21  	//func name
    22  	GetBalance string = "getBalance"
    23  	GetAccount string = "getAccount"
    24  	Transfer   string = "transfer"
    25  	Counter    string = "counter"
    26  	Sender     string = "sender"
    27  	CalcFee    string = "calcFee"
    28  )
    29  
    30  // User chaincode for token operations
    31  // After a token issued, users can use this chaincode to make query or transfer operations.
    32  type tokenChaincode struct {
    33  }
    34  
    35  // Init func
    36  func (t *tokenChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
    37  	fmt.Println("token user chaincode Init.")
    38  	return shim.Success([]byte("Init success."))
    39  }
    40  
    41  // Invoke func
    42  func (t *tokenChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
    43  	fmt.Println("token user chaincode Invoke")
    44  	function, args := stub.GetFunctionAndParameters()
    45  
    46  	switch function {
    47  	case GetBalance:
    48  		if len(args) != 2 {
    49  			return shim.Error("Incorrect number of arguments. Expecting 2.")
    50  		}
    51  		return t.getBalance(stub, args)
    52  
    53  	case GetAccount:
    54  		if len(args) != 1 {
    55  			return shim.Error("Incorrect number of arguments. Expecting 1.")
    56  		}
    57  		return t.getAccount(stub, args)
    58  
    59  	case Transfer:
    60  		if len(args) != 3 {
    61  			return shim.Error("Incorrect number of arguments. Expecting 3")
    62  		}
    63  		return t.transfer(stub, args)
    64  
    65  	case Counter:
    66  		if len(args) != 1 {
    67  			return shim.Error("Incorrect number of arguments. Expecting 1")
    68  		}
    69  		return t.getCounter(stub, args)
    70  
    71  	case Sender:
    72  		sender, err := stub.GetSender()
    73  		if err != nil {
    74  			return shim.Error("Get sender failed.")
    75  		}
    76  		return shim.Success([]byte(sender))
    77  	case CalcFee:
    78  		if len(args) != 1 {
    79  			return shim.Error("Incorrect number of arguments. Expecting 1.")
    80  		}
    81  		return t.calcFee(stub, args)
    82  	}
    83  
    84  	return shim.Error("Invalid invoke function name. Expecting \"getBalance\", \"getAccount\", \"transfer\", \"counter\" , \"sender\" , \"fee\".")
    85  }
    86  
    87  // getBalance
    88  // Get the balance of a specific token type in an account
    89  func (t *tokenChaincode) getBalance(stub shim.ChaincodeStubInterface, args []string) pb.Response {
    90  	var A string           // Address
    91  	var BalanceType string // Token type
    92  	var err error
    93  
    94  	A = strings.ToLower(args[0])
    95  	BalanceType = args[1]
    96  	// Get the state from the ledger
    97  	account, err := stub.GetAccount(A)
    98  	if err != nil {
    99  		return shim.Error("account does not exists")
   100  	}
   101  
   102  	if account == nil || account.Balance[BalanceType] == nil {
   103  		return shim.Error("Nil amount for " + A)
   104  	}
   105  	result := make(map[string]string)
   106  	result[BalanceType] = account.Balance[BalanceType].String()
   107  	balanceJson, jsonErr := json.Marshal(result)
   108  	if jsonErr != nil {
   109  		return shim.Error(jsonErr.Error())
   110  	}
   111  	return shim.Success([]byte(balanceJson))
   112  }
   113  
   114  // getAccount
   115  // Get the balances of all token types in an account
   116  func (t *tokenChaincode) getAccount(stub shim.ChaincodeStubInterface, args []string) pb.Response {
   117  	var A string // Address
   118  	var err error
   119  
   120  	A = strings.ToLower(args[0])
   121  	// Get the state from the ledger
   122  	account, err := stub.GetAccount(A)
   123  	if err != nil {
   124  		return shim.Error("account does not exists")
   125  	}
   126  
   127  	if account == nil {
   128  		return shim.Error("Nil amount for " + A)
   129  	}
   130  	result := make(map[string]string)
   131  	for key, value := range account.Balance {
   132  		result[key] = value.String()
   133  	}
   134  	balanceJson, jsonErr := json.Marshal(result)
   135  	if jsonErr != nil {
   136  		return shim.Error(jsonErr.Error())
   137  	}
   138  	return shim.Success([]byte(balanceJson))
   139  }
   140  
   141  // transfer
   142  // Send tokens to the specified address
   143  func (t *tokenChaincode) transfer(stub shim.ChaincodeStubInterface, args []string) pb.Response {
   144  	var B string           // To address
   145  	var BalanceType string // Token type
   146  	var err error
   147  
   148  	B = strings.ToLower(args[0])
   149  	BalanceType = args[1]
   150  
   151  	// Amount
   152  	amount := big.NewInt(0)
   153  	_, good := amount.SetString(args[2], 10)
   154  	if !good {
   155  		return shim.Error("Expecting integer value for amount")
   156  	}
   157  	err = stub.Transfer(B, BalanceType, amount)
   158  	if err != nil {
   159  		return shim.Error("transfer error" + err.Error())
   160  	}
   161  	return shim.Success(nil)
   162  }
   163  
   164  // counter
   165  // Get current tx counter of an account
   166  func (t *tokenChaincode) getCounter(stub shim.ChaincodeStubInterface, args []string) pb.Response {
   167  	var A string // Address
   168  	var err error
   169  
   170  	A = strings.ToLower(args[0])
   171  	account, err := stub.GetAccount(A)
   172  	if err != nil {
   173  		return shim.Error("account not exists")
   174  	}
   175  
   176  	if account == nil {
   177  		return shim.Error("account not exists for " + A)
   178  	}
   179  	return shim.Success([]byte(strconv.FormatUint(account.Counter, 10)))
   180  }
   181  
   182  func (t *tokenChaincode) calcFee(stub shim.ChaincodeStubInterface, args []string) pb.Response {
   183  	fee, err := stub.CalcFee(string(args[0]))
   184  	if err != nil {
   185  		return shim.Error("Query fee failed.")
   186  	}
   187  	res := map[string]interface{}{
   188  		"fee": fee,
   189  	}
   190  	resJson, err := json.Marshal(res)
   191  	if err != nil {
   192  		return shim.Error(err.Error())
   193  	}
   194  	return shim.Success(resJson)
   195  }
   196  
   197  func main() {
   198  	err := shim.Start(new(tokenChaincode))
   199  	if err != nil {
   200  		fmt.Printf("Error starting tokenChaincode: %s", err)
   201  	}
   202  }