From 9c9ba366ebc85b0d8eef6d962a9fa84cffe0cae7 Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 24 Feb 2016 02:27:02 +0300 Subject: [PATCH] Add CWallet::ExtractAddress method --- src/qt/coincontroldialog.cpp | 47 ++++++++++++++++++++++++++++++++++++++ src/qt/transactionrecord.cpp | 51 +++++++++-------------------------------- src/qt/walletmodel.cpp | 7 +++-- src/wallet.cpp | 36 +++++++++++++++++++++++++++++ src/wallet.h | 2 + 5 files changed, 100 insertions(+), 43 deletions(-) diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index ae73042..998a992 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -631,6 +631,7 @@ void CoinControlDialog::updateView() itemOutput->setCheckState(COLUMN_CHECKBOX,Qt::Unchecked); // address +/* CTxDestination outputAddress; QString sAddress = ""; if(ExtractDestination(out.tx->vout[out.i].scriptPubKey, outputAddress)) @@ -646,6 +647,52 @@ void CoinControlDialog::updateView() if (keyid && model->getPubKey(*keyid, pubkey) && !pubkey.IsCompressed()) nInputSize = 180; } +*/ + QString sAddress = ""; + txnouttype whichType; + std::vector vSolutions; + if (Solver(out.tx->vout[out.i].scriptPubKey, whichType, vSolutions)) + { + CTxDestination address; + if (whichType == TX_PUBKEY) + { + // Pay-to-Pubkey + CPubKey pubKey = CPubKey(vSolutions[0]); + address = pubKey.GetID(); + sAddress = CBitcoinAddress(address).ToString().c_str(); + + if (!pubKey.IsCompressed()) + nInputSize = 180; + } + else if (whichType == TX_PUBKEYHASH) + { + // Pay-to-PubkeyHash + address = CKeyID(uint160(vSolutions[0])); + sAddress = CBitcoinAddress(address).ToString().c_str(); + + CPubKey pubkey; + CKeyID *keyid = boost::get< CKeyID >(&address); + if (keyid && model->getPubKey(*keyid, pubkey) && !pubkey.IsCompressed()) + nInputSize = 180; + } + else if (whichType == TX_SCRIPTHASH) + { + // Pay-to-ScriptHash + address = CScriptID(uint160(vSolutions[0])); + sAddress = CBitcoinAddress(address).ToString().c_str(); + } + else if (whichType == TX_PUBKEY_DROP) + { + // Pay-to-Pubkey-R + CMalleableKeyView view; + pwalletMain->CheckOwnership(CPubKey(vSolutions[0]), CPubKey(vSolutions[1]), view); + sAddress = view.GetMalleablePubKey().ToString().c_str(); + } + + // if listMode or change => show bitcoin address. In tree mode, address is not shown again for direct wallet address outputs + if (!treeMode || (!(sAddress == sWalletAddress))) + itemOutput->setText(COLUMN_ADDRESS, sAddress); + } // label if (!(sAddress == sWalletAddress)) // change diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 7c50f91..e28a64b 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -46,48 +46,19 @@ QList TransactionRecord::decomposeTransaction(const CWallet * sub.idx = parts.size(); // sequence number sub.credit = txout.nValue; - txnouttype whichType; - std::vector vSolutions; - if (Solver(txout.scriptPubKey, whichType, vSolutions)) + std::string address; + if (pwalletMain->ExtractAddress(txout.scriptPubKey, address)) { - CTxDestination address; - if (whichType == TX_PUBKEY) - { - // Pay-to-Pubkey - address = CPubKey(vSolutions[0]).GetID(); - sub.type = TransactionRecord::RecvWithAddress; - sub.address = CBitcoinAddress(address).ToString(); - } - else if (whichType == TX_PUBKEYHASH) - { - // Pay-to-PubkeyHash - address = CKeyID(uint160(vSolutions[0])); - sub.type = TransactionRecord::RecvWithAddress; - sub.address = CBitcoinAddress(address).ToString(); - } - else if (whichType == TX_SCRIPTHASH) - { - // Pay-to-ScriptHash - address = CScriptID(uint160(vSolutions[0])); - sub.type = TransactionRecord::RecvWithAddress; - sub.address = CBitcoinAddress(address).ToString(); - } - else if (whichType == TX_PUBKEY_DROP) - { - // Pay-to-Pubkey-R - sub.type = TransactionRecord::RecvWithAddress; - - CMalleableKeyView view; - pwalletMain->CheckOwnership(CPubKey(vSolutions[0]), CPubKey(vSolutions[1]), view); - sub.address = view.GetMalleablePubKey().ToString(); - } - else - { - // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction - sub.type = TransactionRecord::RecvFromOther; - sub.address = mapValue["from"]; - } + sub.type = TransactionRecord::RecvWithAddress; + sub.address = address; } + 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 (proof-of-work) diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 4769fda..47b12e9 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -495,10 +495,11 @@ void WalletModel::listCoins(std::map >& mapCoins) cout = COutput(&wallet->mapWallet[cout.tx->vin[0].prevout.hash], cout.tx->vin[0].prevout.n, 0, true); } - CTxDestination address; - if(!out.fSpendable || !ExtractDestination(cout.tx->vout[cout.i].scriptPubKey, address)) + std::string address; + if(!out.fSpendable || !wallet->ExtractAddress(cout.tx->vout[cout.i].scriptPubKey, address)) continue; - mapCoins[CBitcoinAddress(address).ToString().c_str()].push_back(out); + + mapCoins[address.c_str()].push_back(out); } } diff --git a/src/wallet.cpp b/src/wallet.cpp index d5e3285..780c7f4 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -2780,3 +2780,39 @@ void CWallet::ClearOrphans() for(list::const_iterator it = orphans.begin(); it != orphans.end(); ++it) EraseFromWallet(*it); } + +bool CWallet::ExtractAddress(const CScript& scriptPubKey, std::string& addressRet) +{ + vector vSolutions; + txnouttype whichType; + if (!Solver(scriptPubKey, whichType, vSolutions)) + return false; + + if (whichType == TX_PUBKEY) + { + addressRet = CBitcoinAddress(CPubKey(vSolutions[0]).GetID()).ToString(); + return true; + } + if (whichType == TX_PUBKEY_DROP) + { + // Pay-to-Pubkey-R + CMalleableKeyView view; + if (!CheckOwnership(CPubKey(vSolutions[0]), CPubKey(vSolutions[1]), view)) + return false; + + addressRet = view.GetMalleablePubKey().ToString(); + return true; + } + else if (whichType == TX_PUBKEYHASH) + { + addressRet = CBitcoinAddress(CKeyID(uint160(vSolutions[0]))).ToString(); + return true; + } + else if (whichType == TX_SCRIPTHASH) + { + addressRet = CBitcoinAddress(CScriptID(uint160(vSolutions[0]))).ToString(); + return true; + } + // Multisig txns have more than one address... + return false; +} diff --git a/src/wallet.h b/src/wallet.h index bc8afa8..12d8af5 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -337,6 +337,8 @@ public: bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx); + bool ExtractAddress(const CScript& scriptPubKey, std::string& addressRet); + bool SetDefaultKey(const CPubKey &vchPubKey); // signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower -- 1.7.1