Beispiel #1
0
 public void PayOutCancel(SpendTx spend)
 {
     if (spend.ChangeAddress.Length > 0)
     {
         NodeCash.DeleteChangeKey(spend.ChangeAddress);
     }
 }
Beispiel #2
0
        public bool PayAccountBalanceNode(SpendTx spendTx, string accountCode, string cashCodeForChange)
        {
            try
            {
                foreach (var tx in spendTx.Transactions)
                {
                    Money minerFee = tx.MinerFee;

                    for (int i = 0; i < tx.TxIds.Count; i++)
                    {
                        TxId  input    = tx.TxIds[i];
                        Money moneyOut = input.MoneyOut;

                        if (i == tx.TxIds.Count - 1)
                        {
                            moneyOut -= tx.ChangeAmount;
                        }

                        NodeCash.proc_TxPayAccount
                        (
                            tx.PaymentAddress,
                            $"{input.TransactionId}",
                            moneyOut.ToUnit(MoneyUnit.MilliBTC),
                            minerFee.ToUnit(MoneyUnit.MilliBTC),
                            accountCode
                        );

                        minerFee = minerFee <= moneyOut ? Money.Zero : minerFee - moneyOut;
                    }

                    foreach (var output in tx.Tx.Outputs)
                    {
                        string toAddress = $"{output.ScriptPubKey.GetDestinationAddress(GetNetwork)}";
                        if (toAddress == spendTx.ChangeAddress)
                        {
                            string toTxId = $"{tx.Tx.GetHash()}";

                            NodeCash.proc_ChangeTxAdd
                            (
                                toAddress,
                                toTxId,
                                (short)TxStatus.UTXO,
                                output.Value.ToUnit(MoneyUnit.MilliBTC),
                                0,
                                spendTx.TxMessage
                            );

                            NodeCash.proc_TxPayInChange(CashAccountCode, toAddress, toTxId, accountCode, cashCodeForChange, Properties.Resources.PaymentChange);
                        }
                    }
                }

                return(true);
            }
            catch (Exception err)
            {
                Console.WriteLine($"Error: {err.Message}");
                return(false);
            }
        }
Beispiel #3
0
 public void KeyTransferCancel(SpendTx spend)
 {
     NodeCash.DeleteChangeKey(spend.ToAddress);
     if (spend.ChangeAddress.Length > 0)
     {
         NodeCash.DeleteChangeKey(spend.ChangeAddress);
     }
 }
Beispiel #4
0
        public async Task <SpendTx> PayOutTx(AccountKey fromKey, string toAddress, decimal payAmount, int minersRate, string txMessage)
        {
            try
            {
                int?addressIndex = 0;

                string changeAddress  = string.Empty;
                double accountBalance = await KeyNameBalance(fromKey.KeyName);

                if ((decimal)accountBalance > payAmount)
                {
                    changeAddress = NewChangeKey(fromKey.KeyName, fromKey.HDPath, CoinChangeType.Change, ref addressIndex);

                    if (!AddChangeKey(fromKey.KeyName, changeAddress, (int)addressIndex, null))
                    {
                        return(null);
                    }
                }

                string changePath = $"{fromKey.HDPath}{(short)CoinChangeType.Change}/{addressIndex}/";

                Money spendAmount = new Money(payAmount, MoneyUnit.MilliBTC);

                SpendTx spend = new SpendTx(BlockchainApi)
                {
                    ToAddress      = toAddress,
                    ChangeAddress  = changeAddress,
                    FromKey        = fromKey.KeyName,
                    ChangeKey      = fromKey.KeyName,
                    MinerRate      = minersRate,
                    TxMessage      = txMessage,
                    TargetAmount   = spendAmount,
                    AccountBalance = new Money((decimal)accountBalance, MoneyUnit.MilliBTC)
                };

                var keyAddresses = NodeCash.fnKeyAddresses(CashAccountCode, fromKey.KeyName)
                                   .OrderBy(tb => tb.AddressIndex)
                                   .Select(tb => tb);

                foreach (var key in keyAddresses)
                {
                    spend.AddKey(GetExtendedKey(key.HDPath), GetExtendedKey(changePath));

                    if (spend.IsSatisfied)
                    {
                        break;
                    }
                }

                return(spend);
            }
            catch (Exception err)
            {
                Console.WriteLine($"Error: {err.Message}");
                return(null);
            }
        }
