// Invoke function func (t *EventSender) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { b, err := stub.GetState("noevents") if err != nil { return nil, errors.New("Failed to get state") } noevts, _ := strconv.Atoi(string(b)) tosend := "Event " + string(b) for _, s := range args { tosend = tosend + "," + s } err = stub.PutState("noevents", []byte(strconv.Itoa(noevts+1))) if err != nil { return nil, err } err = stub.SetEvent("evtsender", []byte(tosend)) if err != nil { return nil, err } return nil, nil }
// Transaction makes payment of X units from A to B func (t *ChaincodeExample) MakePayment(stub shim.ChaincodeStubInterface, param *example02.PaymentParams) error { var err error // Get the state from the ledger src, err := t.GetState(stub, param.PartySrc) if err != nil { return err } dst, err := t.GetState(stub, param.PartyDst) if err != nil { return err } // Perform the execution X := int(param.Amount) src = src - X dst = dst + X fmt.Printf("Aval = %d, Bval = %d\n", src, dst) // Write the state back to the ledger err = stub.PutState(param.PartySrc, []byte(strconv.Itoa(src))) if err != nil { return err } err = stub.PutState(param.PartyDst, []byte(strconv.Itoa(dst))) if err != nil { return err } return nil }
// Invoke gets the supplied key and if it exists, updates the key with the newly // supplied value. func (t *SampleSysCC) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { var key, val string // Entities if len(args) != 2 { return nil, errors.New("need 2 args (key and a value)") } // Initialize the chaincode key = args[0] val = args[1] _, err := stub.GetState(key) if err != nil { jsonResp := "{\"Error\":\"Failed to get val for " + key + "\"}" return nil, errors.New(jsonResp) } // Write the state to the ledger err = stub.PutState(key, []byte(val)) if err != nil { return nil, err } return nil, nil }
// Transaction makes payment of X units from A to B func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { if function == "delete" { // Deletes an entity from its state return t.delete(stub, args) } var A, B string // Entities var Aval, Bval int // Asset holdings var X int // Transaction value var err error if len(args) != 3 { return nil, errors.New("Incorrect number of arguments. Expecting 3") } A = args[0] B = args[1] // Get the state from the ledger // TODO: will be nice to have a GetAllState call to ledger Avalbytes, err := stub.GetState(A) if err != nil { return nil, errors.New("Failed to get state") } if Avalbytes == nil { return nil, errors.New("Entity not found") } Aval, _ = strconv.Atoi(string(Avalbytes)) Bvalbytes, err := stub.GetState(B) if err != nil { return nil, errors.New("Failed to get state") } if Bvalbytes == nil { return nil, errors.New("Entity not found") } Bval, _ = strconv.Atoi(string(Bvalbytes)) // Perform the execution X, err = strconv.Atoi(args[2]) if err != nil { return nil, errors.New("Invalid transaction amount, expecting a integer value") } Aval = Aval - X Bval = Bval + X fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) // Write the state back to the ledger err = stub.PutState(A, []byte(strconv.Itoa(Aval))) if err != nil { return nil, err } err = stub.PutState(B, []byte(strconv.Itoa(Bval))) if err != nil { return nil, err } return nil, nil }
// ============================================================================================================================ // Set User Permission on Marble // ============================================================================================================================ func (t *SimpleChaincode) set_user(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { var err error // 0 1 // "name", "bob" if len(args) < 2 { return nil, errors.New("Incorrect number of arguments. Expecting 2") } fmt.Println("- start set user") fmt.Println(args[0] + " - " + args[1]) marbleAsBytes, err := stub.GetState(args[0]) if err != nil { return nil, errors.New("Failed to get thing") } res := Marble{} json.Unmarshal(marbleAsBytes, &res) //un stringify it aka JSON.parse() res.User = args[1] //change the user jsonAsBytes, _ := json.Marshal(res) err = stub.PutState(args[0], jsonAsBytes) //rewrite the marble with id as key if err != nil { return nil, err } fmt.Println("- end set user") return nil, nil }
// Invoke has two functions // put - takes two arguements, a key and value, and stores them in the state // remove - takes one argument, a key, and removes if from the state func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { switch function { case "put": if len(args) < 2 { return nil, errors.New("put operation must include two arguments, a key and value") } key := args[0] value := args[1] err := stub.PutState(key, []byte(value)) if err != nil { fmt.Printf("Error putting state %s", err) return nil, fmt.Errorf("put operation failed. Error updating state: %s", err) } return nil, nil case "remove": if len(args) < 1 { return nil, errors.New("remove operation must include one argument, a key") } key := args[0] err := stub.DelState(key) if err != nil { return nil, fmt.Errorf("remove operation failed. Error updating state: %s", err) } return nil, nil default: return nil, errors.New("Unsupported operation") } }
// ============================================================================================================================ // Delete - remove a key/value pair from state // ============================================================================================================================ func (t *SimpleChaincode) Delete(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { if len(args) != 1 { return nil, errors.New("Incorrect number of arguments. Expecting 1") } name := args[0] err := stub.DelState(name) //remove the key from chaincode state if err != nil { return nil, errors.New("Failed to delete state") } //get the marble index marblesAsBytes, err := stub.GetState(marbleIndexStr) if err != nil { return nil, errors.New("Failed to get marble index") } var marbleIndex []string json.Unmarshal(marblesAsBytes, &marbleIndex) //un stringify it aka JSON.parse() //remove marble from index for i, val := range marbleIndex { fmt.Println(strconv.Itoa(i) + " - looking at " + val + " for " + name) if val == name { //find the correct marble fmt.Println("found marble") marbleIndex = append(marbleIndex[:i], marbleIndex[i+1:]...) //remove it for x := range marbleIndex { //debug prints... fmt.Println(string(x) + " - " + marbleIndex[x]) } break } } jsonAsBytes, _ := json.Marshal(marbleIndex) //save new index err = stub.PutState(marbleIndexStr, jsonAsBytes) return nil, nil }
// Init takes two arguments, a string and int. The string will be a key with // the int as a value. func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) ([]byte, error) { var sum string // Sum of asset holdings across accounts. Initially 0 var sumVal int // Sum of holdings var err error _, args := stub.GetFunctionAndParameters() if len(args) != 2 { return nil, errors.New("Incorrect number of arguments. Expecting 2") } // Initialize the chaincode sum = args[0] sumVal, err = strconv.Atoi(args[1]) if err != nil { return nil, errors.New("Expecting integer value for sum") } fmt.Printf("sumVal = %d\n", sumVal) // Write the state to the ledger err = stub.PutState(sum, []byte(strconv.Itoa(sumVal))) if err != nil { return nil, err } return nil, nil }
// Init initialization func (t *AssetManagementChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { myLogger.Info("[AssetManagementChaincode] Init") if len(args) != 0 { return nil, errors.New("Incorrect number of arguments. Expecting 0") } // Create ownership table err := stub.CreateTable("AssetsOwnership", []*shim.ColumnDefinition{ &shim.ColumnDefinition{Name: "Asset", Type: shim.ColumnDefinition_STRING, Key: true}, &shim.ColumnDefinition{Name: "Owner", Type: shim.ColumnDefinition_BYTES, Key: false}, }) if err != nil { return nil, fmt.Errorf("Failed creating AssetsOnwership table, [%v]", err) } // Set the role of the users that are allowed to assign assets // The metadata will contain the role of the users that are allowed to assign assets assignerRole, err := stub.GetCallerMetadata() fmt.Printf("Assiger role is %v\n", string(assignerRole)) if err != nil { return nil, fmt.Errorf("Failed getting metadata, [%v]", err) } if len(assignerRole) == 0 { return nil, errors.New("Invalid assigner role. Empty.") } stub.PutState("assignerRole", assignerRole) return nil, nil }
// Init method will be called during deployment. // The deploy transaction metadata is supposed to contain the administrator cert func (t *AssetManagementChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { myLogger.Debug("Init Chaincode...") if len(args) != 0 { return nil, errors.New("Incorrect number of arguments. Expecting 0") } // Create ownership table err := stub.CreateTable("AssetsOwnership", []*shim.ColumnDefinition{ &shim.ColumnDefinition{Name: "Asset", Type: shim.ColumnDefinition_STRING, Key: true}, &shim.ColumnDefinition{Name: "Owner", Type: shim.ColumnDefinition_BYTES, Key: false}, }) if err != nil { return nil, errors.New("Failed creating AssetsOnwership table.") } // Set the admin // The metadata will contain the certificate of the administrator adminCert, err := stub.GetCallerMetadata() if err != nil { myLogger.Debug("Failed getting metadata") return nil, errors.New("Failed getting metadata.") } if len(adminCert) == 0 { myLogger.Debug("Invalid admin certificate. Empty.") return nil, errors.New("Invalid admin certificate. Empty.") } myLogger.Debug("The administrator is [%x]", adminCert) stub.PutState("admin", adminCert) myLogger.Debug("Init Chaincode...done") return nil, nil }
// Invoke invokes another chaincode - chaincode_example02, upon receipt of an event and changes event state func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { var event string // Event entity var eventVal string // State of event var err error var amount int event = args[0] eventVal = args[1] chainCodeToCall := args[2] // Get the chaincode to call from the ledger if eventVal == "middleSchool" { amount = 2000 } else { amount = 5000 } // 转账操作 invokeArgs := util.ToChaincodeArgs("transferAcc", args[3], args[4], strconv.Itoa(amount)) response, err := stub.InvokeChaincode(chainCodeToCall, invokeArgs) if err != nil { errStr := fmt.Sprintf("Failed to invoke chaincode. Got error: %s", err.Error()) fmt.Printf(errStr) return nil, errors.New(errStr) } fmt.Printf("Invoke chaincode successful. Got response %s", string(response)) // Write the event state back to the ledger err = stub.PutState(event, []byte(args[1])) if err != nil { return nil, err } return nil, nil }
// Init takes a string and int. These are stored as a key/value pair in the state func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) ([]byte, error) { var A string // Entity var Aval int // Asset holding var err error _, args := stub.GetFunctionAndParameters() if len(args) != 2 { return nil, errors.New("Incorrect number of arguments. Expecting 2") } // Initialize the chaincode A = args[0] Aval, err = strconv.Atoi(args[1]) if err != nil { return nil, errors.New("Expecting integer value for asset holding") } fmt.Printf("Aval = %d\n", Aval) // Write the state to the ledger - this put is legal within Run err = stub.PutState(A, []byte(strconv.Itoa(Aval))) if err != nil { return nil, err } return nil, nil }
func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { var A string // Entity var Aval int // Asset holding var err error if len(args) != 2 { return nil, errors.New("Incorrect number of arguments. Expecting 2") } A = args[0] Aval, err = strconv.Atoi(args[1]) if err != nil { return nil, errors.New("Expecting integer value for asset holding") } fmt.Printf("Aval = %d\n", Aval) // Write the state to the ledger - this put is illegal within Run err = stub.PutState(A, []byte(strconv.Itoa(Aval))) if err != nil { jsonResp := "{\"Error\":\"Cannot put state within chaincode query\"}" return nil, errors.New(jsonResp) } fmt.Printf("Something is wrong. This query should not have succeeded") return nil, nil }
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { var A, B string // Entities var Aval, Bval int // Asset holdings var err error if len(args) != 4 { return nil, errors.New("Incorrect number of arguments. Expecting 4") } // Initialize the chaincode A = args[0] Aval, err = strconv.Atoi(args[1]) if err != nil { return nil, errors.New("Expecting integer value for asset holding") } B = args[2] Bval, err = strconv.Atoi(args[3]) if err != nil { return nil, errors.New("Expecting integer value for asset holding") } fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) // Write the state to the ledger err = stub.PutState(A, []byte(strconv.Itoa(Aval))) if err != nil { return nil, err } err = stub.PutState(B, []byte(strconv.Itoa(Bval))) if err != nil { return nil, err } return nil, nil }
// Init function func (t *EventSender) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { err := stub.PutState("noevents", []byte("0")) if err != nil { return nil, err } return nil, nil }
// Invoke queries another chaincode and updates its own state func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { var sum string // Sum entity var Aval, Bval, sumVal int // value of sum entity - to be computed var err error if len(args) != 2 { return nil, errors.New("Incorrect number of arguments. Expecting 2") } chaincodeURL := args[0] // Expecting "github.com/hyperledger/fabric/core/example/chaincode/chaincode_example02" sum = args[1] // Query chaincode_example02 f := "query" queryArgs := util.ToChaincodeArgs(f, "a") response, err := stub.InvokeChaincode(chaincodeURL, queryArgs) if err != nil { errStr := fmt.Sprintf("Failed to query chaincode. Got error: %s", err.Error()) fmt.Printf(errStr) return nil, errors.New(errStr) } Aval, err = strconv.Atoi(string(response)) if err != nil { errStr := fmt.Sprintf("Error retrieving state from ledger for queried chaincode: %s", err.Error()) fmt.Printf(errStr) return nil, errors.New(errStr) } queryArgs = util.ToChaincodeArgs(f, "b") response, err = stub.InvokeChaincode(chaincodeURL, queryArgs) if err != nil { errStr := fmt.Sprintf("Failed to query chaincode. Got error: %s", err.Error()) fmt.Printf(errStr) return nil, errors.New(errStr) } Bval, err = strconv.Atoi(string(response)) if err != nil { errStr := fmt.Sprintf("Error retrieving state from ledger for queried chaincode: %s", err.Error()) fmt.Printf(errStr) return nil, errors.New(errStr) } // Compute sum sumVal = Aval + Bval // Write sumVal back to the ledger err = stub.PutState(sum, []byte(strconv.Itoa(sumVal))) if err != nil { return nil, err } fmt.Printf("Invoke chaincode successful. Got sum %d\n", sumVal) return []byte(strconv.Itoa(sumVal)), nil }
// Invoke gets the supplied key and if it exists, updates the key with the newly // supplied value. func (t *SampleSysCC) Invoke(stub shim.ChaincodeStubInterface) ([]byte, error) { f, args := stub.GetFunctionAndParameters() switch f { case "putval": if len(args) != 2 { return nil, errors.New("need 2 args (key and a value)") } // Initialize the chaincode key := args[0] val := args[1] _, err := stub.GetState(key) if err != nil { jsonResp := "{\"Error\":\"Failed to get val for " + key + "\"}" return nil, errors.New(jsonResp) } // Write the state to the ledger err = stub.PutState(key, []byte(val)) return nil, err case "getval": var err error if len(args) != 1 { return nil, errors.New("Incorrect number of arguments. Expecting key to query") } key := args[0] // Get the state from the ledger valbytes, err := stub.GetState(key) if err != nil { jsonResp := "{\"Error\":\"Failed to get state for " + key + "\"}" return nil, errors.New(jsonResp) } if valbytes == nil { jsonResp := "{\"Error\":\"Nil val for " + key + "\"}" return nil, errors.New(jsonResp) } return valbytes, nil default: jsonResp := "{\"Error\":\"Unknown functon " + f + "\"}" return nil, errors.New(jsonResp) } }
// ============================================================================================================================ // Write - write variable into chaincode state // ============================================================================================================================ func (t *SimpleChaincode) Write(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { var name, value string // Entities var err error fmt.Println("running write()") if len(args) != 2 { return nil, errors.New("Incorrect number of arguments. Expecting 2. name of the variable and value to set") } name = args[0] //rename for funsies value = args[1] err = stub.PutState(name, []byte(value)) //write the variable into the chaincode state if err != nil { return nil, err } return nil, nil }
func (t *Attributes2State) setStateToAttributes(stub shim.ChaincodeStubInterface, args []string) error { attrHandler, err := attr.NewAttributesHandlerImpl(stub) if err != nil { return err } for _, att := range args { fmt.Println("Writing attribute " + att) attVal, err := attrHandler.GetValue(att) if err != nil { return err } err = stub.PutState(att, attVal) if err != nil { return err } } return nil }
// Invoke invokes another chaincode - chaincode_example02, upon receipt of an event and changes event state func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { var event string // Event entity var eventVal int // State of event var err error if len(args) != 2 { return nil, errors.New("Incorrect number of arguments. Expecting 2") } event = args[0] eventVal, err = strconv.Atoi(args[1]) if err != nil { return nil, errors.New("Expected integer value for event state change") } if eventVal != 1 { fmt.Printf("Unexpected event. Doing nothing\n") return nil, nil } // Get the chaincode to call from the ledger chainCodeToCall := t.GetChaincodeToCall() f := "invoke" invokeArgs := util.ToChaincodeArgs(f, "a", "b", "10") response, err := stub.InvokeChaincode(chainCodeToCall, invokeArgs) if err != nil { errStr := fmt.Sprintf("Failed to invoke chaincode. Got error: %s", err.Error()) fmt.Printf(errStr) return nil, errors.New(errStr) } fmt.Printf("Invoke chaincode successful. Got response %s", string(response)) // Write the event state back to the ledger err = stub.PutState(event, []byte(strconv.Itoa(eventVal))) if err != nil { return nil, err } return nil, nil }
func (t *RBACChaincode) write(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { if len(args) != 1 { return nil, errors.New("Incorrect number of arguments. Expecting 1") } value := args[0] myLogger.Debug("Write [%s]", value) // Verify that the invoker has the 'writer' role ok, _, err := t.hasInvokerRole(stub, "writer") if err != nil { return nil, fmt.Errorf("Failed checking role [%s]", err) } if !ok { return nil, errors.New("The invoker does not have the required roles.") } return nil, stub.PutState("state", []byte(value)) }
//Invoke makes increment counter func (t *AuthorizableCounterChaincode) increment(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { val, err := stub.ReadCertAttribute("position") fmt.Printf("Position => %v error %v \n", string(val), err) isOk, _ := stub.VerifyAttribute("position", []byte("Software Engineer")) // Here the ABAC API is called to verify the attribute, just if the value is verified the counter will be incremented. if isOk { counter, err := stub.GetState("counter") if err != nil { return nil, err } var cInt int cInt, err = strconv.Atoi(string(counter)) if err != nil { return nil, err } cInt = cInt + 1 counter = []byte(strconv.Itoa(cInt)) stub.PutState("counter", counter) } return nil, nil }
// ============================================================================================================================ // Remove Open Trade - close an open trade // ============================================================================================================================ func (t *SimpleChaincode) remove_trade(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { var err error // 0 //[data.id] if len(args) < 1 { return nil, errors.New("Incorrect number of arguments. Expecting 1") } fmt.Println("- start remove trade") timestamp, err := strconv.ParseInt(args[0], 10, 64) if err != nil { return nil, errors.New("1st argument must be a numeric string") } //get the open trade struct tradesAsBytes, err := stub.GetState(openTradesStr) if err != nil { return nil, errors.New("Failed to get opentrades") } var trades AllTrades json.Unmarshal(tradesAsBytes, &trades) //un stringify it aka JSON.parse() for i := range trades.OpenTrades { //look for the trade //fmt.Println("looking at " + strconv.FormatInt(trades.OpenTrades[i].Timestamp, 10) + " for " + strconv.FormatInt(timestamp, 10)) if trades.OpenTrades[i].Timestamp == timestamp { fmt.Println("found the trade") trades.OpenTrades = append(trades.OpenTrades[:i], trades.OpenTrades[i+1:]...) //remove this trade jsonAsBytes, _ := json.Marshal(trades) err = stub.PutState(openTradesStr, jsonAsBytes) //rewrite open orders if err != nil { return nil, err } break } } fmt.Println("- end remove trade") return nil, nil }
// Init takes two arguements, a string and int. These are stored in the key/value pair in the state func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { var event string // Indicates whether event has happened. Initially 0 var eventVal int // State of event var err error if len(args) != 2 { return nil, errors.New("Incorrect number of arguments. Expecting 2") } // Initialize the chaincode event = args[0] eventVal, err = strconv.Atoi(args[1]) if err != nil { return nil, errors.New("Expecting integer value for event status") } fmt.Printf("eventVal = %d\n", eventVal) err = stub.PutState(event, []byte(strconv.Itoa(eventVal))) if err != nil { return nil, err } return nil, nil }
// ============================================================================================================================ // Init - reset all the things // ============================================================================================================================ func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { var Aval int var err error if len(args) != 1 { return nil, errors.New("Incorrect number of arguments. Expecting 1") } // Initialize the chaincode Aval, err = strconv.Atoi(args[0]) if err != nil { return nil, errors.New("Expecting integer value for asset holding") } // Write the state to the ledger err = stub.PutState("abc", []byte(strconv.Itoa(Aval))) //making a test var "abc", I find it handy to read/write to it right away to test the network if err != nil { return nil, err } var empty []string jsonAsBytes, _ := json.Marshal(empty) //marshal an emtpy array of strings to clear the index err = stub.PutState(marbleIndexStr, jsonAsBytes) if err != nil { return nil, err } var trades AllTrades jsonAsBytes, _ = json.Marshal(trades) //clear the open trade struct err = stub.PutState(openTradesStr, jsonAsBytes) if err != nil { return nil, err } return nil, nil }
// Transaction makes payment of X units from A to B func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { if function == "delete" { // Deletes an entity from its state return t.delete(stub, args) } if function == "createAccNO" { accNO := args[0] var amount int var err error if 1 == len(args) { amount = 0 } else { amount, err = strconv.Atoi(args[1]) if err != nil { return nil, errors.New("Expecting integer value for asset holding") } } err = stub.PutState(accNO, []byte(strconv.Itoa(amount))) if err != nil { return nil, err } } if function == "transferAcc" { if len(args) != 3 { return nil, errors.New("Incorrect number of arguments. Expecting 3") } srcAcc := args[0] // 转出户名 tarAcc := args[1] // 转入户名 amount, err := strconv.Atoi(args[2]) // 金额 // 获取A的余额 srcAccvalbytes, err := stub.GetState(srcAcc) if err != nil { return nil, errors.New("Failed to get state") } if srcAccvalbytes == nil { return nil, errors.New("Entity not found") } srcAccVal, _ := strconv.Atoi(string(srcAccvalbytes)) // 获取B的月 tarAccvalbytes, err := stub.GetState(tarAcc) if err != nil { return nil, errors.New("Failed to get state") } if tarAccvalbytes == nil { return nil, errors.New("Entity not found") } tarAccVal, _ := strconv.Atoi(string(tarAccvalbytes)) srcAccVal -= amount tarAccVal += amount // Write the state back to the ledger err = stub.PutState(srcAcc, []byte(strconv.Itoa(srcAccVal))) if err != nil { return nil, err } err = stub.PutState(tarAcc, []byte(strconv.Itoa(tarAccVal))) if err != nil { return nil, err } } if function == "ECashPrinter" { accNO := args[0] // 转出户名 amount, err := strconv.Atoi(args[1]) // 金额 // 获取A的余额 accValbytes, err := stub.GetState(accNO) if err != nil { return nil, errors.New("Failed to get state") } if accValbytes == nil { return nil, errors.New("Entity not found") } accVal, _ := strconv.Atoi(string(accValbytes)) accVal += amount // Write the state back to the ledger err = stub.PutState(accNO, []byte(strconv.Itoa(accVal))) if err != nil { return nil, err } } return nil, nil }
// ============================================================================================================================ // Clean Up Open Trades - make sure open trades are still possible, remove choices that are no longer possible, remove trades that have no valid choices // ============================================================================================================================ func cleanTrades(stub shim.ChaincodeStubInterface) (err error) { var didWork = false fmt.Println("- start clean trades") //get the open trade struct tradesAsBytes, err := stub.GetState(openTradesStr) if err != nil { return errors.New("Failed to get opentrades") } var trades AllTrades json.Unmarshal(tradesAsBytes, &trades) //un stringify it aka JSON.parse() fmt.Println("# trades " + strconv.Itoa(len(trades.OpenTrades))) for i := 0; i < len(trades.OpenTrades); { //iter over all the known open trades fmt.Println(strconv.Itoa(i) + ": looking at trade " + strconv.FormatInt(trades.OpenTrades[i].Timestamp, 10)) fmt.Println("# options " + strconv.Itoa(len(trades.OpenTrades[i].Willing))) for x := 0; x < len(trades.OpenTrades[i].Willing); { //find a marble that is suitable fmt.Println("! on next option " + strconv.Itoa(i) + ":" + strconv.Itoa(x)) _, e := findMarble4Trade(stub, trades.OpenTrades[i].User, trades.OpenTrades[i].Willing[x].Color, trades.OpenTrades[i].Willing[x].Size) if e != nil { fmt.Println("! errors with this option, removing option") didWork = true trades.OpenTrades[i].Willing = append(trades.OpenTrades[i].Willing[:x], trades.OpenTrades[i].Willing[x+1:]...) //remove this option x-- } else { fmt.Println("! this option is fine") } x++ fmt.Println("! x:" + strconv.Itoa(x)) if x >= len(trades.OpenTrades[i].Willing) { //things might have shifted, recalcuate break } } if len(trades.OpenTrades[i].Willing) == 0 { fmt.Println("! no more options for this trade, removing trade") didWork = true trades.OpenTrades = append(trades.OpenTrades[:i], trades.OpenTrades[i+1:]...) //remove this trade i-- } i++ fmt.Println("! i:" + strconv.Itoa(i)) if i >= len(trades.OpenTrades) { //things might have shifted, recalcuate break } } if didWork { fmt.Println("! saving open trade changes") jsonAsBytes, _ := json.Marshal(trades) err = stub.PutState(openTradesStr, jsonAsBytes) //rewrite open orders if err != nil { return err } } else { fmt.Println("! all open trades are fine") } fmt.Println("- end clean trades") return nil }
// ============================================================================================================================ // Perform Trade - close an open trade and move ownership // ============================================================================================================================ func (t *SimpleChaincode) perform_trade(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { var err error // 0 1 2 3 4 5 //[data.id, data.closer.user, data.closer.name, data.opener.user, data.opener.color, data.opener.size] if len(args) < 6 { return nil, errors.New("Incorrect number of arguments. Expecting 6") } fmt.Println("- start close trade") timestamp, err := strconv.ParseInt(args[0], 10, 64) if err != nil { return nil, errors.New("1st argument must be a numeric string") } size, err := strconv.Atoi(args[5]) if err != nil { return nil, errors.New("6th argument must be a numeric string") } //get the open trade struct tradesAsBytes, err := stub.GetState(openTradesStr) if err != nil { return nil, errors.New("Failed to get opentrades") } var trades AllTrades json.Unmarshal(tradesAsBytes, &trades) //un stringify it aka JSON.parse() for i := range trades.OpenTrades { //look for the trade fmt.Println("looking at " + strconv.FormatInt(trades.OpenTrades[i].Timestamp, 10) + " for " + strconv.FormatInt(timestamp, 10)) if trades.OpenTrades[i].Timestamp == timestamp { fmt.Println("found the trade") marbleAsBytes, err := stub.GetState(args[2]) if err != nil { return nil, errors.New("Failed to get thing") } closersMarble := Marble{} json.Unmarshal(marbleAsBytes, &closersMarble) //un stringify it aka JSON.parse() //verify if marble meets trade requirements if closersMarble.Color != trades.OpenTrades[i].Want.Color || closersMarble.Size != trades.OpenTrades[i].Want.Size { msg := "marble in input does not meet trade requriements" fmt.Println(msg) return nil, errors.New(msg) } marble, e := findMarble4Trade(stub, trades.OpenTrades[i].User, args[4], size) //find a marble that is suitable from opener if e == nil { fmt.Println("! no errors, proceeding") t.set_user(stub, []string{args[2], trades.OpenTrades[i].User}) //change owner of selected marble, closer -> opener t.set_user(stub, []string{marble.Name, args[1]}) //change owner of selected marble, opener -> closer trades.OpenTrades = append(trades.OpenTrades[:i], trades.OpenTrades[i+1:]...) //remove trade jsonAsBytes, _ := json.Marshal(trades) err = stub.PutState(openTradesStr, jsonAsBytes) //rewrite open orders if err != nil { return nil, err } } } } fmt.Println("- end close trade") return nil, nil }
// ============================================================================================================================ // Init Marble - create a new marble, store into chaincode state // ============================================================================================================================ func (t *SimpleChaincode) init_marble(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { var err error // 0 1 2 3 // "asdf", "blue", "35", "bob" if len(args) != 4 { return nil, errors.New("Incorrect number of arguments. Expecting 4") } //input sanitation fmt.Println("- start init marble") if len(args[0]) <= 0 { return nil, errors.New("1st argument must be a non-empty string") } if len(args[1]) <= 0 { return nil, errors.New("2nd argument must be a non-empty string") } if len(args[2]) <= 0 { return nil, errors.New("3rd argument must be a non-empty string") } if len(args[3]) <= 0 { return nil, errors.New("4th argument must be a non-empty string") } name := args[0] color := strings.ToLower(args[1]) user := strings.ToLower(args[3]) size, err := strconv.Atoi(args[2]) if err != nil { return nil, errors.New("3rd argument must be a numeric string") } //check if marble already exists marbleAsBytes, err := stub.GetState(name) if err != nil { return nil, errors.New("Failed to get marble name") } res := Marble{} json.Unmarshal(marbleAsBytes, &res) if res.Name == name { fmt.Println("This marble arleady exists: " + name) fmt.Println(res) return nil, errors.New("This marble arleady exists") //all stop a marble by this name exists } //build the marble json string manually str := `{"name": "` + name + `", "color": "` + color + `", "size": ` + strconv.Itoa(size) + `, "user": "******"}` err = stub.PutState(name, []byte(str)) //store marble with id as key if err != nil { return nil, err } //get the marble index marblesAsBytes, err := stub.GetState(marbleIndexStr) if err != nil { return nil, errors.New("Failed to get marble index") } var marbleIndex []string json.Unmarshal(marblesAsBytes, &marbleIndex) //un stringify it aka JSON.parse() //append marbleIndex = append(marbleIndex, name) //add marble name to index list fmt.Println("! marble index: ", marbleIndex) jsonAsBytes, _ := json.Marshal(marbleIndex) err = stub.PutState(marbleIndexStr, jsonAsBytes) //store name of marble fmt.Println("- end init marble") return nil, nil }
// ============================================================================================================================ // Open Trade - create an open trade for a marble you want with marbles you have // ============================================================================================================================ func (t *SimpleChaincode) open_trade(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { var err error var will_size int var trade_away Description // 0 1 2 3 4 5 6 //["bob", "blue", "16", "red", "16"] *"blue", "35* if len(args) < 5 { return nil, errors.New("Incorrect number of arguments. Expecting like 5?") } if len(args)%2 == 0 { return nil, errors.New("Incorrect number of arguments. Expecting an odd number") } size1, err := strconv.Atoi(args[2]) if err != nil { return nil, errors.New("3rd argument must be a numeric string") } open := AnOpenTrade{} open.User = args[0] open.Timestamp = makeTimestamp() //use timestamp as an ID open.Want.Color = args[1] open.Want.Size = size1 fmt.Println("- start open trade") jsonAsBytes, _ := json.Marshal(open) err = stub.PutState("_debug1", jsonAsBytes) for i := 3; i < len(args); i++ { //create and append each willing trade will_size, err = strconv.Atoi(args[i+1]) if err != nil { msg := "is not a numeric string " + args[i+1] fmt.Println(msg) return nil, errors.New(msg) } trade_away = Description{} trade_away.Color = args[i] trade_away.Size = will_size fmt.Println("! created trade_away: " + args[i]) jsonAsBytes, _ = json.Marshal(trade_away) err = stub.PutState("_debug2", jsonAsBytes) open.Willing = append(open.Willing, trade_away) fmt.Println("! appended willing to open") i++ } //get the open trade struct tradesAsBytes, err := stub.GetState(openTradesStr) if err != nil { return nil, errors.New("Failed to get opentrades") } var trades AllTrades json.Unmarshal(tradesAsBytes, &trades) //un stringify it aka JSON.parse() trades.OpenTrades = append(trades.OpenTrades, open) //append to open trades fmt.Println("! appended open to trades") jsonAsBytes, _ = json.Marshal(trades) err = stub.PutState(openTradesStr, jsonAsBytes) //rewrite open orders if err != nil { return nil, err } fmt.Println("- end open trade") return nil, nil }