/* * Decompose CWallet transaction to model transaction records. */ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet* wallet, const CWalletTx& wtx) { QList<TransactionRecord> parts; int64_t nTime = wtx.GetComputedTxTime(); CAmount nCredit = wtx.GetCredit(ISMINE_ALL); CAmount nDebit = wtx.GetDebit(ISMINE_ALL); CAmount nNet = nCredit - nDebit; uint256 hash = wtx.GetHash(); std::map<std::string, std::string> mapValue = wtx.mapValue; if (wtx.IsCoinStake()) { TransactionRecord sub(hash, nTime); CTxDestination address; if (!ExtractDestination(wtx.vout[1].scriptPubKey, address)) return parts; if (!IsMine(*wallet, address)) { //if the address is not yours then it means you have a tx sent to you in someone elses coinstake tx for (unsigned int i = 1; i < wtx.vout.size(); i++) { CTxDestination outAddress; if (ExtractDestination(wtx.vout[i].scriptPubKey, outAddress)) { if (IsMine(*wallet, outAddress)) { isminetype mine = wallet->IsMine(wtx.vout[i]); sub.involvesWatchAddress = mine & ISMINE_WATCH_ONLY; sub.type = TransactionRecord::MNReward; sub.address = CBitcoinAddress(outAddress).ToString(); sub.credit = wtx.vout[i].nValue; } } } } else { //stake reward isminetype mine = wallet->IsMine(wtx.vout[1]); sub.involvesWatchAddress = mine & ISMINE_WATCH_ONLY; sub.type = TransactionRecord::StakeMint; sub.address = CBitcoinAddress(address).ToString(); sub.credit = nNet; } parts.append(sub); } else if (wtx.IsZerocoinSpend()) { // a zerocoin spend that was created by this wallet libzerocoin::CoinSpend zcspend = TxInToZerocoinSpend(wtx.vin[0]); bool fSpendFromMe = wallet->IsMyZerocoinSpend(zcspend.getCoinSerialNumber()); //zerocoin spend outputs bool fFeeAssigned = false; for (const CTxOut txout : wtx.vout) { // change that was reminted as zerocoins if (txout.IsZerocoinMint()) { // do not display record if this isn't from our wallet if (!fSpendFromMe) continue; TransactionRecord sub(hash, nTime); sub.type = TransactionRecord::ZerocoinSpend_Change_zPiv; sub.address = mapValue["zerocoinmint"]; sub.debit = -txout.nValue; if (!fFeeAssigned) { sub.debit -= (wtx.GetZerocoinSpent() - wtx.GetValueOut()); fFeeAssigned = true; } sub.idx = parts.size(); parts.append(sub); continue; } string strAddress = ""; CTxDestination address; if (ExtractDestination(txout.scriptPubKey, address)) strAddress = CBitcoinAddress(address).ToString(); // a zerocoinspend that was sent to an address held by this wallet isminetype mine = wallet->IsMine(txout); if (mine) { TransactionRecord sub(hash, nTime); sub.type = (fSpendFromMe ? TransactionRecord::ZerocoinSpend_FromMe : TransactionRecord::RecvFromZerocoinSpend); sub.debit = txout.nValue; sub.address = mapValue["recvzerocoinspend"]; if (strAddress != "") sub.address = strAddress; sub.idx = parts.size(); parts.append(sub); continue; } // spend is not from us, so do not display the spend side of the record if (!fSpendFromMe) continue; // zerocoin spend that was sent to someone else TransactionRecord sub(hash, nTime); sub.debit = -txout.nValue; sub.type = TransactionRecord::ZerocoinSpend; sub.address = mapValue["zerocoinspend"]; if (strAddress != "") sub.address = strAddress; sub.idx = parts.size(); parts.append(sub); } } else if (nNet > 0 || wtx.IsCoinBase()) { // // Credit // BOOST_FOREACH (const CTxOut& txout, wtx.vout) { isminetype mine = wallet->IsMine(txout); if (mine) { TransactionRecord sub(hash, nTime); CTxDestination address; sub.idx = parts.size(); // sequence number sub.credit = txout.nValue; sub.involvesWatchAddress = mine & ISMINE_WATCH_ONLY; if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) { // Received by PIVX Address sub.type = TransactionRecord::RecvWithAddress; sub.address = CBitcoinAddress(address).ToString(); } else { // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction sub.type = TransactionRecord::RecvFromOther; sub.address = mapValue["from"]; } if (wtx.IsCoinBase()) { // Generated sub.type = TransactionRecord::Generated; } parts.append(sub); } } } else {