Example #1
0
        /// <summary>
        /// Creates an AccountTransaction for the account and wallet transaction when the transaction is relevant to the account.
        /// </summary>
        /// <param name="account">Account to search for in a transaction's inputs and outputs</param>
        /// <param name="tx">Wallet transaction to consider</param>
        /// <returns>An AccountTransaction for relevant transactions, otherwise null.</returns>
        public static AccountTransaction?Create(Account account, WalletTransaction tx)
        {
            Amount debit = 0, credit = 0;
            bool   isForAccount = false; // Not saved by the WalletTransaction so need a way to detect irrelevant transactions.

            foreach (var input in tx.Inputs.Where(i => i.PreviousAccount == account))
            {
                debit       -= input.Amount;
                isForAccount = true;
            }
            foreach (var output in tx.Outputs.OfType <WalletTransaction.Output.ControlledOutput>().Where(o => o.Account == account))
            {
                if (output.Change)
                {
                    debit += output.Amount;
                }
                else
                {
                    credit += output.Amount;
                }

                isForAccount = true;
            }

            return(isForAccount ? new AccountTransaction(tx, debit, credit) : (AccountTransaction?)null);
        }
        public TransactionViewModel(Wallet wallet, WalletTransaction transaction, BlockIdentity transactionLocation)
        {
            _transaction = transaction;
            _location = transactionLocation;

            var groupedOutputs = _transaction.NonChangeOutputs.Select(o =>
            {
                var destination = wallet.OutputDestination(o);
                return new GroupedOutput(o.Amount, destination);
            }).Aggregate(new List<GroupedOutput>(), (items, next) =>
            {
                var item = items.Find(a => a.Destination == next.Destination);
                if (item == null)
                    items.Add(next);
                else
                    item.Amount += next.Amount;

                return items;
            });

            Depth = BlockChain.Depth(wallet.ChainTip.Height, transactionLocation);
            Inputs = _transaction.Inputs.Select(input => new Input(-input.Amount, wallet.AccountName(input.PreviousAccount))).ToArray();
            Outputs = _transaction.Outputs.Select(output => new Output(output.Amount, wallet.OutputDestination(output))).ToArray();
            GroupedOutputs = groupedOutputs;
        }
Example #3
0
        public static bool RelevantTransaction(WalletTransaction tx, Account account, out Amount debit, out Amount credit)
        {
            if (tx == null)
            {
                throw new ArgumentNullException(nameof(tx));
            }

            debit  = 0;
            credit = 0;
            var relevant = false;

            foreach (var input in tx.Inputs)
            {
                if (input.PreviousAccount == account)
                {
                    relevant = true;
                    debit   -= input.Amount;
                }
            }
            foreach (var output in tx.Outputs)
            {
                var controlledOutput = output as WalletTransaction.Output.ControlledOutput;
                if (controlledOutput?.Account == account)
                {
                    relevant = true;
                    credit  += output.Amount;
                }
            }

            return(relevant);
        }
Example #4
0
        public static bool RelevantTransaction(WalletTransaction tx, Account account, out Amount debit, out Amount credit)
        {
            if (tx == null)
                throw new ArgumentNullException(nameof(tx));

            debit = 0;
            credit = 0;
            var relevant = false;

            foreach (var input in tx.Inputs)
            {
                if (input.PreviousAccount == account)
                {
                    relevant = true;
                    debit -= input.Amount;
                }
            }
            foreach (var output in tx.Outputs)
            {
                var controlledOutput = output as WalletTransaction.Output.ControlledOutput;
                if (controlledOutput?.Account == account)
                {
                    relevant = true;
                    credit += output.Amount;
                }
            }

            return relevant;
        }
Example #5
0
        private void AddTransactionToTotals(WalletTransaction tx, Dictionary<Account, AccountProperties> modifiedAccounts)
        {
            var isCoinbase = BlockChain.IsCoinbase(tx.Transaction);

            foreach (var input in tx.Inputs)
            {
                TotalBalance -= input.Amount;

                var accountProperties = LookupAccountProperties(input.PreviousAccount);
                accountProperties.TotalBalance -= input.Amount;
                if (isCoinbase)
                    accountProperties.ImmatureCoinbaseReward -= input.Amount;
                modifiedAccounts[input.PreviousAccount] = accountProperties;
            }

            foreach (var output in tx.Outputs.OfType<WalletTransaction.Output.ControlledOutput>())
            {
                TotalBalance += output.Amount;

                var accountProperties = LookupAccountProperties(output.Account);
                accountProperties.TotalBalance += output.Amount;
                if (isCoinbase)
                    accountProperties.ImmatureCoinbaseReward += output.Amount;
                modifiedAccounts[output.Account] = accountProperties;
            }

            _transactionCount++;
        }
