src/wallet/wallet.cpp
// GetAmounts will determine the transparent debits and credits for a given wallet tx.
GetAmounts will determine the transparent debits and credits for a given wallet tx.
GetAmounts will determine the transparent debits and credits for a given wallet tx .
void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
                           list<COutputEntry>& listSent, CAmount& nFee, string& strSentAccount, const isminefilter& filter) const
{
    nFee = 0;
    listReceived.clear();
    listSent.clear();
    strSentAccount = strFromAccount;
    CAmount nDebit = GetDebit(filter);
    bool isFromMyTaddr = nDebit > 0; 
    if (isFromMyTaddr) {
        CAmount nValueOut = GetValueOut();  
        CAmount nValueIn = GetShieldedValueIn();
        nFee = nDebit - nValueOut + nValueIn;
    }
    if (isFromMyTaddr) {
        CAmount myVpubOld = 0;
        CAmount myVpubNew = 0;
        for (const JSDescription& js : vJoinSplit) {
            bool fMyJSDesc = false;
            for (const uint256& nullifier : js.nullifiers) {
                if (pwallet->IsSproutNullifierFromMe(nullifier)) {
                    fMyJSDesc = true;
                    break;
                }
            }
            if (!fMyJSDesc) {
                for (const std::pair<JSOutPoint, SproutNoteData> nd : this->mapSproutNoteData) {
                    if (nd.first.js < vJoinSplit.size() && nd.first.n < vJoinSplit[nd.first.js].ciphertexts.size()) {
                        fMyJSDesc = true;
                        break;
                    }
                }
            }
            if (fMyJSDesc) {
                myVpubOld += js.vpub_old;
                myVpubNew += js.vpub_new;
            }
            if (!MoneyRange(js.vpub_old) || !MoneyRange(js.vpub_new) || !MoneyRange(myVpubOld) || !MoneyRange(myVpubNew)) {
                 throw std::runtime_error("CWalletTx::GetAmounts: value out of range");
            }
        }
        if (myVpubOld > myVpubNew) {
            COutputEntry output = {CNoDestination(), myVpubOld - myVpubNew, (int)vout.size()};
            listSent.push_back(output);
        } else if (myVpubNew > myVpubOld) {
            COutputEntry output = {CNoDestination(), myVpubNew - myVpubOld, (int)vout.size()};
            listReceived.push_back(output);
        }
    }
    if (isFromMyTaddr) {
        if (valueBalance < 0) {
            COutputEntry output = {CNoDestination(), -valueBalance, (int) vout.size()};
            listSent.push_back(output);
        } else if (valueBalance > 0) {
            COutputEntry output = {CNoDestination(), valueBalance, (int) vout.size()};
            listReceived.push_back(output);
        }
    }
    for (unsigned int i = 0; i < vout.size(); ++i)
    {
        const CTxOut& txout = vout[i];
        isminetype fIsMine = pwallet->IsMine(txout);
        if (nDebit > 0)
        {
            if (pwallet->IsChange(txout))
                continue;
        }
        else if (!(fIsMine & filter))
            continue;
        CTxDestination address;
        if (!ExtractDestination(txout.scriptPubKey, address))
        {
            LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
                     this->GetHash().ToString());
            address = CNoDestination();
        }
        COutputEntry output = {address, txout.nValue, (int)i};
        if (nDebit > 0)
            listSent.push_back(output);
        if (fIsMine & filter)
            listReceived.push_back(output);
    }
}
void CWalletTx :: GetAmounts ( list < COutputEntry > & listReceived , list < COutputEntry > & listSent , CAmount & nFee , string & strSentAccount , const isminefilter & filter ) const { nFee = 0 ; listReceived . clear ( ) ; listSent . clear ( ) ; strSentAccount = strFromAccount ; CAmount nDebit = GetDebit ( filter ) ; bool isFromMyTaddr = nDebit > 0 ; if ( isFromMyTaddr ) { CAmount nValueOut = GetValueOut ( ) ; CAmount nValueIn = GetShieldedValueIn ( ) ; nFee = nDebit - nValueOut + nValueIn ; } if ( isFromMyTaddr ) { CAmount myVpubOld = 0 ; CAmount myVpubNew = 0 ; for ( const JSDescription & js : vJoinSplit ) { bool fMyJSDesc = false ; for ( const uint256 & nullifier : js . nullifiers ) { if ( pwallet -> IsSproutNullifierFromMe ( nullifier ) ) { fMyJSDesc = true ; break ; } } if ( ! fMyJSDesc ) { for ( const std :: pair < JSOutPoint , SproutNoteData > nd : this -> mapSproutNoteData ) { if ( nd . first . js < vJoinSplit . size ( ) && nd . first . n < vJoinSplit [ nd . first . js ] . ciphertexts . size ( ) ) { fMyJSDesc = true ; break ; } } } if ( fMyJSDesc ) { myVpubOld += js . vpub_old ; myVpubNew += js . vpub_new ; } if ( ! MoneyRange ( js . vpub_old ) || ! MoneyRange ( js . vpub_new ) || ! MoneyRange ( myVpubOld ) || ! MoneyRange ( myVpubNew ) ) { throw std :: runtime_error ( " " ) ; } } if ( myVpubOld > myVpubNew ) { COutputEntry output = { CNoDestination ( ) , myVpubOld - myVpubNew , ( int ) vout . size ( ) } ; listSent . push_back ( output ) ; } else if ( myVpubNew > myVpubOld ) { COutputEntry output = { CNoDestination ( ) , myVpubNew - myVpubOld , ( int ) vout . size ( ) } ; listReceived . push_back ( output ) ; } } if ( isFromMyTaddr ) { if ( valueBalance < 0 ) { COutputEntry output = { CNoDestination ( ) , - valueBalance , ( int ) vout . size ( ) } ; listSent . push_back ( output ) ; } else if ( valueBalance > 0 ) { COutputEntry output = { CNoDestination ( ) , valueBalance , ( int ) vout . size ( ) } ; listReceived . push_back ( output ) ; } } for ( unsigned int i = 0 ; i < vout . size ( ) ; ++ i ) { const CTxOut & txout = vout [ i ] ; isminetype fIsMine = pwallet -> IsMine ( txout ) ; if ( nDebit > 0 ) { if ( pwallet -> IsChange ( txout ) ) continue ; } else if ( ! ( fIsMine & filter ) ) continue ; CTxDestination address ; if ( ! ExtractDestination ( txout . scriptPubKey , address ) ) { LogPrintf ( " \n " , this -> GetHash ( ) . ToString ( ) ) ; address = CNoDestination ( ) ; } COutputEntry output = { address , txout . nValue , ( int ) i } ; if ( nDebit > 0 ) listSent . push_back ( output ) ; if ( fIsMine & filter ) listReceived . push_back ( output ) ; } }
GetAmounts will determine the transparent debits and credits for a given wallet tx.
GetAmounts will determine the transparent debits and credits for a given wallet tx .
// Is this tx sent/signed by me? // debit>0 means we signed/sent this transaction // Compute fee if we sent this transaction. // transparent outputs plus all Sprout vpub_old and negative Sapling valueBalance // Create output entry for vpub_old/new, if we sent utxos from this transaction // Check input side // Check output side // Create an output for the value taken from or added to the transparent value pool by JoinSplits // If we sent utxos from this transaction, create output for value taken from (negative valueBalance) // or added (positive valueBalance) to the transparent value pool by Sapling shielding and unshielding. // Sent/received. // Only need to handle txouts if AT LEAST one of these is true: //   1) they debit from us (sent) //   2) the output is to us (received) // Don't report 'change' txouts // In either case, we need to get the destination address // If we are debited by the transaction, add the output as a "sent" entry // If we are receiving the output, add it as a "received" entry