BitSharper.Transaction.GetValueSentFromMe C# (CSharp) Method

GetValueSentFromMe() public method

Calculates the sum of the inputs that are spending coins with keys in the wallet. This requires the transactions sending coins to those keys to be in the wallet. This method will not attempt to download the blocks containing the input transactions if the key is in the wallet but the transactions are not.
public GetValueSentFromMe ( Wallet wallet ) : ulong
wallet Wallet
return ulong
        public ulong GetValueSentFromMe(Wallet wallet)
        {
            // This is tested in WalletTest.
            var v = 0UL;
            foreach (var input in _inputs)
            {
                // This input is taking value from an transaction in our wallet. To discover the value,
                // we must find the connected transaction.
                var connected = input.GetConnectedOutput(wallet.Unspent);
                if (connected == null)
                    connected = input.GetConnectedOutput(wallet.Spent);
                if (connected == null)
                    connected = input.GetConnectedOutput(wallet.Pending);
                if (connected == null)
                    continue;
                // The connected output may be the change to the sender of a previous input sent to this wallet. In this
                // case we ignore it.
                if (!connected.IsMine(wallet))
                    continue;
                v += connected.Value;
            }
            return v;
        }

Usage Example

示例#1
0
        /// <exception cref="VerificationException"/>
        /// <exception cref="ScriptException"/>
        private void Receive(Transaction tx, StoredBlock block, BlockChain.NewBlockType blockType, bool reorg)
        {
            lock (this)
            {
                // Runs in a peer thread.
                var prevBalance = GetBalance();

                var txHash = tx.Hash;

                var bestChain = blockType == BlockChain.NewBlockType.BestChain;
                var sideChain = blockType == BlockChain.NewBlockType.SideChain;

                var valueSentFromMe = tx.GetValueSentFromMe(this);
                var valueSentToMe = tx.GetValueSentToMe(this);
                var valueDifference = (long) (valueSentToMe - valueSentFromMe);

                if (!reorg)
                {
                    _log.InfoFormat("Received tx{0} for {1} BTC: {2}", sideChain ? " on a side chain" : "",
                                    Utils.BitcoinValueToFriendlyString(valueDifference), tx.HashAsString);
                }

                // If this transaction is already in the wallet we may need to move it into a different pool. At the very
                // least we need to ensure we're manipulating the canonical object rather than a duplicate.
                Transaction wtx;
                if (Pending.TryGetValue(txHash, out wtx))
                {
                    Pending.Remove(txHash);
                    _log.Info("  <-pending");
                    // A transaction we created appeared in a block. Probably this is a spend we broadcast that has been
                    // accepted by the network.
                    //
                    // Mark the tx as appearing in this block so we can find it later after a re-org.
                    wtx.AddBlockAppearance(block);
                    if (bestChain)
                    {
                        if (valueSentToMe.Equals(0))
                        {
                            // There were no change transactions so this tx is fully spent.
                            _log.Info("  ->spent");
                            Debug.Assert(!Spent.ContainsKey(wtx.Hash), "TX in both pending and spent pools");
                            Spent[wtx.Hash] = wtx;
                        }
                        else
                        {
                            // There was change back to us, or this tx was purely a spend back to ourselves (perhaps for
                            // anonymization purposes).
                            _log.Info("  ->unspent");
                            Debug.Assert(!Unspent.ContainsKey(wtx.Hash), "TX in both pending and unspent pools");
                            Unspent[wtx.Hash] = wtx;
                        }
                    }
                    else if (sideChain)
                    {
                        // The transaction was accepted on an inactive side chain, but not yet by the best chain.
                        _log.Info("  ->inactive");
                        // It's OK for this to already be in the inactive pool because there can be multiple independent side
                        // chains in which it appears:
                        //
                        //     b1 --> b2
                        //        \-> b3
                        //        \-> b4 (at this point it's already present in 'inactive'
                        if (_inactive.ContainsKey(wtx.Hash))
                            _log.Info("Saw a transaction be incorporated into multiple independent side chains");
                        _inactive[wtx.Hash] = wtx;
                        // Put it back into the pending pool, because 'pending' means 'waiting to be included in best chain'.
                        Pending[wtx.Hash] = wtx;
                    }
                }
                else
                {
                    if (!reorg)
                    {
                        // Mark the tx as appearing in this block so we can find it later after a re-org.
                        tx.AddBlockAppearance(block);
                    }
                    // This TX didn't originate with us. It could be sending us coins and also spending our own coins if keys
                    // are being shared between different wallets.
                    if (sideChain)
                    {
                        _log.Info("  ->inactive");
                        _inactive[tx.Hash] = tx;
                    }
                    else if (bestChain)
                    {
                        ProcessTxFromBestChain(tx);
                    }
                }

                _log.InfoFormat("Balance is now: {0}", Utils.BitcoinValueToFriendlyString(GetBalance()));

                // Inform anyone interested that we have new coins. Note: we may be re-entered by the event listener,
                // so we must not make assumptions about our state after this loop returns! For example,
                // the balance we just received might already be spent!
                if (!reorg && bestChain && valueDifference > 0 && CoinsReceived != null)
                {
                    lock (CoinsReceived)
                    {
                        CoinsReceived(this, new WalletCoinsReceivedEventArgs(tx, prevBalance, GetBalance()));
                    }
                }
            }
        }