Beispiel #5
0
        private async void MiscellaneousPayment()
        {
            try
            {
                PayOutWindow payOut = new PayOutWindow(tcBitcoin, SelectedKey);

                if (payOut.ShowDialog() == true)
                {
                    Cursor = Cursors.Wait;
                    SpendTx spendTx = await tcBitcoin.PayOutTx(SelectedKey, payOut.PaymentAddress,
                                                               payOut.AmountToPay, payOut.MinerRate, payOut.TxMessage);

                    if (!spendTx.IsSatisfied)
                    {
                        MessageBox.Show(Properties.Resources.UnsatisfiedPayment, payOut.Title, MessageBoxButton.OK, MessageBoxImage.Error);
                        tcBitcoin.PayOutCancel(spendTx);
                    }
                    else
                    {
                        Cursor = Cursors.Arrow;
                        SpendConfirmWindow spendDialog = new SpendConfirmWindow(spendTx);

                        if (spendDialog.ShowDialog() == true)
                        {
                            Cursor = Cursors.Wait;

                            bool broadcast = await spendTx.Send();

                            if (broadcast)
                            {
                                if (tcBitcoin.PayOutMiscNode(spendTx, payOut.AccountCode, payOut.CashCode, payOut.TaxCode, payOut.PaymentReference))
                                {
                                    Refresh();
                                    await RefreshBalance();
                                }
                            }
                            else
                            {
                                tcBitcoin.PayOutCancel(spendTx);
                            }
                        }
                        else
                        {
                            tcBitcoin.PayOutCancel(spendTx);
                        }
                    }
                }
            }
            catch (Exception err)
            {
                MessageBox.Show($"{err.Message}", $"{err.Source}.{err.TargetSite.Name}", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            finally
            {
                Cursor = Cursors.Arrow;
            }
        }
Beispiel #6
0
        private async void PayAccount()
        {
            try
            {
                var              invoice    = (vwInvoicedPayments)dgInvoices.SelectedItem;
                AccountKey       accountKey = (AccountKey)tvWallet.SelectedItem;
                PayAccountWindow payAccount = new PayAccountWindow(tcBitcoin, accountKey, invoice);

                if (payAccount.ShowDialog() == true)
                {
                    Cursor = Cursors.Wait;
                    SpendTx spendTx = await tcBitcoin.PayOutTx(accountKey, payAccount.PaymentAddress,
                                                               payAccount.AmountToPay, payAccount.MinerRate, payAccount.TxMessage);

                    if (!spendTx.IsSatisfied)
                    {
                        MessageBox.Show(Properties.Resources.UnsatisfiedPayment, payAccount.Title, MessageBoxButton.OK, MessageBoxImage.Error);
                        tcBitcoin.PayOutCancel(spendTx);
                    }
                    else
                    {
                        Cursor = Cursors.Arrow;
                        SpendConfirmWindow spendDialog = new SpendConfirmWindow(spendTx);

                        if (spendDialog.ShowDialog() == true)
                        {
                            Cursor = Cursors.Wait;

                            bool broadcast = await spendTx.Send();

                            if (broadcast)
                            {
                                if (tcBitcoin.PayAccountBalanceNode(spendTx, invoice.AccountCode, payAccount.CashCodeForChange))
                                {
                                    Refresh();
                                    OnBalance?.Invoke(this, new EventArgs());
                                }
                            }
                        }
                        else
                        {
                            tcBitcoin.PayOutCancel(spendTx);
                        }
                    }
                }
            }
            catch (Exception err)
            {
                MessageBox.Show($"{err.Message}", $"{err.Source}.{err.TargetSite.Name}", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            finally
            {
                Cursor = Cursors.Arrow;
            }
        }
Beispiel #7
0
        private async void KeyTransfer()
        {
            try
            {
                KeyTransferWindow keyTransfer = new KeyTransferWindow(tcBitcoin, SelectedKey);

                if (keyTransfer.ShowDialog() == true)
                {
                    Cursor = Cursors.Wait;
                    SpendTx spendTx = await tcBitcoin.KeyTransferTx(SelectedKey, GetKey(keyTransfer.KeyNameTo),
                                                                    keyTransfer.TransferAmount, keyTransfer.MinerRate, keyTransfer.TxMessage, keyTransfer.CashCodeFrom, keyTransfer.CashCodeTo);

                    if (!spendTx.IsSatisfied)
                    {
                        MessageBox.Show(Properties.Resources.UnsatisfiedPayment, Title, MessageBoxButton.OK, MessageBoxImage.Error);
                        tcBitcoin.KeyTransferCancel(spendTx);
                    }
                    else
                    {
                        Cursor = Cursors.Arrow;
                        SpendConfirmWindow spendDialog = new SpendConfirmWindow(spendTx);

                        if (spendDialog.ShowDialog() == true)
                        {
                            Cursor = Cursors.Wait;

                            bool broadcast = await spendTx.Send();

                            if (broadcast)
                            {
                                if (tcBitcoin.KeyTransferNode(spendTx, keyTransfer.KeyNameTo, keyTransfer.CashCodeFrom, keyTransfer.CashCodeTo))
                                {
                                    Refresh();
                                    await RefreshBalance();
                                }
                            }
                        }
                        else
                        {
                            tcBitcoin.KeyTransferCancel(spendTx);
                        }
                    }
                }
            }
            catch (Exception err)
            {
                MessageBox.Show($"{err.Message}", $"{err.Source}.{err.TargetSite.Name}", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            finally
            {
                Cursor = Cursors.Arrow;
            }
        }
Beispiel #8
0
        public bool KeyTransferNode(SpendTx spend, string toKey, string cashCodeFrom, string cashCodeTo)
        {
            try
            {
                string paymentRef = string.Empty;

                paymentRef = $"{spend.FromKey} -> {toKey}";

                foreach (var tx in spend.Transactions)
                {
                    Money minerFee = tx.MinerFee;

                    for (int i = 0; i < tx.TxIds.Count; i++)
                    {
                        TxId  input    = tx.TxIds[i];
                        Money moneyOut = input.MoneyOut;

                        if (i == tx.TxIds.Count - 1)
                        {
                            moneyOut -= tx.ChangeAmount;
                        }

                        NodeCash.proc_TxPayOutTransfer
                        (
                            tx.PaymentAddress,
                            $"{input.TransactionId}",
                            moneyOut.ToUnit(MoneyUnit.MilliBTC),
                            minerFee.ToUnit(MoneyUnit.MilliBTC),
                            cashCodeFrom,
                            paymentRef
                        );

                        minerFee = minerFee <= moneyOut ? Money.Zero : minerFee - moneyOut;
                    }

                    foreach (var output in tx.Tx.Outputs)
                    {
                        string toAddress = $"{output.ScriptPubKey.GetDestinationAddress(GetNetwork)}";
                        string toTxId    = $"{tx.Tx.GetHash()}";

                        NodeCash.proc_ChangeTxAdd
                        (
                            toAddress,
                            toTxId,
                            (short)TxStatus.UTXO,
                            output.Value.ToUnit(MoneyUnit.MilliBTC),
                            0,
                            spend.TxMessage
                        );

                        if (toAddress == spend.ChangeAddress)
                        {
                            paymentRef = $"{spend.FromKey} -> {spend.FromKey}";
                        }
                        else
                        {
                            paymentRef = $"{spend.FromKey} -> {toKey}";
                        }

                        TxPayIn(toAddress, toTxId, string.Empty, cashCodeTo, DateTime.Now, paymentRef);
                    }
                }

                return(true);
            }
            catch (Exception err)
            {
                Console.WriteLine($"Error: {err.Message}");
                return(false);
            }
        }
Beispiel #9
0
            public KeyTx(SpendTx spend, ExtKey spendKey, ExtKey changeKey, Money minerFee)
            {
                Spend    = spend;
                MinerFee = minerFee;

                PaymentAddress = spendKey.PrivateKey.GetWif(Spend.Api.Network).GetAddress(ScriptPubKeyType.Legacy).ToString();

                Tx = Transaction.Create(Spend.Api.Network);
                var ReceiverAddress = BitcoinAddress.Create(Spend.ToAddress, Spend.Api.Network);

                Tx.Outputs.Add(SpendAmount, ReceiverAddress.ScriptPubKey);
                Tx.Outputs.Add(ChangeAmount, changeKey.PrivateKey.GetWif(Spend.Api.Network).GetAddress(ScriptPubKeyType.Legacy).ScriptPubKey);

                if (Spend.TxMessage.Length > 0)
                {
                    Tx.Outputs.Add(Money.Zero, TxNullDataTemplate.Instance.GenerateScriptPubKey(Encoding.UTF8.GetBytes(Spend.TxMessage)));
                }

                GetTransactions(spendKey);

                List <TxId> inputs = new List <TxId>();

                foreach (var txId in TxIds)
                {
                    if (!AddTransaction(spendKey, txId))
                    {
                        continue;
                    }
                    else
                    {
                        inputs.Add(txId);
                    }

                    var totalSpend      = Spend.SpendAmount + TxInAmount - MinerFee;
                    var remainingAmount = Spend.TargetAmount - totalSpend;

                    SpendAmount  = remainingAmount > Money.Zero ? TxInAmount - MinerFee : TxInAmount - MinerFee + remainingAmount;
                    ChangeAmount = TxInAmount - SpendAmount - MinerFee;

                    if (Spend.TargetAmount <= (Spend.TxInAmount + TxInAmount - Spend.MinerFee - MinerFee))
                    {
                        break;
                    }
                }

                List <TxId> unusedTx = TxIds.Where(tx => !inputs.Contains(tx)).ToList();

                foreach (var tx in unusedTx)
                {
                    TxIds.Remove(tx);
                }

                Tx.Outputs.Clear();
                Tx.Outputs.Add(SpendAmount, ReceiverAddress.ScriptPubKey);

                if (ChangeAmount > Money.Zero)
                {
                    Tx.Outputs.Add(ChangeAmount, changeKey.PrivateKey.GetWif(Spend.Api.Network).GetAddress(ScriptPubKeyType.Legacy).ScriptPubKey);
                }

                if (Spend.TxMessage.Length > 0)
                {
                    Tx.Outputs.Add(Money.Zero, TxNullDataTemplate.Instance.GenerateScriptPubKey(Encoding.UTF8.GetBytes(Spend.TxMessage)));
                }

                Tx.Sign(spendKey.PrivateKey.GetBitcoinSecret(Spend.Api.Network), coins.ToArray());
            }
 public SpendConfirmWindow(SpendTx spend)
 {
     spendTx = spend;
     InitializeComponent();
 }