From 62b3df9c02e86432aa73f8b475900946bb348816 Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Sun, 6 Mar 2016 23:54:53 +0300 Subject: [PATCH] Simplification of scriptPubKey handling code. --- novacoin-qt.pro | 4 +- src/base58.cpp | 30 +++++++++++++- src/base58.h | 1 + src/qt/coincontroldialog.cpp | 78 ++++++++++-------------------------- src/qt/signverifymessagedialog.cpp | 2 +- src/qt/walletmodel.cpp | 4 +- src/rpcrawtransaction.cpp | 14 +----- src/rpcwallet.cpp | 41 ++++--------------- src/script.cpp | 18 +++++++- src/script.h | 4 +- 10 files changed, 86 insertions(+), 110 deletions(-) diff --git a/novacoin-qt.pro b/novacoin-qt.pro index abafeb7..9b9cb14 100644 --- a/novacoin-qt.pro +++ b/novacoin-qt.pro @@ -52,8 +52,8 @@ contains(RELEASE, 1) { } contains(DEBUG, 1) { - QMAKE_CXXFLAGS_RELEASE -= -O2 - QMAKE_CFLAGS_RELEASE -= -O2 + QMAKE_CXXFLAGS -= -O2 + QMAKE_CFLAGS -= -O2 QMAKE_CFLAGS += -g -O0 QMAKE_CXXCFLAGS += -g -O0 diff --git a/src/base58.cpp b/src/base58.cpp index a524be6..2691ea4 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -258,11 +258,13 @@ bool DecodeBase58Check(const std::string& str, std::vector& vchRe { unsigned int nExpectedSize = 20; bool fExpectTestNet = false; + bool fSimple = true; switch(nVersion) { case PUBKEY_PAIR_ADDRESS: nExpectedSize = 68; // Serialized pair of public keys fExpectTestNet = false; + fSimple = false; break; case PUBKEY_ADDRESS: nExpectedSize = 20; // Hash of public key @@ -276,6 +278,7 @@ bool DecodeBase58Check(const std::string& str, std::vector& vchRe case PUBKEY_PAIR_ADDRESS_TEST: nExpectedSize = 68; fExpectTestNet = true; + fSimple = false; break; case PUBKEY_ADDRESS_TEST: nExpectedSize = 20; @@ -289,7 +292,20 @@ bool DecodeBase58Check(const std::string& str, std::vector& vchRe default: return false; } - return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize; + + // Basic format sanity check + bool fSeemsSane = (fExpectTestNet == fTestNet && vchData.size() == nExpectedSize); + + if (fSeemsSane && !fSimple) + { + // Perform dditional checking + // for pubkey pair addresses + CMalleablePubKey mpk; + mpk.setvch(vchData); + return mpk.IsValid(); + } + else + return fSeemsSane; } CTxDestination CBitcoinAddress::Get() const { @@ -345,6 +361,18 @@ bool DecodeBase58Check(const std::string& str, std::vector& vchRe default: return false; } } + + bool CBitcoinAddress::IsPubKey() const { + if (!IsValid()) + return false; + switch (nVersion) { + case PUBKEY_ADDRESS: + case PUBKEY_ADDRESS_TEST: { + return true; + } + default: return false; + } + } bool CBitcoinAddress::IsPair() const { if (!IsValid()) diff --git a/src/base58.h b/src/base58.h index b312443..d5df354 100644 --- a/src/base58.h +++ b/src/base58.h @@ -142,6 +142,7 @@ public: CTxDestination Get() const; bool GetKeyID(CKeyID &keyID) const; bool IsScript() const; + bool IsPubKey() const; bool IsPair() const; }; diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 3f67ee6..9ea82a4 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -4,6 +4,7 @@ #include "init.h" #include "base58.h" #include "bitcoinunits.h" +#include "wallet.h" #include "walletmodel.h" #include "addresstablemodel.h" #include "optionsmodel.h" @@ -469,17 +470,22 @@ void CoinControlDialog::updateLabels(WalletModel *model, QWidget* dialog) dPriorityInputs += (double)out.tx->vout[out.i].nValue * (out.nDepth+1); // Bytes - CTxDestination address; - if(ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) + CBitcoinAddress address; + if(pwalletMain->ExtractAddress(out.tx->vout[out.i].scriptPubKey, address)) { - CPubKey pubkey; - CKeyID *keyid = boost::get< CKeyID >(&address); - if (keyid && model->getPubKey(*keyid, pubkey)) - nBytesInputs += (pubkey.IsCompressed() ? 148 : 180); - else - nBytesInputs += 148; // in all error cases, simply assume 148 here + if (address.IsPair()) + nBytesInputs += 213; + else if (address.IsPubKey()) + { + CPubKey pubkey; + CTxDestination dest = address.Get(); + CKeyID *keyid = boost::get< CKeyID >(&dest); + if (keyid && model->getPubKey(*keyid, pubkey)) + nBytesInputs += (pubkey.IsCompressed() ? 148 : 180); + else + nBytesInputs += 148; // in all error cases, simply assume 148 here + } } - else nBytesInputs += 148; } // calculation @@ -631,10 +637,10 @@ void CoinControlDialog::updateView() itemOutput->setCheckState(COLUMN_CHECKBOX,Qt::Unchecked); // address -/* - CTxDestination outputAddress; + CBitcoinAddress outputAddress; QString sAddress = ""; - if(ExtractDestination(out.tx->vout[out.i].scriptPubKey, outputAddress)) + + if(pwalletMain->ExtractAddress(out.tx->vout[out.i].scriptPubKey, outputAddress)) { sAddress = CBitcoinAddress(outputAddress).ToString().c_str(); @@ -642,56 +648,14 @@ void CoinControlDialog::updateView() if (!treeMode || (!(sAddress == sWalletAddress))) itemOutput->setText(COLUMN_ADDRESS, sAddress); - CPubKey pubkey; - CKeyID *keyid = boost::get< CKeyID >(&outputAddress); - 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) + if (outputAddress.IsPubKey()) { - // 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); + CTxDestination dest = outputAddress.Get(); + CKeyID *keyid = boost::get< CKeyID >(&dest); 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 = CBitcoinAddress(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 diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 187fe13..8d011ab 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -288,4 +288,4 @@ void SignVerifyMessageDialog::keyPressEvent(QKeyEvent *event) close(); } #endif -} \ No newline at end of file +} diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index a185ed3..d761fa0 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -207,7 +207,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QListclear(); - *this << pubKeyVariant << R << OP_DROP << OP_CHECKSIG; + if (dest.IsScript()) + *this << OP_HASH160 << dest.GetData() << OP_EQUAL; + else if (dest.IsPubKey()) + *this << OP_DUP << OP_HASH160 << dest.GetData() << OP_EQUALVERIFY << OP_CHECKSIG; + else if (dest.IsPair()) { + // Pubkey pair address, going to generate + // new one-time public key. + CMalleablePubKey mpk; + if (!mpk.setvch(dest.GetData())) + return; + CPubKey R, pubKeyVariant; + mpk.GetVariant(R, pubKeyVariant); + *this << pubKeyVariant << R << OP_DROP << OP_CHECKSIG; + } } - void CScript::SetMultisig(int nRequired, const std::vector& keys) { this->clear(); diff --git a/src/script.h b/src/script.h index 00b0525..af523e6 100644 --- a/src/script.h +++ b/src/script.h @@ -12,10 +12,12 @@ #include "keystore.h" #include "bignum.h" +#include "base58.h" typedef std::vector valtype; class CTransaction; +class CBitcoinAddress; static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes @@ -583,7 +585,7 @@ public: bool HasCanonicalPushes() const; void SetDestination(const CTxDestination& address); - void SetDestination(const CPubKey& R, CPubKey& pubKeyVariant); + void SetAddress(const CBitcoinAddress& dest); void SetMultisig(int nRequired, const std::vector& keys); -- 1.7.1