func FactoidSignTransaction(key string) error { ok := Utility.IsValidKey(key) if !ok { return fmt.Errorf("Invalid name for transaction") } // Get the transaction trans, err := GetTransaction(key) if err != nil { return fmt.Errorf("Failed to get the transaction") } err = factoidState.GetWallet().Validate(1, trans) if err != nil { return err } valid, err := factoidState.GetWallet().SignInputs(trans) if !valid { return fmt.Errorf("Do not have all the private keys required to sign this transaction\n" + err.Error()) } if err != nil { return err } // Update our map with our new transaction to the same key. Otherwise, all // of our work will go away! factoidState.GetDB().PutRaw([]byte(fct.DB_BUILD_TRANS), []byte(key), trans) return nil }
func FactoidAddOutput(trans fct.ITransaction, key string, address fct.IAddress, amount uint64) error { ok := Utility.IsValidKey(key) if !ok { return fmt.Errorf("Invalid name for transaction") } // First look if this is really an update for _, output := range trans.GetOutputs() { if output.GetAddress().IsSameAs(address) { output.SetAmount(amount) return nil } } // Add our new Output err := factoidState.GetWallet().AddOutput(trans, address, uint64(amount)) if err != nil { return fmt.Errorf("Failed to add output") } // Update our map with our new transaction to the same key. Otherwise, all // of our work will go away! factoidState.GetDB().PutRaw([]byte(fct.DB_BUILD_TRANS), []byte(key), trans) return nil }
func GenerateAddressFromMnemonic(name string, privateKey string) (factoid.IAddress, error) { if Utility.IsValidKey(name) == false { return nil, fmt.Errorf("Invalid name or address") } addr, err := factoidState.GetWallet().GenerateFctAddressFromMnemonic([]byte(name), privateKey, 1, 1) if err != nil { return nil, err } return addr, nil }
func GenerateECAddressFromHumanReadablePrivateKey(name string, privateKey string) (factoid.IAddress, error) { if Utility.IsValidKey(name) == false { return nil, fmt.Errorf("Invalid name or address") } addr, err := factoidState.GetWallet().GenerateECAddressFromHumanReadablePrivateKey([]byte(name), privateKey) if err != nil { return nil, err } return addr, nil }
func GenerateAddress(name string) (factoid.IAddress, error) { ok := Utility.IsValidKey(name) if !ok { return nil, fmt.Errorf("Invalid name or address") } addr, err := factoidState.GetWallet().GenerateFctAddress([]byte(name), 1, 1) if err != nil { return nil, err } return addr, nil }
func FactoidAddFee(trans fct.ITransaction, key string, address fct.IAddress, name string) (uint64, error) { { ins, err := trans.TotalInputs() if err != nil { return 0, err } outs, err := trans.TotalOutputs() if err != nil { return 0, err } ecs, err := trans.TotalECs() if err != nil { return 0, err } if ins != outs+ecs { return 0, fmt.Errorf("Inputs and outputs don't add up") } } ok := Utility.IsValidKey(key) if !ok { return 0, fmt.Errorf("Invalid name for transaction") } fee, err := GetFee() if err != nil { return 0, err } transfee, err := trans.CalculateFee(uint64(fee)) if err != nil { return 0, err } adr, err := factoidState.GetWallet().GetAddressHash(address) if err != nil { return 0, err } for _, input := range trans.GetInputs() { if input.GetAddress().IsSameAs(adr) { amt, err := fct.ValidateAmounts(input.GetAmount(), transfee) if err != nil { return 0, err } input.SetAmount(amt) return transfee, nil } } return 0, fmt.Errorf("%s is not an input to the transaction.", key) }
func HandleFactoidGenerateECAddress(ctx *web.Context, name string) { if Utility.IsValidKey(name) == false { reportResults(ctx, "Name provided is not valid", false) return } adrstr, err := Wallet.GenerateECAddressString(name) if err != nil { reportResults(ctx, err.Error(), false) return } reportResults(ctx, adrstr, true) }
func HandleFactoidGenerateAddressFromMnemonic(ctx *web.Context, params string) { name := ctx.Params["name"] mnemonic := ctx.Params["mnemonic"] if Utility.IsValidKey(name) == false { reportResults(ctx, "Name provided is not valid", false) return } adrstr, err := Wallet.GenerateAddressStringFromMnemonic(name, mnemonic) if err != nil { reportResults(ctx, err.Error(), false) return } reportResults(ctx, adrstr, true) }
func HandleFactoidGenerateECAddressFromHumanReadablePrivateKey(ctx *web.Context, params string) { name := ctx.Params["name"] privateKey := ctx.Params["privateKey"] if Utility.IsValidKey(name) == false { reportResults(ctx, "Name provided is not valid", false) return } adrstr, err := Wallet.GenerateECAddressStringFromHumanReadablePrivateKey(name, privateKey) if err != nil { reportResults(ctx, err.Error(), false) return } reportResults(ctx, adrstr, true) }
func GetTransaction(key string) (trans fct.ITransaction, err error) { ok := Utility.IsValidKey(key) if !ok { return nil, fmt.Errorf("Invalid name or address") } // Now get the transaction. If we don't have a transaction by the given // keys there is nothing we can do. Now we *could* create the transaaction // and tie it to the key. Something to think about. ib := factoidState.GetDB().GetRaw([]byte(fct.DB_BUILD_TRANS), []byte(key)) trans, ok = ib.(fct.ITransaction) if ib == nil || !ok { return nil, fmt.Errorf("Unknown Transaction: %s", key) } return }
func GenerateAddressFromPrivateKey(name string, privateKey string) (factoid.IAddress, error) { if Utility.IsValidKey(name) == false { return nil, fmt.Errorf("Invalid name or address") } if len(privateKey) != 64 && len(privateKey) != 128 { return nil, fmt.Errorf("Invalid private key length") } if Utility.IsValidHex(privateKey) == false { return nil, fmt.Errorf("Invalid private key format") } priv, err := hex.DecodeString(privateKey) if err != nil { return nil, err } addr, err := factoidState.GetWallet().GenerateFctAddressFromPrivateKey([]byte(name), priv, 1, 1) if err != nil { return nil, err } return addr, nil }
// New Transaction: key -- // We create a new transaction, and track it with the user supplied key. The // user can then use this key to make subsequent calls to add inputs, outputs, // and to sign. Then they can submit the transaction. // // When the transaction is submitted, we clear it from our working memory. // Multiple transactions can be under construction at one time, but they need // their own keys. Once a transaction is either submitted or deleted, the key // can be reused. func FactoidNewTransaction(key string) error { // Make sure we have a key if len(key) == 0 { return fmt.Errorf("Missing transaction key") } ok := Utility.IsValidKey(key) if !ok { return fmt.Errorf("Invalid name for transaction") } // Make sure we don't already have a transaction in process with this key t := factoidState.GetDB().GetRaw([]byte(fct.DB_BUILD_TRANS), []byte(key)) if t != nil { return fmt.Errorf("Duplicate key: '%s'", key) } // Create a transaction t = factoidState.GetWallet().CreateTransaction(factoidState.GetTimeMilli()) // Save it with the key factoidState.GetDB().PutRaw([]byte(fct.DB_BUILD_TRANS), []byte(key), t) return nil }
func HandleFactoidGenerateECAddressFromPrivateKey(ctx *web.Context, params string) { name := ctx.Params["name"] privateKey := ctx.Params["privateKey"] if Utility.IsValidKey(name) == false { reportResults(ctx, "Name provided is not valid", false) return } if len(privateKey) != 64 && len(privateKey) != 128 { reportResults(ctx, "Invalid private key length", false) return } if Utility.IsValidHex(privateKey) == false { reportResults(ctx, "Invalid private key format", false) return } adrstr, err := Wallet.GenerateECAddressStringFromPrivateKey(name, privateKey) if err != nil { reportResults(ctx, err.Error(), false) return } reportResults(ctx, adrstr, true) }
func ValidateKey(key string) error { if Utility.IsValidKey(key) { return nil } return fmt.Errorf("Invalid key") }