github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/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  type Marble struct {
    45  	Name  string `json:"asset_name"` //the fieldtags are needed to keep case from bouncing around
    46  	Color string `json:"color"`
    47  	Size  int    `json:"size"`
    48  	User  string `json:"owner"`
    49  	Rev   string `json:"_rev"`
    50  	Txid  string `json:"txid"`
    51  }
    52  
    53  // CreateMarble simulates init transaction
    54  func (marbleApp *MarbleApp) CreateMarble(args []string) (*common.Envelope, error) {
    55  	//   0       1       2     3
    56  	// "asdf", "blue", "35", "bob"
    57  	logger.Debugf("Entering ----------CreateMarble()----------")
    58  	marbleName := args[0]
    59  	marbleJsonBytes, err := init_marble(args)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	var txSimulator ledger.TxSimulator
    65  	if txSimulator, err = marbleApp.ledger.NewTxSimulator(); err != nil {
    66  		return nil, err
    67  	}
    68  	defer txSimulator.Done()
    69  
    70  	txSimulator.SetState(marbleApp.name, marbleName, marbleJsonBytes)
    71  
    72  	var txSimulationResults []byte
    73  	if txSimulationResults, err = txSimulator.GetTxSimulationResults(); err != nil {
    74  		return nil, err
    75  	}
    76  	logger.Debugf("CreateMarble() simulation done, packaging into a transaction...")
    77  	tx := constructTransaction(txSimulationResults)
    78  	logger.Debugf("Exiting CreateMarble()")
    79  	return tx, nil
    80  }
    81  
    82  // ============================================================================================================================
    83  // Init Marble - create a new marble, store into chaincode state
    84  // ============================================================================================================================
    85  func init_marble(args []string) ([]byte, error) {
    86  	var err error
    87  
    88  	//   0       1       2     3
    89  	// "asdf", "blue", "35", "bob"
    90  	if len(args) != 4 {
    91  		return nil, errors.New("Incorrect number of arguments. Expecting 4")
    92  	}
    93  
    94  	logger.Debugf("Entering init marble")
    95  	if len(args[0]) <= 0 {
    96  		return nil, errors.New("1st argument must be a non-empty string")
    97  	}
    98  	if len(args[1]) <= 0 {
    99  		return nil, errors.New("2nd argument must be a non-empty string")
   100  	}
   101  	if len(args[2]) <= 0 {
   102  		return nil, errors.New("3rd argument must be a non-empty string")
   103  	}
   104  	if len(args[3]) <= 0 {
   105  		return nil, errors.New("4th argument must be a non-empty string")
   106  	}
   107  
   108  	size, err := strconv.Atoi(args[2])
   109  	if err != nil {
   110  		return nil, errors.New("3rd argument must be a numeric string")
   111  	}
   112  
   113  	color := strings.ToLower(args[1])
   114  	user := strings.ToLower(args[3])
   115  
   116  	tx := "tx000000000000001" // COUCHDB hardcode a txid for now for demo purpose
   117  	marbleJson := `{"txid": "` + tx + `",  "asset_name": "` + args[0] + `", "color": "` + color + `", "size": ` + strconv.Itoa(size) + `, "owner": "` + user + `"}`
   118  	marbleBytes := []byte(marbleJson)
   119  
   120  	logger.Debugf("Exiting init marble")
   121  	return marbleBytes, nil
   122  }
   123  
   124  // TransferMarble simulates transfer transaction
   125  func (marbleApp *MarbleApp) TransferMarble(args []string) (*common.Envelope, error) {
   126  	//   0       1
   127  	// "name", "bob"
   128  	if len(args) < 2 {
   129  		return nil, errors.New("Incorrect number of arguments. Expecting 2")
   130  	}
   131  	marbleName := args[0]
   132  	marbleNewOwner := args[1]
   133  
   134  	logger.Debugf("Entering ----------TransferMarble----------")
   135  	var txSimulator ledger.TxSimulator
   136  	var err error
   137  	if txSimulator, err = marbleApp.ledger.NewTxSimulator(); err != nil {
   138  		return nil, err
   139  	}
   140  	defer txSimulator.Done()
   141  
   142  	marbleBytes, err := txSimulator.GetState(marbleApp.name, marbleName)
   143  	logger.Debugf("marbleBytes is: %v", marbleBytes)
   144  	if marbleBytes != nil {
   145  		jsonString := string(marbleBytes[:])
   146  		logger.Debugf("TransferMarble() Retrieved jsonString: \n   %s", jsonString)
   147  	}
   148  
   149  	theMarble := Marble{}
   150  	json.Unmarshal(marbleBytes, &theMarble) //Unmarshal JSON bytes into a Marble struct
   151  
   152  	logger.Debugf(" theMarble after unmarshal: %v", theMarble)
   153  
   154  	logger.Debugf(" Setting the owner to: %s", marbleNewOwner)
   155  	theMarble.User = marbleNewOwner      //change the user
   156  	theMarble.Txid = "tx000000000000002" // COUCHDB hardcode a txid for now for demo purpose
   157  
   158  	updatedMarbleBytes, _ := json.Marshal(theMarble)
   159  	if updatedMarbleBytes != nil {
   160  		updatedJsonString := string(updatedMarbleBytes[:])
   161  		logger.Debugf("updatedJsonString:\n   %s", updatedJsonString)
   162  	}
   163  	err = txSimulator.SetState(marbleApp.name, marbleName, updatedMarbleBytes)
   164  	if err != nil {
   165  		return nil, err
   166  	}
   167  
   168  	var txSimulationResults []byte
   169  	if txSimulationResults, err = txSimulator.GetTxSimulationResults(); err != nil {
   170  		return nil, err
   171  	}
   172  	logger.Debugf("TransferMarble() simulation done, packaging into a transaction...")
   173  	tx := constructTransaction(txSimulationResults)
   174  	return tx, nil
   175  }