Example #6
0
        private void AddTransactionToTotals(WalletTransaction tx, Dictionary <Account, AccountProperties> modifiedAccounts)
        {
            var isCoinbase = BlockChain.IsCoinbase(tx.Transaction);

            foreach (var input in tx.Inputs)
            {
                TotalBalance -= input.Amount;

                var accountProperties = LookupAccountProperties(input.PreviousAccount);
                accountProperties.TotalBalance -= input.Amount;
                if (isCoinbase)
                {
                    accountProperties.ImmatureCoinbaseReward -= input.Amount;
                }
                modifiedAccounts[input.PreviousAccount] = accountProperties;
            }

            foreach (var output in tx.Outputs.OfType <WalletTransaction.Output.ControlledOutput>())
            {
                TotalBalance += output.Amount;

                var accountProperties = LookupAccountProperties(output.Account);
                accountProperties.TotalBalance += output.Amount;
                if (isCoinbase)
                {
                    accountProperties.ImmatureCoinbaseReward += output.Amount;
                }
                modifiedAccounts[output.Account] = accountProperties;
            }

            _transactionCount++;
        }
Example #7
0
        /// <summary>
        /// Creates an AccountTransaction for the account and wallet transaction when the transaction is relevant to the account.
        /// </summary>
        /// <param name="account">Account to search for in a transaction's inputs and outputs</param>
        /// <param name="tx">Wallet transaction to consider</param>
        /// <returns>An AccountTransaction for relevant transactions, otherwise null.</returns>
        public static AccountTransaction? Create(Account account, WalletTransaction tx)
        {
            Amount debit = 0, credit = 0;
            bool isForAccount = false; // Not saved by the WalletTransaction so need a way to detect irrelevant transactions.

            foreach (var input in tx.Inputs.Where(i => i.PreviousAccount == account))
            {
                debit -= input.Amount;
                isForAccount = true;
            }
            foreach (var output in tx.Outputs.OfType<WalletTransaction.Output.ControlledOutput>().Where(o => o.Account == account))
            {
                if (output.Change)
                    debit += output.Amount;
                else
                    credit += output.Amount;

                isForAccount = true;
            }

            return isForAccount ? new AccountTransaction(tx, debit, credit) : (AccountTransaction?)null;
        }
Example #8
0
 private AccountTransaction(WalletTransaction tx, Amount debit, Amount credit)
 {
     Transaction = tx;
     Debit       = debit;
     Credit      = credit;
 }
Example #9
0
 private AccountTransaction(WalletTransaction tx, Amount debit, Amount credit)
 {
     Transaction = tx;
     Debit = debit;
     Credit = credit;
 }
Example #10
0
        public string OutputDestination(WalletTransaction.Output output)
        {
            if (output == null)
                throw new ArgumentNullException(nameof(output));

            if (output is WalletTransaction.Output.ControlledOutput)
            {
                var controlledOutput = (WalletTransaction.Output.ControlledOutput)output;
                if (controlledOutput.Change)
                    return "Change";
                else
                    return LookupAccountProperties(controlledOutput.Account).AccountName;
            }
            else
            {
                var uncontrolledOutput = (WalletTransaction.Output.UncontrolledOutput)output;
                Address address;
                if (Address.TryFromOutputScript(uncontrolledOutput.PkScript, ActiveChain, out address))
                    return address.Encode();
                else
                    return "Non-address output";
            }
        }
Example #11
0
 private static IEnumerable<WalletTransaction.Output.ControlledOutput> OutputsToAccount(WalletTransaction.Output[] outputs, Account account)
 {
     return outputs.OfType<WalletTransaction.Output.ControlledOutput>().Where(o => o.Account == account);
 }