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 }