// Use Entry Credits. Note Entry Credit balances are maintained // as entry credits, not Factoids. But adding is done in Factoids, using // done in Entry Credits. Using lowers the Entry Credit Balance. func (fs *AssetState) UseECs(address fct.IAddress, amount uint64) error { balance := fs.GetBalance(address) - amount if balance < 0 { return fmt.Errorf("Overdraft of Entry Credits attempted.") } fs.database.PutRaw([]byte(fct.DB_EC_BALANCES), address.Bytes(), &state.FSbalance{Number: balance}) return nil }
// Any address that is not defined has a zero balance. func (fs *AssetState) GetECBalance(address fct.IAddress) uint64 { balance := uint64(0) b := fs.database.GetRaw([]byte(fct.DB_EC_BALANCES), address.Bytes()) if b != nil { balance = b.(*state.FSbalance).Number } return balance }
// Any address that is not defined has a zero balance. func (fs *FactoidState) GetBalance(address fct.IAddress) uint64 { balance := uint64(0) b := fs.database.GetRaw([]byte(fct.DB_F_BALANCES), address.Bytes()) if b != nil { balance = b.(*FSbalance).number } return balance }
// Update ec balance throws an error if your update will drive the balance negative. func (fs *AssetState) UpdateECBalance(address fct.IAddress, amount int64) error { nbalance := int64(fs.GetBalance(address)) + amount if nbalance < 0 { return fmt.Errorf("New balance cannot be negative") } balance := uint64(nbalance) fs.database.PutRaw([]byte(fct.DB_EC_BALANCES), address.Bytes(), &state.FSbalance{Number: balance}) return nil }
// Update ec balance throws an error if your update will drive the balance negative. func (fs *FactoidState) UpdateECBalance(address fct.IAddress, amount int64) error { nbalance := int64(fs.GetECBalance(address)) + amount if nbalance < 0 { return fmt.Errorf("The update to this Entry Credit address would drive the balance negative.") } balance := uint64(nbalance) fs.database.PutRaw([]byte(fct.DB_EC_BALANCES), address.Bytes(), &FSbalance{number: balance}) return nil }
func (AddInput) Execute(state IState, args []string) error { if len(args) != 4 { return fmt.Errorf("Invalid Parameters") } key := args[1] adr := args[2] amt := args[3] ib := state.GetFS().GetDB().GetRaw([]byte(fct.DB_BUILD_TRANS), []byte(key)) trans, ok := ib.(fct.ITransaction) if ib == nil || !ok { return fmt.Errorf("Unknown Transaction: " + key) } var addr fct.IAddress if !fct.ValidateFUserStr(adr) { if len(adr) != 64 { if len(adr) > 32 { return fmt.Errorf("Invalid Name. Check the address or name for proper entry.", len(adr)) } we := state.GetFS().GetDB().GetRaw([]byte(fct.W_NAME), []byte(adr)) if we != nil { we2 := we.(wallet.IWalletEntry) addr, _ = we2.GetAddress() adr = hex.EncodeToString(addr.Bytes()) } else { return fmt.Errorf("Name is undefined.") } } else { badr, err := hex.DecodeString(adr) if err != nil { return fmt.Errorf("Looks like an Invalid hex address. Check that you entered it correctly") } addr = fct.NewAddress(badr) } } else { fmt.Printf("adr: %x\n", adr) addr = fct.NewAddress(fct.ConvertUserStrToAddress(adr)) } amount, _ := fct.ConvertFixedPoint(amt) bamount, _ := strconv.ParseInt(amount, 10, 64) err := state.GetFS().GetWallet().AddInput(trans, addr, uint64(bamount)) if err != nil { return err } fmt.Println("Added Input of ", amt, " to be paid from ", args[2], fct.ConvertFctAddressToUserStr(addr)) return nil }
func (w *SCWallet) getWalletEntry(bucket []byte, address fct.IAddress) (IWalletEntry, fct.IAddress, error) { v := w.db.GetRaw([]byte(fct.W_RCD_ADDRESS_HASH), address.Bytes()) if v == nil { return nil, nil, fmt.Errorf("Unknown address") } we := v.(*WalletEntry) adr, err := we.GetAddress() if err != nil { return nil, nil, err } return we, adr, nil }
func (w *SCWallet) AddInput(trans fct.ITransaction, address fct.IAddress, amount uint64) error { // Check if this is an address we know. we, adr, err := w.getWalletEntry([]byte(fct.W_RCD_ADDRESS_HASH), address) // If it isn't, we assume the user knows what they are doing. if we == nil || err != nil { rcd := fct.NewRCD_1(address.Bytes()) trans.AddRCD(rcd) adr, err := rcd.GetAddress() if err != nil { return err } trans.AddInput(fct.CreateAddress(adr), amount) } else { trans.AddRCD(we.GetRCD()) trans.AddInput(fct.CreateAddress(adr), amount) } return nil }
func SilentAddInput(txKey string, inputAddress string, inputSize string) error { ib := myState.GetFS().GetDB().GetRaw([]byte(fct.DB_BUILD_TRANS), []byte(txKey)) trans, ok := ib.(fct.ITransaction) if ib == nil || !ok { return fmt.Errorf("Unknown Transaction: " + txKey) } var addr fct.IAddress if !fct.ValidateFUserStr(inputAddress) { if len(inputAddress) != 64 { if len(inputAddress) > 32 { return fmt.Errorf("Invalid Name. Check the address or name for proper entry.", len(inputAddress)) } we := myState.GetFS().GetDB().GetRaw([]byte(fct.W_NAME), []byte(inputAddress)) if we != nil { we2 := we.(wallet.IWalletEntry) addr, _ = we2.GetAddress() inputAddress = hex.EncodeToString(addr.Bytes()) } else { return fmt.Errorf("Name is undefined.") } } else { badr, err := hex.DecodeString(inputAddress) if err != nil { return fmt.Errorf("Looks like an Invalid hex address. Check that you entered it correctly.") } addr = fct.NewAddress(badr) } } else { //fmt.Printf("adr: %x\n",adr) addr = fct.NewAddress(fct.ConvertUserStrToAddress(inputAddress)) } amount, _ := fct.ConvertFixedPoint(inputSize) bamount, _ := strconv.ParseInt(amount, 10, 64) err := myState.GetFS().GetWallet().AddInput(trans, addr, uint64(bamount)) if err != nil { return err } return nil }
func SilentAddECOutput(txKey string, outputAddress string, outputSize string) error { ib := myState.GetFS().GetDB().GetRaw([]byte(fct.DB_BUILD_TRANS), []byte(txKey)) trans, ok := ib.(fct.ITransaction) if ib == nil || !ok { return fmt.Errorf("Unknown Transaction") } var addr fct.IAddress if !fct.ValidateECUserStr(outputAddress) { if len(outputAddress) != 64 { if len(outputAddress) > 32 { return fmt.Errorf("Invalid Address or Name. Check that you entered it correctly.") } we := myState.GetFS().GetDB().GetRaw([]byte(fct.W_NAME), []byte(outputAddress)) if we != nil { we2 := we.(wallet.IWalletEntry) addr, _ = we2.GetAddress() outputAddress = hex.EncodeToString(addr.Bytes()) } else { return fmt.Errorf("Name is undefined.") } } else { if badHexChar.FindStringIndex(outputAddress) != nil { return fmt.Errorf("Looks like an invalid hex address. Check that you entered it correctly.") } } } else { addr = fct.NewAddress(fct.ConvertUserStrToAddress(outputAddress)) } amount, _ := fct.ConvertFixedPoint(outputSize) bamount, _ := strconv.ParseInt(amount, 10, 64) err := myState.GetFS().GetWallet().AddECOutput(trans, addr, uint64(bamount)) if err != nil { return err } return nil }
func (AddFee) Execute(state IState, args []string) (err error) { if len(args) != 3 && len(args) != 4 { return fmt.Errorf("Invalid Parameters") } key := args[1] adr := args[2] rate := int64(0) if len(args) == 4 { srate, err := fct.ConvertFixedPoint(args[3]) if err != nil { return fmt.Errorf("Could not parse exchange rate: %v", err) } rate, err = strconv.ParseInt(srate, 10, 64) } else { if rate, err = GetRate(state); err != nil { return fmt.Errorf("Could not reach the server to get the exchange rate") } } ib := state.GetFS().GetDB().GetRaw([]byte(fct.DB_BUILD_TRANS), []byte(key)) trans, ok := ib.(fct.ITransaction) if ib == nil || !ok { return fmt.Errorf("Unknown Transaction") } var addr fct.IAddress if fct.ValidateFUserStr(adr) { addr = fct.NewAddress(fct.ConvertUserStrToAddress(adr)) } else if Utility.IsValidHexAddress(adr) { badr, _ := hex.DecodeString(adr) addr = fct.NewAddress(badr) } else if Utility.IsValidNickname(adr) { we := state.GetFS().GetDB().GetRaw([]byte(fct.W_NAME), []byte(adr)) if we != nil { we2 := we.(wallet.IWalletEntry) addr, _ = we2.GetAddress() adr = hex.EncodeToString(addr.Bytes()) } else { return fmt.Errorf("Name is undefined.") } } fee, err := trans.CalculateFee(uint64(rate)) var tin, tout, tec uint64 if tin, err = trans.TotalInputs(); err != nil { return err } if tout, err = trans.TotalOutputs(); err != nil { return err } if tec, err = trans.TotalECs(); err != nil { return err } if tin != tout+tec { msg := fmt.Sprintf("%s Total Inputs\n", fct.ConvertDecimal(tin)) msg += fmt.Sprintf("%s Total Outputs and Entry Credits\n", fct.ConvertDecimal(tout+tec)) msg += fmt.Sprintf("\nThe Inputs must match the outputs to use AddFee to add the fee to an input") return fmt.Errorf(msg) } for _, input := range trans.GetInputs() { if bytes.Equal(input.GetAddress().Bytes(), addr.Bytes()) { input.SetAmount(input.GetAmount() + fee) fmt.Printf("Added fee of %v\n", strings.TrimSpace(fct.ConvertDecimal(fee))) break } } return nil }
// Add to Entry Credit Balance. Note Entry Credit balances are maintained // as entry credits, not Factoids. But adding is done in Factoids, using // done in Entry Credits. Using lowers the Entry Credit Balance. func (fs *FactoidState) AddToECBalance(address fct.IAddress, amount uint64) error { ecs := amount / fs.GetFactoshisPerEC() balance := fs.GetECBalance(address) + ecs fs.database.PutRaw([]byte(fct.DB_EC_BALANCES), address.Bytes(), &FSbalance{number: balance}) return nil }