}
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
{
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
case PUBKEY_PAIR_ADDRESS_TEST:
nExpectedSize = 68;
fExpectTestNet = true;
+ fSimple = false;
break;
case PUBKEY_ADDRESS_TEST:
nExpectedSize = 20;
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 {
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())
CTxDestination Get() const;
bool GetKeyID(CKeyID &keyID) const;
bool IsScript() const;
+ bool IsPubKey() const;
bool IsPair() const;
};
#include "init.h"
#include "base58.h"
#include "bitcoinunits.h"
+#include "wallet.h"
#include "walletmodel.h"
#include "addresstablemodel.h"
#include "optionsmodel.h"
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
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();
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<valtype> 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
close();
}
#endif
-}
\ No newline at end of file
+}
foreach(const SendCoinsRecipient &rcp, recipients)
{
CScript scriptPubKey;
- scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
+ scriptPubKey.SetAddress(CBitcoinAddress(rcp.address.toStdString()));
vecSend.push_back(make_pair(scriptPubKey, rcp.amount));
}
CWallet* WalletModel::getWallet()
{
return wallet;
-}
\ No newline at end of file
+}
if (address.IsValid())
{
+ scriptPubKey.SetAddress(address);
+
+ // Don't perform duplication checking for pubkey-pair addresses
if (!address.IsPair())
{
- scriptPubKey.SetDestination(address.Get());
if (setAddress.count(address))
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
setAddress.insert(address);
}
- else
- {
- CMalleablePubKey mpk;
- if (!mpk.setvch(address.GetData()))
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid output destination: ")+s.name_);
-
- CPubKey R, pubKeyVariant;
- mpk.GetVariant(R, pubKeyVariant);
- scriptPubKey.SetDestination(R, pubKeyVariant);
- }
}
else
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid output destination: ")+s.name_);
CBitcoinAddress address(strAddress);
if (address.IsValid())
- {
- if (!address.IsPair())
- scriptPubKey.SetDestination(address.Get());
- else
- {
- CMalleablePubKey mpk;
- if (!mpk.setvch(address.GetData()))
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
-
- CPubKey R, pubKeyVariant;
- mpk.GetVariant(R, pubKeyVariant);
- scriptPubKey.SetDestination(R, pubKeyVariant);
- }
- }
+ scriptPubKey.SetAddress(address);
else
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
CBitcoinAddress address(strAddress);
if (address.IsValid())
- {
- if (!address.IsPair())
- scriptPubKey.SetDestination(address.Get());
- else
- {
- CMalleablePubKey mpk;
- if (!mpk.setvch(address.GetData()))
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
-
- CPubKey R, pubKeyVariant;
- mpk.GetVariant(R, pubKeyVariant);
- scriptPubKey.SetDestination(R, pubKeyVariant);
- }
- }
+ scriptPubKey.SetAddress(address);
else
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid NovaCoin address: ")+s.name_);
- if (setAddress.count(address))
- throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
- setAddress.insert(address);
+ if (!address.IsPair())
+ {
+ if (setAddress.count(address))
+ throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
+ setAddress.insert(address);
+ }
CScript scriptPubKey;
- scriptPubKey.SetDestination(address.Get());
+ scriptPubKey.SetAddress(address);
int64_t nAmount = AmountFromValue(s.value_);
if (nAmount < nMinimumInputValue)
boost::apply_visitor(CScriptVisitor(this), dest);
}
-void CScript::SetDestination(const CPubKey& R, CPubKey& pubKeyVariant)
+void CScript::SetAddress(const CBitcoinAddress& dest)
{
this->clear();
- *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<CKey>& keys)
{
this->clear();
#include "keystore.h"
#include "bignum.h"
+#include "base58.h"
typedef std::vector<uint8_t> valtype;
class CTransaction;
+class CBitcoinAddress;
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes
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<CKey>& keys);