github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/core/ledger/kvledger/example/marble_app.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 example
    18  
    19  import (
    20  	"encoding/json"
    21  	"errors"
    22  	"strconv"
    23  	"strings"
    24  
    25  	ledger "github.com/hyperledger/fabric/core/ledger"
    26  
    27  	"github.com/hyperledger/fabric/protos/common"
    28  	logging "github.com/op/go-logging"
    29  )
    30  
    31  var logger = logging.MustGetLogger("example")
    32  
    33  // App - a sample fund transfer app
    34  type MarbleApp struct {
    35  	name   string
    36  	ledger ledger.PeerLedger
    37  }
    38  
    39  // ConstructAppInstance constructs an instance of an app
    40  func ConstructMarbleAppInstance(ledger ledger.PeerLedger) *MarbleApp {
    41  	return &MarbleApp{"marbles_app", ledger}
    42  }
    43  
    44  var marbleIndexStr = "_marbleindex" //name for the key/value that will store a list of all known marbles
    45  var openTradesStr = "_opentrades"   //name for the key/value that will store all open trades
    46  
    47  type Marble struct {
    48  	Name  string `json:"asset_name"` //the fieldtags are needed to keep case from bouncing around
    49  	Color string `json:"color"`
    50  	Size  int    `json:"size"`
    51  	User  string `json:"owner"`
    52  	Rev   string `json:"_rev"`
    53  	Txid  string `json:"txid"`
    54  }
    55  
    56  // CreateMarble simulates init transaction
    57  func (marbleApp *MarbleApp) CreateMarble(args []string) (*common.Envelope, error) {
    58  	//   0       1       2     3
    59  	// "asdf", "blue", "35", "bob"
    60  	logger.Debugf("Entering ----------CreateMarble()----------")
    61  	marbleName := args[0]
    62  	marbleJsonBytes, err := init_marble(args)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  
    67  	var txSimulator ledger.TxSimulator
    68  	if txSimulator, err = marbleApp.ledger.NewTxSimulator(); err != nil {
    69  		return nil, err
    70  	}
    71  	defer txSimulator.Done()
    72  
    73  	txSimulator.SetState(marbleApp.name, marbleName, marbleJsonBytes)
    74  
    75  	var txSimulationResults []byte
    76  	if txSimulationResults, err = txSimulator.GetTxSimulationResults(); err != nil {
    77  		return nil, err
    78  	}
    79  	logger.Debugf("CreateMarble() simulation done, packaging into a transaction...")
    80  	tx := constructTransaction(txSimulationResults)
    81  	logger.Debugf("Exiting CreateMarble()")
    82  	return tx, nil
    83  }
    84  
    85  // ============================================================================================================================
    86  // Init Marble - create a new marble, store into chaincode state
    87  // ============================================================================================================================
    88  func init_marble(args []string) ([]byte, error) {
    89  	var err error
    90  
    91  	//   0       1       2     3
    92  	// "asdf", "blue", "35", "bob"
    93  	if len(args) != 4 {
    94  		return nil, errors.New("Incorrect number of arguments. Expecting 4")
    95  	}
    96  
    97  	logger.Debugf("Entering init marble")
    98  	if len(args[0]) <= 0 {
    99  		return nil, errors.New("1st argument must be a non-empty string")
   100  	}
   101  	if len(args[1]) <= 0 {
   102  		return nil, errors.New("2nd argument must be a non-empty string")
   103  	}
   104  	if len(args[2]) <= 0 {
   105  		return nil, errors.New("3rd argument must be a non-empty string")
   106  	}
   107  	if len(args[3]) <= 0 {
   108  		return nil, errors.New("4th argument must be a non-empty string")
   109  	}
   110  
   111  	size, err := strconv.Atoi(args[2])
   112  	if err != nil {
   113  		return nil, errors.New("3rd argument must be a numeric string")
   114  	}
   115  
   116  	color := strings.ToLower(args[1])
   117  	user := strings.ToLower(args[3])
   118  
   119  	tx := "tx000000000000001" // COUCHDB hardcode a txid for now for demo purpose
   120  	marbleJson := `{"txid": "` + tx + `",  "asset_name": "` + args[0] + `", "color": "` + color + `", "size": ` + strconv.Itoa(size) + `, "owner": "` + user + `"}`
   121  	marbleBytes := []byte(marbleJson)
   122  
   123  	logger.Debugf("Exiting init marble")
   124  	return marbleBytes, nil
   125  }
   126  
   127  // TransferMarble simulates transfer transaction
   128  func (marbleApp *MarbleApp) TransferMarble(args []string) (*common.Envelope, error) {
   129  	//   0       1
   130  	// "name", "bob"
   131  	if len(args) < 2 {
   132  		return nil, errors.New("Incorrect number of arguments. Expecting 2")
   133  	}
   134  	marbleName := args[0]
   135  	marbleNewOwner := args[1]
   136  
   137  	logger.Debugf("Entering ----------TransferMarble----------")
   138  	var txSimulator ledger.TxSimulator
   139  	var err error
   140  	if txSimulator, err = marbleApp.ledger.NewTxSimulator(); err != nil {
   141  		return nil, err
   142  	}
   143  	defer txSimulator.Done()
   144  
   145  	marbleBytes, err := txSimulator.GetState(marbleApp.name, marbleName)
   146  	logger.Debugf("marbleBytes is: %v", marbleBytes)
   147  	if marbleBytes != nil {
   148  		jsonString := string(marbleBytes[:])
   149  		logger.Debugf("TransferMarble() Retrieved jsonString: \n   %s", jsonString)
   150  	}
   151  
   152  	theMarble := Marble{}
   153  	json.Unmarshal(marbleBytes, &theMarble) //Unmarshal JSON bytes into a Marble struct
   154  
   155  	logger.Debugf(" theMarble after unmarshal: %v", theMarble)
   156  
   157  	logger.Debugf(" Setting the owner to: %s", marbleNewOwner)
   158  	theMarble.User = marbleNewOwner      //change the user
   159  	theMarble.Txid = "tx000000000000002" // COUCHDB hardcode a txid for now for demo purpose
   160  
   161  	updatedMarbleBytes, _ := json.Marshal(theMarble)
   162  	if updatedMarbleBytes != nil {
   163  		updatedJsonString := string(updatedMarbleBytes[:])
   164  		logger.Debugf("updatedJsonString:\n   %s", updatedJsonString)
   165  	}
   166  	err = txSimulator.SetState(marbleApp.name, marbleName, updatedMarbleBytes)
   167  	if err != nil {
   168  		return nil, err
   169  	}
   170  
   171  	var txSimulationResults []byte
   172  	if txSimulationResults, err = txSimulator.GetTxSimulationResults(); err != nil {
   173  		return nil, err
   174  	}
   175  	logger.Debugf("TransferMarble() simulation done, packaging into a transaction...")
   176  	tx := constructTransaction(txSimulationResults)
   177  	return tx, nil
   178  }