/// <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; }
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); }
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; }
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++; }
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++; }
/// <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; }
private AccountTransaction(WalletTransaction tx, Amount debit, Amount credit) { Transaction = tx; Debit = debit; Credit = credit; }
private AccountTransaction(WalletTransaction tx, Amount debit, Amount credit) { Transaction = tx; Debit = debit; Credit = credit; }
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"; } }
private static IEnumerable<WalletTransaction.Output.ControlledOutput> OutputsToAccount(WalletTransaction.Output[] outputs, Account account) { return outputs.OfType<WalletTransaction.Output.ControlledOutput>().Where(o => o.Account == account); }