Permalink
Browse files

Refactor: split CKeyID/CScriptID/CTxDestination from CBitcoinAddress

This introduces internal types:
* CKeyID: reference (hash160) of a key
* CScriptID: reference (hash160) of a script
* CTxDestination: a boost::variant of the former two

CBitcoinAddress is retrofitted to be a Base58 encoding of a
CTxDestination. This allows all internal code to only use the
internal types, and only have RPC and GUI depend on the base58 code.

Furthermore, the header dependencies are a lot saner now. base58.h is
at the top (right below rpc and gui) instead of at the bottom. For the
rest: wallet -> script -> keystore -> key. Only keystore still requires
a forward declaration of CScript. Solving that would require splitting
script into two layers.
  • Loading branch information...
1 parent fd61d6f commit 1025440184ef100a22d07c7bb543ee45cf169d64 @sipa sipa committed May 14, 2012
View
101 src/base58.h
@@ -19,6 +19,7 @@
#include <vector>
#include "bignum.h"
#include "key.h"
+#include "script.h"
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
@@ -258,6 +259,18 @@ class CBase58Data
* Script-hash-addresses have version 5 (or 196 testnet).
* The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
*/
+class CBitcoinAddress;
+class CBitcoinAddressVisitor : public boost::static_visitor<bool>
+{
+private:
+ CBitcoinAddress *addr;
+public:
+ CBitcoinAddressVisitor(CBitcoinAddress *addrIn) : addr(addrIn) { }
+ bool operator()(const CKeyID &id) const;
+ bool operator()(const CScriptID &id) const;
+ bool operator()(const CNoDestination &no) const;
+};
+
class CBitcoinAddress : public CBase58Data
{
public:
@@ -269,21 +282,19 @@ class CBitcoinAddress : public CBase58Data
SCRIPT_ADDRESS_TEST = 196,
};
- bool SetHash160(const uint160& hash160)
- {
- SetData(fTestNet ? PUBKEY_ADDRESS_TEST : PUBKEY_ADDRESS, &hash160, 20);
+ bool Set(const CKeyID &id) {
+ SetData(fTestNet ? PUBKEY_ADDRESS_TEST : PUBKEY_ADDRESS, &id, 20);
return true;
}
- void SetPubKey(const CPubKey& vchPubKey)
- {
- SetHash160(vchPubKey.GetID());
+ bool Set(const CScriptID &id) {
+ SetData(fTestNet ? SCRIPT_ADDRESS_TEST : SCRIPT_ADDRESS, &id, 20);
+ return true;
}
- bool SetScriptHash160(const uint160& hash160)
+ bool Set(const CTxDestination &dest)
{
- SetData(fTestNet ? SCRIPT_ADDRESS_TEST : SCRIPT_ADDRESS, &hash160, 20);
- return true;
+ return boost::apply_visitor(CBitcoinAddressVisitor(this), dest);
}
bool IsValid() const
@@ -315,27 +326,14 @@ class CBitcoinAddress : public CBase58Data
}
return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize;
}
- bool IsScript() const
- {
- if (!IsValid())
- return false;
- if (fTestNet)
- return nVersion == SCRIPT_ADDRESS_TEST;
- return nVersion == SCRIPT_ADDRESS;
- }
CBitcoinAddress()
{
}
- CBitcoinAddress(uint160 hash160In)
- {
- SetHash160(hash160In);
- }
-
- CBitcoinAddress(const CPubKey& vchPubKey)
+ CBitcoinAddress(const CTxDestination &dest)
{
- SetPubKey(vchPubKey);
+ Set(dest);
}
CBitcoinAddress(const std::string& strAddress)
@@ -348,15 +346,58 @@ class CBitcoinAddress : public CBase58Data
SetString(pszAddress);
}
- uint160 GetHash160() const
- {
- assert(vchData.size() == 20);
- uint160 hash160;
- memcpy(&hash160, &vchData[0], 20);
- return hash160;
+ CTxDestination Get() const {
+ if (!IsValid())
+ return CNoDestination();
+ switch (nVersion) {
+ case PUBKEY_ADDRESS:
+ case PUBKEY_ADDRESS_TEST: {
+ uint160 id;
+ memcpy(&id, &vchData[0], 20);
+ return CKeyID(id);
+ }
+ case SCRIPT_ADDRESS:
+ case SCRIPT_ADDRESS_TEST: {
+ uint160 id;
+ memcpy(&id, &vchData[0], 20);
+ return CScriptID(id);
+ }
+ }
+ return CNoDestination();
+ }
+
+ bool GetKeyID(CKeyID &keyID) const {
+ if (!IsValid())
+ return false;
+ switch (nVersion) {
+ case PUBKEY_ADDRESS:
+ case PUBKEY_ADDRESS_TEST: {
+ uint160 id;
+ memcpy(&id, &vchData[0], 20);
+ keyID = CKeyID(id);
+ return true;
+ }
+ default: return false;
+ }
+ }
+
+ bool IsScript() const {
+ if (!IsValid())
+ return false;
+ switch (nVersion) {
+ case SCRIPT_ADDRESS:
+ case SCRIPT_ADDRESS_TEST: {
+ return true;
+ }
+ default: return false;
+ }
}
};
+bool inline CBitcoinAddressVisitor::operator()(const CKeyID &id) const { return addr->Set(id); }
+bool inline CBitcoinAddressVisitor::operator()(const CScriptID &id) const { return addr->Set(id); }
+bool inline CBitcoinAddressVisitor::operator()(const CNoDestination &id) const { return false; }
+
/** A base58-encoded secret key */
class CBitcoinSecret : public CBase58Data
{
View
199 src/bitcoinrpc.cpp
@@ -10,6 +10,7 @@
#include "net.h"
#include "init.h"
#include "ui_interface.h"
+#include "base58.h"
#include "bitcoinrpc.h"
#undef printf
@@ -184,10 +185,10 @@ ScriptSigToJSON(const CTxIn& txin, Object& out)
return;
txnouttype type;
- vector<CBitcoinAddress> addresses;
+ vector<CTxDestination> addresses;
int nRequired;
- if (!ExtractAddresses(txprev.vout[txin.prevout.n].scriptPubKey, type,
+ if (!ExtractDestinations(txprev.vout[txin.prevout.n].scriptPubKey, type,
addresses, nRequired))
{
out.push_back(Pair("type", GetTxnOutputType(TX_NONSTANDARD)));
@@ -202,22 +203,22 @@ ScriptSigToJSON(const CTxIn& txin, Object& out)
}
Array a;
- BOOST_FOREACH(const CBitcoinAddress& addr, addresses)
- a.push_back(addr.ToString());
+ BOOST_FOREACH(const CTxDestination& addr, addresses)
+ a.push_back(CBitcoinAddress(addr).ToString());
out.push_back(Pair("addresses", a));
}
void
ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out)
{
txnouttype type;
- vector<CBitcoinAddress> addresses;
+ vector<CTxDestination> addresses;
int nRequired;
out.push_back(Pair("asm", scriptPubKey.ToString()));
out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
- if (!ExtractAddresses(scriptPubKey, type, addresses, nRequired))
+ if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired))
{
out.push_back(Pair("type", GetTxnOutputType(TX_NONSTANDARD)));
return;
@@ -227,8 +228,8 @@ ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out)
out.push_back(Pair("type", GetTxnOutputType(type)));
Array a;
- BOOST_FOREACH(const CBitcoinAddress& addr, addresses)
- a.push_back(addr.ToString());
+ BOOST_FOREACH(const CTxDestination& addr, addresses)
+ a.push_back(CBitcoinAddress(addr).ToString());
out.push_back(Pair("addresses", a));
}
@@ -593,11 +594,11 @@ Value getnewaddress(const Array& params, bool fHelp)
CPubKey newKey;
if (!pwalletMain->GetKeyFromPool(newKey, false))
throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
- CBitcoinAddress address(newKey);
+ CKeyID keyID = newKey.GetID();
- pwalletMain->SetAddressBookName(address, strAccount);
+ pwalletMain->SetAddressBookName(keyID, strAccount);
- return address.ToString();
+ return CBitcoinAddress(keyID).ToString();
}
@@ -614,7 +615,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
if (account.vchPubKey.IsValid())
{
CScript scriptPubKey;
- scriptPubKey.SetBitcoinAddress(account.vchPubKey);
+ scriptPubKey.SetDestination(account.vchPubKey.GetID());
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid();
++it)
@@ -632,11 +633,11 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
- pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount);
+ pwalletMain->SetAddressBookName(account.vchPubKey.GetID(), strAccount);
walletdb.WriteAccount(strAccount, account);
}
- return CBitcoinAddress(account.vchPubKey);
+ return CBitcoinAddress(account.vchPubKey.GetID());
}
Value getaccountaddress(const Array& params, bool fHelp)
@@ -675,14 +676,14 @@ Value setaccount(const Array& params, bool fHelp)
strAccount = AccountFromValue(params[1]);
// Detect when changing the account of an address that is the 'unused current key' of another account:
- if (pwalletMain->mapAddressBook.count(address))
+ if (pwalletMain->mapAddressBook.count(address.Get()))
{
- string strOldAccount = pwalletMain->mapAddressBook[address];
+ string strOldAccount = pwalletMain->mapAddressBook[address.Get()];
if (address == GetAccountAddress(strOldAccount))
GetAccountAddress(strOldAccount, true);
}
- pwalletMain->SetAddressBookName(address, strAccount);
+ pwalletMain->SetAddressBookName(address.Get(), strAccount);
return Value::null;
}
@@ -700,7 +701,7 @@ Value getaccount(const Array& params, bool fHelp)
throw JSONRPCError(-5, "Invalid Bitcoin address");
string strAccount;
- map<CBitcoinAddress, string>::iterator mi = pwalletMain->mapAddressBook.find(address);
+ map<CTxDestination, string>::iterator mi = pwalletMain->mapAddressBook.find(address.Get());
if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty())
strAccount = (*mi).second;
return strAccount;
@@ -769,7 +770,7 @@ Value sendtoaddress(const Array& params, bool fHelp)
if (pwalletMain->IsLocked())
throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
- string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
+ string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
if (strError != "")
throw JSONRPCError(-4, strError);
@@ -792,8 +793,12 @@ Value signmessage(const Array& params, bool fHelp)
if (!addr.IsValid())
throw JSONRPCError(-3, "Invalid address");
+ CKeyID keyID;
+ if (!addr.GetKeyID(keyID))
+ throw JSONRPCError(-3, "Address does not refer to key");
+
CKey key;
- if (!pwalletMain->GetKey(addr, key))
+ if (!pwalletMain->GetKey(keyID, key))
throw JSONRPCError(-4, "Private key not available");
CDataStream ss(SER_GETHASH, 0);
@@ -822,6 +827,10 @@ Value verifymessage(const Array& params, bool fHelp)
if (!addr.IsValid())
throw JSONRPCError(-3, "Invalid address");
+ CKeyID keyID;
+ if (!addr.GetKeyID(keyID))
+ throw JSONRPCError(-3, "Address does not refer to key");
+
bool fInvalid = false;
vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
@@ -836,7 +845,7 @@ Value verifymessage(const Array& params, bool fHelp)
if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig))
return false;
- return (CBitcoinAddress(key.GetPubKey()) == addr);
+ return (key.GetPubKey().GetID() == keyID);
}
@@ -852,7 +861,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
CScript scriptPubKey;
if (!address.IsValid())
throw JSONRPCError(-5, "Invalid Bitcoin address");
- scriptPubKey.SetBitcoinAddress(address);
+ scriptPubKey.SetDestination(address.Get());
if (!IsMine(*pwalletMain,scriptPubKey))
return (double)0.0;
@@ -879,18 +888,17 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
}
-void GetAccountAddresses(string strAccount, set<CBitcoinAddress>& setAddress)
+void GetAccountAddresses(string strAccount, set<CTxDestination>& setAddress)
{
- BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
+ BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& item, pwalletMain->mapAddressBook)
{
- const CBitcoinAddress& address = item.first;
+ const CTxDestination& address = item.first;
const string& strName = item.second;
if (strName == strAccount)
setAddress.insert(address);
}
}
-
Value getreceivedbyaccount(const Array& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
@@ -905,7 +913,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
// Get the set of pub keys assigned to account
string strAccount = AccountFromValue(params[0]);
- set<CBitcoinAddress> setAddress;
+ set<CTxDestination> setAddress;
GetAccountAddresses(strAccount, setAddress);
// Tally
@@ -918,8 +926,8 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
{
- CBitcoinAddress address;
- if (ExtractAddress(txout.scriptPubKey, address) && pwalletMain->HaveKey(address) && setAddress.count(address))
+ CTxDestination address;
+ if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address))
if (wtx.GetDepthInMainChain() >= nMinDepth)
nAmount += txout.nValue;
}
@@ -990,15 +998,15 @@ Value getbalance(const Array& params, bool fHelp)
int64 allGeneratedImmature, allGeneratedMature, allFee;
allGeneratedImmature = allGeneratedMature = allFee = 0;
string strSentAccount;
- list<pair<CBitcoinAddress, int64> > listReceived;
- list<pair<CBitcoinAddress, int64> > listSent;
+ list<pair<CTxDestination, int64> > listReceived;
+ list<pair<CTxDestination, int64> > listSent;
wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
if (wtx.GetDepthInMainChain() >= nMinDepth)
{
- BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
+ BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listReceived)
nBalance += r.second;
}
- BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listSent)
+ BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listSent)
nBalance -= r.second;
nBalance -= allFee;
nBalance += allGeneratedMature;
@@ -1094,7 +1102,7 @@ Value sendfrom(const Array& params, bool fHelp)
throw JSONRPCError(-6, "Account has insufficient funds");
// Send
- string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
+ string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
if (strError != "")
throw JSONRPCError(-4, strError);
@@ -1136,7 +1144,7 @@ Value sendmany(const Array& params, bool fHelp)
setAddress.insert(address);
CScript scriptPubKey;
- scriptPubKey.SetBitcoinAddress(address);
+ scriptPubKey.SetDestination(address.Get());
int64 nAmount = AmountFromValue(s.value_);
totalAmount += nAmount;
@@ -1200,11 +1208,12 @@ Value addmultisigaddress(const Array& params, bool fHelp)
CBitcoinAddress address(ks);
if (address.IsValid())
{
- if (address.IsScript())
+ CKeyID keyID;
+ if (!address.GetKeyID(keyID))
throw runtime_error(
- strprintf("%s is a pay-to-script address",ks.c_str()));
+ strprintf("%s does not refer to a key",ks.c_str()));
CPubKey vchPubKey;
- if (!pwalletMain->GetPubKey(address, vchPubKey))
+ if (!pwalletMain->GetPubKey(keyID, vchPubKey))
throw runtime_error(
strprintf("no full public key for address %s",ks.c_str()));
if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey))
@@ -1227,16 +1236,11 @@ Value addmultisigaddress(const Array& params, bool fHelp)
// Construct using pay-to-script-hash:
CScript inner;
inner.SetMultisig(nRequired, pubkeys);
-
- uint160 scriptHash = Hash160(inner);
- CScript scriptPubKey;
- scriptPubKey.SetPayToScriptHash(inner);
+ CScriptID innerID = inner.GetID();
pwalletMain->AddCScript(inner);
- CBitcoinAddress address;
- address.SetScriptHash160(scriptHash);
- pwalletMain->SetAddressBookName(address, strAccount);
- return address.ToString();
+ pwalletMain->SetAddressBookName(innerID, strAccount);
+ return CBitcoinAddress(innerID).ToString();
}
@@ -1278,8 +1282,8 @@ Value ListReceived(const Array& params, bool fByAccounts)
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
{
- CBitcoinAddress address;
- if (!ExtractAddress(txout.scriptPubKey, address) || !pwalletMain->HaveKey(address) || !address.IsValid())
+ CTxDestination address;
+ if (!ExtractDestination(txout.scriptPubKey, address) || !IsMine(*pwalletMain, address))
continue;
tallyitem& item = mapTally[address];
@@ -1376,8 +1380,8 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
{
int64 nGeneratedImmature, nGeneratedMature, nFee;
string strSentAccount;
- list<pair<CBitcoinAddress, int64> > listReceived;
- list<pair<CBitcoinAddress, int64> > listSent;
+ list<pair<CTxDestination, int64> > listReceived;
+ list<pair<CTxDestination, int64> > listSent;
wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
@@ -1406,11 +1410,11 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
// Sent
if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
{
- BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
+ BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& s, listSent)
{
Object entry;
entry.push_back(Pair("account", strSentAccount));
- entry.push_back(Pair("address", s.first.ToString()));
+ entry.push_back(Pair("address", CBitcoinAddress(s.first).ToString()));
entry.push_back(Pair("category", "send"));
entry.push_back(Pair("amount", ValueFromAmount(-s.second)));
entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
@@ -1423,7 +1427,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
// Received
if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
{
- BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
+ BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& r, listReceived)
{
string account;
if (pwalletMain->mapAddressBook.count(r.first))
@@ -1432,7 +1436,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
{
Object entry;
entry.push_back(Pair("account", account));
- entry.push_back(Pair("address", r.first.ToString()));
+ entry.push_back(Pair("address", CBitcoinAddress(r.first).ToString()));
entry.push_back(Pair("category", "receive"));
entry.push_back(Pair("amount", ValueFromAmount(r.second)));
if (fLong)
@@ -1547,8 +1551,8 @@ Value listaccounts(const Array& params, bool fHelp)
nMinDepth = params[0].get_int();
map<string, int64> mapAccountBalances;
- BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& entry, pwalletMain->mapAddressBook) {
- if (pwalletMain->HaveKey(entry.first)) // This address belongs to me
+ BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& entry, pwalletMain->mapAddressBook) {
+ if (IsMine(*pwalletMain, entry.first)) // This address belongs to me
mapAccountBalances[entry.second] = 0;
}
@@ -1557,16 +1561,16 @@ Value listaccounts(const Array& params, bool fHelp)
const CWalletTx& wtx = (*it).second;
int64 nGeneratedImmature, nGeneratedMature, nFee;
string strSentAccount;
- list<pair<CBitcoinAddress, int64> > listReceived;
- list<pair<CBitcoinAddress, int64> > listSent;
+ list<pair<CTxDestination, int64> > listReceived;
+ list<pair<CTxDestination, int64> > listSent;
wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
mapAccountBalances[strSentAccount] -= nFee;
- BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
+ BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& s, listSent)
mapAccountBalances[strSentAccount] -= s.second;
if (wtx.GetDepthInMainChain() >= nMinDepth)
{
mapAccountBalances[""] += nGeneratedMature;
- BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
+ BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& r, listReceived)
if (pwalletMain->mapAddressBook.count(r.first))
mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
else
@@ -1932,6 +1936,40 @@ Value encryptwallet(const Array& params, bool fHelp)
return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet";
}
+class DescribeAddressVisitor : public boost::static_visitor<Object>
+{
+public:
+ Object operator()(const CNoDestination &dest) const { return Object(); }
+
+ Object operator()(const CKeyID &keyID) const {
+ Object obj;
+ CPubKey vchPubKey;
+ pwalletMain->GetPubKey(keyID, vchPubKey);
+ obj.push_back(Pair("isscript", false));
+ obj.push_back(Pair("pubkey", HexStr(vchPubKey.Raw())));
+ obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
+ return obj;
+ }
+
+ Object operator()(const CScriptID &scriptID) const {
+ Object obj;
+ obj.push_back(Pair("isscript", true));
+ CScript subscript;
+ pwalletMain->GetCScript(scriptID, subscript);
+ std::vector<CTxDestination> addresses;
+ txnouttype whichType;
+ int nRequired;
+ ExtractDestinations(subscript, whichType, addresses, nRequired);
+ obj.push_back(Pair("script", GetTxnOutputType(whichType)));
+ Array a;
+ BOOST_FOREACH(const CTxDestination& addr, addresses)
+ a.push_back(CBitcoinAddress(addr).ToString());
+ obj.push_back(Pair("addresses", a));
+ if (whichType == TX_MULTISIG)
+ obj.push_back(Pair("sigsrequired", nRequired));
+ return obj;
+ }
+};
Value validateaddress(const Array& params, bool fHelp)
{
@@ -1947,42 +1985,17 @@ Value validateaddress(const Array& params, bool fHelp)
ret.push_back(Pair("isvalid", isValid));
if (isValid)
{
- // Call Hash160ToAddress() so we always return current ADDRESSVERSION
- // version of the address:
+ CTxDestination dest = address.Get();
string currentAddress = address.ToString();
ret.push_back(Pair("address", currentAddress));
- if (pwalletMain->HaveKey(address))
- {
- ret.push_back(Pair("ismine", true));
- CPubKey vchPubKey;
- pwalletMain->GetPubKey(address, vchPubKey);
- ret.push_back(Pair("pubkey", HexStr(vchPubKey.Raw())));
- CKey key;
- key.SetPubKey(vchPubKey);
- ret.push_back(Pair("iscompressed", key.IsCompressed()));
- }
- else if (pwalletMain->HaveCScript(address.GetHash160()))
- {
- ret.push_back(Pair("isscript", true));
- CScript subscript;
- pwalletMain->GetCScript(address.GetHash160(), subscript);
- ret.push_back(Pair("ismine", ::IsMine(*pwalletMain, subscript)));
- std::vector<CBitcoinAddress> addresses;
- txnouttype whichType;
- int nRequired;
- ExtractAddresses(subscript, whichType, addresses, nRequired);
- ret.push_back(Pair("script", GetTxnOutputType(whichType)));
- Array a;
- BOOST_FOREACH(const CBitcoinAddress& addr, addresses)
- a.push_back(addr.ToString());
- ret.push_back(Pair("addresses", a));
- if (whichType == TX_MULTISIG)
- ret.push_back(Pair("sigsrequired", nRequired));
+ bool fMine = IsMine(*pwalletMain, dest);
+ ret.push_back(Pair("ismine", fMine));
+ if (fMine) {
+ Object detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
+ ret.insert(ret.end(), detail.begin(), detail.end());
}
- else
- ret.push_back(Pair("ismine", false));
- if (pwalletMain->mapAddressBook.count(address))
- ret.push_back(Pair("account", pwalletMain->mapAddressBook[address]));
+ if (pwalletMain->mapAddressBook.count(dest))
+ ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest]));
}
return ret;
}
View
2 src/init.cpp
@@ -608,7 +608,7 @@ bool AppInit2()
if (!pwalletMain->GetKeyFromPool(newDefaultKey, false))
strErrors << _("Cannot initialize keypool") << "\n";
pwalletMain->SetDefaultKey(newDefaultKey);
- if (!pwalletMain->SetAddressBookName(CBitcoinAddress(pwalletMain->vchDefaultKey), ""))
+ if (!pwalletMain->SetAddressBookName(pwalletMain->vchDefaultKey.GetID(), ""))
strErrors << _("Cannot write default address") << "\n";
}
View
25 src/key.h
@@ -44,6 +44,23 @@ class key_error : public std::runtime_error
explicit key_error(const std::string& str) : std::runtime_error(str) {}
};
+/** A reference to a CKey: the Hash160 of its serialized public key */
+class CKeyID : public uint160
+{
+public:
+ CKeyID() : uint160(0) { }
+ CKeyID(const uint160 &in) : uint160(in) { }
+};
+
+/** A reference to a CScript: the Hash160 of its serialization (see script.h) */
+class CScriptID : public uint160
+{
+public:
+ CScriptID() : uint160(0) { }
+ CScriptID(const uint160 &in) : uint160(in) { }
+};
+
+/** An encapsulated public key. */
class CPubKey {
private:
std::vector<unsigned char> vchPubKey;
@@ -60,8 +77,8 @@ class CPubKey {
READWRITE(vchPubKey);
)
- uint160 GetID() const {
- return Hash160(vchPubKey);
+ CKeyID GetID() const {
+ return CKeyID(Hash160(vchPubKey));
}
uint256 GetHash() const {
@@ -72,6 +89,10 @@ class CPubKey {
return vchPubKey.size() == 33 || vchPubKey.size() == 65;
}
+ bool IsCompressed() const {
+ return vchPubKey.size() == 33;
+ }
+
std::vector<unsigned char> Raw() const {
return vchPubKey;
}
View
16 src/keystore.cpp
@@ -6,7 +6,7 @@
#include "keystore.h"
#include "script.h"
-bool CKeyStore::GetPubKey(const CBitcoinAddress &address, CPubKey &vchPubKeyOut) const
+bool CKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
{
CKey key;
if (!GetKey(address, key))
@@ -21,7 +21,7 @@ bool CBasicKeyStore::AddKey(const CKey& key)
CSecret secret = key.GetSecret(fCompressed);
{
LOCK(cs_KeyStore);
- mapKeys[CBitcoinAddress(key.GetPubKey())] = make_pair(secret, fCompressed);
+ mapKeys[key.GetPubKey().GetID()] = make_pair(secret, fCompressed);
}
return true;
}
@@ -30,12 +30,12 @@ bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
{
{
LOCK(cs_KeyStore);
- mapScripts[Hash160(redeemScript)] = redeemScript;
+ mapScripts[redeemScript.GetID()] = redeemScript;
}
return true;
}
-bool CBasicKeyStore::HaveCScript(const uint160& hash) const
+bool CBasicKeyStore::HaveCScript(const CScriptID& hash) const
{
bool result;
{
@@ -46,7 +46,7 @@ bool CBasicKeyStore::HaveCScript(const uint160& hash) const
}
-bool CBasicKeyStore::GetCScript(const uint160 &hash, CScript& redeemScriptOut) const
+bool CBasicKeyStore::GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const
{
{
LOCK(cs_KeyStore);
@@ -147,12 +147,12 @@ bool CCryptoKeyStore::AddCryptedKey(const CPubKey &vchPubKey, const std::vector<
if (!SetCrypted())
return false;
- mapCryptedKeys[CBitcoinAddress(vchPubKey)] = make_pair(vchPubKey, vchCryptedSecret);
+ mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret);
}
return true;
}
-bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
+bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey& keyOut) const
{
{
LOCK(cs_KeyStore);
@@ -177,7 +177,7 @@ bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
return false;
}
-bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, CPubKey& vchPubKeyOut) const
+bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
{
{
LOCK(cs_KeyStore);
View
39 src/keystore.h
@@ -7,7 +7,6 @@
#include "crypter.h"
#include "sync.h"
-#include "base58.h"
#include <boost/signals2/signal.hpp>
class CScript;
@@ -25,17 +24,17 @@ class CKeyStore
virtual bool AddKey(const CKey& key) =0;
// Check whether a key corresponding to a given address is present in the store.
- virtual bool HaveKey(const CBitcoinAddress &address) const =0;
- virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0;
- virtual void GetKeys(std::set<CBitcoinAddress> &setAddress) const =0;
- virtual bool GetPubKey(const CBitcoinAddress &address, CPubKey& vchPubKeyOut) const;
+ virtual bool HaveKey(const CKeyID &address) const =0;
+ virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0;
+ virtual void GetKeys(std::set<CKeyID> &setAddress) const =0;
+ virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
// Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013
virtual bool AddCScript(const CScript& redeemScript) =0;
- virtual bool HaveCScript(const uint160 &hash) const =0;
- virtual bool GetCScript(const uint160 &hash, CScript& redeemScriptOut) const =0;
+ virtual bool HaveCScript(const CScriptID &hash) const =0;
+ virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const =0;
- virtual bool GetSecret(const CBitcoinAddress &address, CSecret& vchSecret, bool &fCompressed) const
+ virtual bool GetSecret(const CKeyID &address, CSecret& vchSecret, bool &fCompressed) const
{
CKey key;
if (!GetKey(address, key))
@@ -45,8 +44,8 @@ class CKeyStore
}
};
-typedef std::map<CBitcoinAddress, std::pair<CSecret, bool> > KeyMap;
-typedef std::map<uint160, CScript > ScriptMap;
+typedef std::map<CKeyID, std::pair<CSecret, bool> > KeyMap;
+typedef std::map<CScriptID, CScript > ScriptMap;
/** Basic key store, that keeps keys in an address->secret map */
class CBasicKeyStore : public CKeyStore
@@ -57,7 +56,7 @@ class CBasicKeyStore : public CKeyStore
public:
bool AddKey(const CKey& key);
- bool HaveKey(const CBitcoinAddress &address) const
+ bool HaveKey(const CKeyID &address) const
{
bool result;
{
@@ -66,7 +65,7 @@ class CBasicKeyStore : public CKeyStore
}
return result;
}
- void GetKeys(std::set<CBitcoinAddress> &setAddress) const
+ void GetKeys(std::set<CKeyID> &setAddress) const
{
setAddress.clear();
{
@@ -79,7 +78,7 @@ class CBasicKeyStore : public CKeyStore
}
}
}
- bool GetKey(const CBitcoinAddress &address, CKey &keyOut) const
+ bool GetKey(const CKeyID &address, CKey &keyOut) const
{
{
LOCK(cs_KeyStore);
@@ -94,11 +93,11 @@ class CBasicKeyStore : public CKeyStore
return false;
}
virtual bool AddCScript(const CScript& redeemScript);
- virtual bool HaveCScript(const uint160 &hash) const;
- virtual bool GetCScript(const uint160 &hash, CScript& redeemScriptOut) const;
+ virtual bool HaveCScript(const CScriptID &hash) const;
+ virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const;
};
-typedef std::map<CBitcoinAddress, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
+typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
/** Keystore which keeps the private keys encrypted.
* It derives from the basic key store, which is used if no encryption is active.
@@ -148,7 +147,7 @@ class CCryptoKeyStore : public CBasicKeyStore
virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
bool AddKey(const CKey& key);
- bool HaveKey(const CBitcoinAddress &address) const
+ bool HaveKey(const CKeyID &address) const
{
{
LOCK(cs_KeyStore);
@@ -158,9 +157,9 @@ class CCryptoKeyStore : public CBasicKeyStore
}
return false;
}
- bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const;
- bool GetPubKey(const CBitcoinAddress &address, CPubKey& vchPubKeyOut) const;
- void GetKeys(std::set<CBitcoinAddress> &setAddress) const
+ bool GetKey(const CKeyID &address, CKey& keyOut) const;
+ bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
+ void GetKeys(std::set<CKeyID> &setAddress) const
{
if (!IsCrypted())
{
View
22 src/qt/addresstablemodel.cpp
@@ -3,6 +3,7 @@
#include "walletmodel.h"
#include "wallet.h"
+#include "base58.h"
#include <QFont>
#include <QColor>
@@ -58,11 +59,11 @@ class AddressTablePriv
cachedAddressTable.clear();
{
LOCK(wallet->cs_wallet);
- BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, std::string)& item, wallet->mapAddressBook)
+ BOOST_FOREACH(const PAIRTYPE(CTxDestination, std::string)& item, wallet->mapAddressBook)
{
const CBitcoinAddress& address = item.first;
const std::string& strName = item.second;
- bool fMine = wallet->HaveKey(address);
+ bool fMine = IsMine(*wallet, address.Get());
cachedAddressTable.append(AddressTableEntry(fMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending,
QString::fromStdString(strName),
QString::fromStdString(address.ToString())));
@@ -220,7 +221,8 @@ bool AddressTableModel::setData(const QModelIndex & index, const QVariant & valu
switch(index.column())
{
case Label:
- wallet->SetAddressBookName(rec->address.toStdString(), value.toString().toStdString());
+ wallet->SetAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get(), value.toString().toStdString());
+ rec->label = value.toString();
break;
case Address:
// Refuse to set invalid address, set error status and return false
@@ -235,9 +237,9 @@ bool AddressTableModel::setData(const QModelIndex & index, const QVariant & valu
{
LOCK(wallet->cs_wallet);
// Remove old entry
- wallet->DelAddressBookName(rec->address.toStdString());
+ wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get());
// Add new entry with new address
- wallet->SetAddressBookName(value.toString().toStdString(), rec->label.toStdString());
+ wallet->SetAddressBookName(CBitcoinAddress(value.toString().toStdString()).Get(), rec->label.toStdString());
}
}
break;
@@ -314,7 +316,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
// Check for duplicate addresses
{
LOCK(wallet->cs_wallet);
- if(wallet->mapAddressBook.count(strAddress))
+ if(wallet->mapAddressBook.count(CBitcoinAddress(strAddress).Get()))
{
editStatus = DUPLICATE_ADDRESS;
return QString();
@@ -337,7 +339,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
editStatus = KEY_GENERATION_FAILURE;
return QString();
}
- strAddress = CBitcoinAddress(newKey).ToString();
+ strAddress = CBitcoinAddress(newKey.GetID()).ToString();
}
else
{
@@ -346,7 +348,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
// Add entry
{
LOCK(wallet->cs_wallet);
- wallet->SetAddressBookName(strAddress, strLabel);
+ wallet->SetAddressBookName(CBitcoinAddress(strAddress).Get(), strLabel);
}
return QString::fromStdString(strAddress);
}
@@ -363,7 +365,7 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex & paren
}
{
LOCK(wallet->cs_wallet);
- wallet->DelAddressBookName(rec->address.toStdString());
+ wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get());
}
return true;
}
@@ -375,7 +377,7 @@ QString AddressTableModel::labelForAddress(const QString &address) const
{
LOCK(wallet->cs_wallet);
CBitcoinAddress address_parsed(address.toStdString());
- std::map<CBitcoinAddress, std::string>::iterator mi = wallet->mapAddressBook.find(address_parsed);
+ std::map<CTxDestination, std::string>::iterator mi = wallet->mapAddressBook.find(address_parsed.Get());
if (mi != wallet->mapAddressBook.end())
{
return QString::fromStdString(mi->second);
View
10 src/qt/messagepage.cpp
@@ -10,6 +10,7 @@
#include "main.h"
#include "wallet.h"
#include "init.h"
+#include "base58.h"
#include "messagepage.h"
#include "ui_messagepage.h"
@@ -83,6 +84,13 @@ void MessagePage::on_signMessage_clicked()
QMessageBox::Abort, QMessageBox::Abort);
return;
}
+ CKeyID keyID;
+ if (!addr.GetKeyID(keyID))
+ {
+ QMessageBox::critical(this, tr("Error signing"), tr("%1 does not refer to a key.").arg(address),
+ QMessageBox::Abort, QMessageBox::Abort);
+ return;
+ }
WalletModel::UnlockContext ctx(model->requestUnlock());
if(!ctx.isValid())
@@ -92,7 +100,7 @@ void MessagePage::on_signMessage_clicked()
}
CKey key;
- if (!pwalletMain->GetKey(addr, key))
+ if (!pwalletMain->GetKey(keyID, key))
{
QMessageBox::critical(this, tr("Error signing"), tr("Private key for %1 is not available.").arg(address),
QMessageBox::Abort, QMessageBox::Abort);
View
24 src/qt/transactiondesc.cpp
@@ -7,6 +7,7 @@
#include "wallet.h"
#include "db.h"
#include "ui_interface.h"
+#include "base58.h"
#include <QString>
@@ -85,14 +86,14 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
{
if (wallet->IsMine(txout))
{
- CBitcoinAddress address;
- if (ExtractAddress(txout.scriptPubKey, address) && wallet->HaveKey(address))
+ CTxDestination address;
+ if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
{
if (wallet->mapAddressBook.count(address))
{
strHTML += tr("<b>From:</b> ") + tr("unknown") + "<br>";
strHTML += tr("<b>To:</b> ");
- strHTML += GUIUtil::HtmlEscape(address.ToString());
+ strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString());
if (!wallet->mapAddressBook[address].empty())
strHTML += tr(" (yours, label: ") + GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + ")";
else
@@ -115,8 +116,9 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
// Online transaction
strAddress = wtx.mapValue["to"];
strHTML += tr("<b>To:</b> ");
- if (wallet->mapAddressBook.count(strAddress) && !wallet->mapAddressBook[strAddress].empty())
- strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[strAddress]) + " ";
+ CTxDestination dest = CBitcoinAddress(strAddress).Get();
+ if (wallet->mapAddressBook.count(dest) && !wallet->mapAddressBook[dest].empty())
+ strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[dest]) + " ";
strHTML += GUIUtil::HtmlEscape(strAddress) + "<br>";
}
@@ -170,13 +172,13 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
if (wtx.mapValue["to"].empty())
{
// Offline transaction
- CBitcoinAddress address;
- if (ExtractAddress(txout.scriptPubKey, address))
+ CTxDestination address;
+ if (ExtractDestination(txout.scriptPubKey, address))
{
strHTML += tr("<b>To:</b> ");
if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].empty())
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + " ";
- strHTML += GUIUtil::HtmlEscape(address.ToString());
+ strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString());
strHTML += "<br>";
}
}
@@ -260,12 +262,12 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
{
strHTML += "<li>";
const CTxOut &vout = prev.vout[prevout.n];
- CBitcoinAddress address;
- if (ExtractAddress(vout.scriptPubKey, address))
+ CTxDestination address;
+ if (ExtractDestination(vout.scriptPubKey, address))
{
if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].empty())
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + " ";
- strHTML += QString::fromStdString(address.ToString());
+ strHTML += QString::fromStdString(CBitcoinAddress(address).ToString());
}
strHTML = strHTML + " Amount=" + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC,vout.nValue);
strHTML = strHTML + " IsMine=" + (wallet->IsMine(vout) ? "true" : "false") + "</li>";
View
13 src/qt/transactionrecord.cpp
@@ -1,6 +1,7 @@
#include "transactionrecord.h"
#include "wallet.h"
+#include "base58.h"
/* Return positive answer if transaction should be shown in list.
*/
@@ -50,19 +51,19 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
if(wallet->IsMine(txout))
{
TransactionRecord sub(hash, nTime);
- CBitcoinAddress address;
+ CTxDestination address;
sub.idx = parts.size(); // sequence number
sub.credit = txout.nValue;
if (wtx.IsCoinBase())
{
// Generated
sub.type = TransactionRecord::Generated;
}
- else if (ExtractAddress(txout.scriptPubKey, address) && wallet->HaveKey(address))
+ else if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
{
// Received by Bitcoin Address
sub.type = TransactionRecord::RecvWithAddress;
- sub.address = address.ToString();
+ sub.address = CBitcoinAddress(address).ToString();
}
else
{
@@ -113,12 +114,12 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
continue;
}
- CBitcoinAddress address;
- if (ExtractAddress(txout.scriptPubKey, address))
+ CTxDestination address;
+ if (ExtractDestination(txout.scriptPubKey, address))
{
// Sent to Bitcoin Address
sub.type = TransactionRecord::SendToAddress;
- sub.address = address.ToString();
+ sub.address = CBitcoinAddress(address).ToString();
}
else
{
View
3 src/qt/verifymessagedialog.cpp
@@ -14,6 +14,7 @@
#include "walletmodel.h"
#include "addresstablemodel.h"
#include "guiutil.h"
+#include "base58.h"
VerifyMessageDialog::VerifyMessageDialog(AddressTableModel *addressModel, QWidget *parent) :
QDialog(parent),
@@ -62,7 +63,7 @@ bool VerifyMessageDialog::checkAddress()
return false;
}
- CBitcoinAddress address(key.GetPubKey());
+ CBitcoinAddress address(key.GetPubKey().GetID());
QString qStringAddress = QString::fromStdString(address.ToString());
ui->lnAddress->setText(qStringAddress);
ui->copyToClipboard->setEnabled(true);
View
14 src/qt/walletmodel.cpp
@@ -7,6 +7,7 @@
#include "ui_interface.h"
#include "wallet.h"
#include "walletdb.h" // for BackupWallet
+#include "base58.h"
#include <QSet>
@@ -137,7 +138,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
foreach(const SendCoinsRecipient &rcp, recipients)
{
CScript scriptPubKey;
- scriptPubKey.SetBitcoinAddress(rcp.address.toStdString());
+ scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
vecSend.push_back(make_pair(scriptPubKey, rcp.amount));
}
@@ -169,16 +170,17 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
foreach(const SendCoinsRecipient &rcp, recipients)
{
std::string strAddress = rcp.address.toStdString();
+ CTxDestination dest = CBitcoinAddress(strAddress).Get();
std::string strLabel = rcp.label.toStdString();
{
LOCK(wallet->cs_wallet);
- std::map<CBitcoinAddress, std::string>::iterator mi = wallet->mapAddressBook.find(strAddress);
+ std::map<CTxDestination, std::string>::iterator mi = wallet->mapAddressBook.find(dest);
// Check if we have a new address or an updated label
if (mi == wallet->mapAddressBook.end() || mi->second != strLabel)
{
- wallet->SetAddressBookName(strAddress, strLabel);
+ wallet->SetAddressBookName(dest, strLabel);
}
}
}
@@ -268,11 +270,11 @@ static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel, CCryptoKeyStor
QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection);
}
-static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, const std::string &address, const std::string &label, bool isMine, ChangeType status)
+static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, ChangeType status)
{
- OutputDebugStringF("NotifyAddressBookChanged %s %s isMine=%i status=%i\n", address.c_str(), label.c_str(), isMine, status);
+ OutputDebugStringF("NotifyAddressBookChanged %s %s isMine=%i status=%i\n", CBitcoinAddress(address).ToString().c_str(), label.c_str(), isMine, status);
QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection,
- Q_ARG(QString, QString::fromStdString(address)),
+ Q_ARG(QString, QString::fromStdString(CBitcoinAddress(address).ToString())),
Q_ARG(QString, QString::fromStdString(label)),
Q_ARG(bool, isMine),
Q_ARG(int, status));
View
9 src/rpcdump.cpp
@@ -5,6 +5,7 @@
#include "init.h" // for pwalletMain
#include "bitcoinrpc.h"
#include "ui_interface.h"
+#include "base58.h"
#include <boost/lexical_cast.hpp>
@@ -51,8 +52,7 @@ Value importprivkey(const Array& params, bool fHelp)
bool fCompressed;
CSecret secret = vchSecret.GetSecret(fCompressed);
key.SetSecret(secret, fCompressed);
- CBitcoinAddress vchAddress = CBitcoinAddress(key.GetPubKey());
-
+ CKeyID vchAddress = key.GetPubKey().GetID();
{
LOCK2(cs_main, pwalletMain->cs_wallet);
@@ -80,9 +80,12 @@ Value dumpprivkey(const Array& params, bool fHelp)
CBitcoinAddress address;
if (!address.SetString(strAddress))
throw JSONRPCError(-5, "Invalid Bitcoin address");
+ CKeyID keyID;
+ if (!address.GetKeyID(keyID))
+ throw JSONRPCError(-3, "Address does not refer to a key");
CSecret vchSecret;
bool fCompressed;
- if (!pwalletMain->GetSecret(address, vchSecret, fCompressed))
+ if (!pwalletMain->GetSecret(keyID, vchSecret, fCompressed))
throw JSONRPCError(-4,"Private key for address " + strAddress + " is not known");
return CBitcoinSecret(vchSecret, fCompressed).ToString();
}
View
117 src/script.cpp
@@ -1312,7 +1312,7 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi
}
-bool Sign1(const CBitcoinAddress& address, const CKeyStore& keystore, uint256 hash, int nHashType, CScript& scriptSigRet)
+bool Sign1(const CKeyID& address, const CKeyStore& keystore, uint256 hash, int nHashType, CScript& scriptSigRet)
{
CKey key;
if (!keystore.GetKey(address, key))
@@ -1334,9 +1334,8 @@ bool SignN(const vector<valtype>& multisigdata, const CKeyStore& keystore, uint2
for (vector<valtype>::const_iterator it = multisigdata.begin()+1; it != multisigdata.begin()+multisigdata.size()-1; it++)
{
const valtype& pubkey = *it;
- CBitcoinAddress address;
- address.SetPubKey(pubkey);
- if (Sign1(address, keystore, hash, nHashType, scriptSigRet))
+ CKeyID keyID = CPubKey(pubkey).GetID();
+ if (Sign1(keyID, keystore, hash, nHashType, scriptSigRet))
{
++nSigned;
if (nSigned == nRequired) break;
@@ -1360,22 +1359,22 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash
if (!Solver(scriptPubKey, whichTypeRet, vSolutions))
return false;
- CBitcoinAddress address;
+ CKeyID keyID;
switch (whichTypeRet)
{
case TX_NONSTANDARD:
return false;
case TX_PUBKEY:
- address.SetPubKey(vSolutions[0]);
- return Sign1(address, keystore, hash, nHashType, scriptSigRet);
+ keyID = CPubKey(vSolutions[0]).GetID();
+ return Sign1(keyID, keystore, hash, nHashType, scriptSigRet);
case TX_PUBKEYHASH:
- address.SetHash160(uint160(vSolutions[0]));
- if (!Sign1(address, keystore, hash, nHashType, scriptSigRet))
+ keyID = CKeyID(uint160(vSolutions[0]));
+ if (!Sign1(keyID, keystore, hash, nHashType, scriptSigRet))
return false;
else
{
CPubKey vch;
- keystore.GetPubKey(address, vch);
+ keystore.GetPubKey(keyID, vch);
scriptSigRet << vch;
}
return true;
@@ -1436,36 +1435,52 @@ unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore)
unsigned int nResult = 0;
BOOST_FOREACH(const valtype& pubkey, pubkeys)
{
- CBitcoinAddress address;
- address.SetPubKey(pubkey);
- if (keystore.HaveKey(address))
+ CKeyID keyID = CPubKey(pubkey).GetID();
+ if (keystore.HaveKey(keyID))
++nResult;
}
return nResult;
}
+
+class CKeyStoreIsMineVisitor : public boost::static_visitor<bool>
+{
+private:
+ const CKeyStore *keystore;
+public:
+ CKeyStoreIsMineVisitor(const CKeyStore *keystoreIn) : keystore(keystoreIn) { }
+ bool operator()(const CNoDestination &dest) const { return false; }
+ bool operator()(const CKeyID &keyID) const { return keystore->HaveKey(keyID); }
+ bool operator()(const CScriptID &scriptID) const { return keystore->HaveCScript(scriptID); }
+};
+
+bool IsMine(const CKeyStore &keystore, const CTxDestination &dest)
+{
+ return boost::apply_visitor(CKeyStoreIsMineVisitor(&keystore), dest);
+}
+
bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
{
vector<valtype> vSolutions;
txnouttype whichType;
if (!Solver(scriptPubKey, whichType, vSolutions))
return false;
- CBitcoinAddress address;
+ CKeyID keyID;
switch (whichType)
{
case TX_NONSTANDARD:
return false;
case TX_PUBKEY:
- address.SetPubKey(vSolutions[0]);
- return keystore.HaveKey(address);
+ keyID = CPubKey(vSolutions[0]).GetID();
+ return keystore.HaveKey(keyID);
case TX_PUBKEYHASH:
- address.SetHash160(uint160(vSolutions[0]));
- return keystore.HaveKey(address);
+ keyID = CKeyID(uint160(vSolutions[0]));
+ return keystore.HaveKey(keyID);
case TX_SCRIPTHASH:
{
CScript subscript;
- if (!keystore.GetCScript(uint160(vSolutions[0]), subscript))
+ if (!keystore.GetCScript(CScriptID(uint160(vSolutions[0])), subscript))
return false;
return IsMine(keystore, subscript);
}
@@ -1483,7 +1498,7 @@ bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
return false;
}
-bool ExtractAddress(const CScript& scriptPubKey, CBitcoinAddress& addressRet)
+bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
{
vector<valtype> vSolutions;
txnouttype whichType;
@@ -1492,24 +1507,24 @@ bool ExtractAddress(const CScript& scriptPubKey, CBitcoinAddress& addressRet)
if (whichType == TX_PUBKEY)
{
- addressRet.SetPubKey(vSolutions[0]);
+ addressRet = CPubKey(vSolutions[0]).GetID();
return true;
}
else if (whichType == TX_PUBKEYHASH)
{
- addressRet.SetHash160(uint160(vSolutions[0]));
+ addressRet = CKeyID(uint160(vSolutions[0]));
return true;
}
else if (whichType == TX_SCRIPTHASH)
{
- addressRet.SetScriptHash160(uint160(vSolutions[0]));
+ addressRet = CScriptID(uint160(vSolutions[0]));
return true;
}
// Multisig txns have more than one address...
return false;
}
-bool ExtractAddresses(const CScript& scriptPubKey, txnouttype& typeRet, vector<CBitcoinAddress>& addressRet, int& nRequiredRet)
+bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vector<CTxDestination>& addressRet, int& nRequiredRet)
{
addressRet.clear();
typeRet = TX_NONSTANDARD;
@@ -1522,21 +1537,16 @@ bool ExtractAddresses(const CScript& scriptPubKey, txnouttype& typeRet, vector<C
nRequiredRet = vSolutions.front()[0];
for (unsigned int i = 1; i < vSolutions.size()-1; i++)
{
- CBitcoinAddress address;
- address.SetPubKey(vSolutions[i]);
+ CTxDestination address = CPubKey(vSolutions[i]).GetID();
addressRet.push_back(address);
}
}
else
{
nRequiredRet = 1;
- CBitcoinAddress address;
- if (typeRet == TX_PUBKEYHASH)
- address.SetHash160(uint160(vSolutions.front()));
- else if (typeRet == TX_SCRIPTHASH)
- address.SetScriptHash160(uint160(vSolutions.front()));
- else if (typeRet == TX_PUBKEY)
- address.SetPubKey(vSolutions.front());
+ CTxDestination address;
+ if (!ExtractDestination(scriptPubKey, address))
+ return false;
addressRet.push_back(address);
}
@@ -1694,13 +1704,34 @@ bool CScript::IsPayToScriptHash() const
this->at(22) == OP_EQUAL);
}
-void CScript::SetBitcoinAddress(const CBitcoinAddress& address)
+class CScriptVisitor : public boost::static_visitor<bool>
{
- this->clear();
- if (address.IsScript())
- *this << OP_HASH160 << address.GetHash160() << OP_EQUAL;
- else
- *this << OP_DUP << OP_HASH160 << address.GetHash160() << OP_EQUALVERIFY << OP_CHECKSIG;
+private:
+ CScript *script;
+public:
+ CScriptVisitor(CScript *scriptin) { script = scriptin; }
+
+ bool operator()(const CNoDestination &dest) const {
+ script->clear();
+ return false;
+ }
+
+ bool operator()(const CKeyID &keyID) const {
+ script->clear();
+ *script << OP_DUP << OP_HASH160 << keyID << OP_EQUALVERIFY << OP_CHECKSIG;
+ return true;
+ }
+
+ bool operator()(const CScriptID &scriptID) const {
+ script->clear();
+ *script << OP_HASH160 << scriptID << OP_EQUAL;
+ return true;
+ }
+};
+
+void CScript::SetDestination(const CTxDestination& dest)
+{
+ boost::apply_visitor(CScriptVisitor(this), dest);
}
void CScript::SetMultisig(int nRequired, const std::vector<CKey>& keys)
@@ -1712,11 +1743,3 @@ void CScript::SetMultisig(int nRequired, const std::vector<CKey>& keys)
*this << key.GetPubKey();
*this << EncodeOP_N(keys.size()) << OP_CHECKMULTISIG;
}
-
-void CScript::SetPayToScriptHash(const CScript& subscript)
-{
- assert(!subscript.empty());
- uint160 subscriptHash = Hash160(subscript);
- this->clear();
- *this << OP_HASH160 << subscriptHash << OP_EQUAL;
-}
View
38 src/script.h
@@ -5,15 +5,16 @@
#ifndef H_BITCOIN_SCRIPT
#define H_BITCOIN_SCRIPT
-#include "base58.h"
-
#include <string>
#include <vector>
#include <boost/foreach.hpp>
+#include <boost/variant.hpp>
+
+#include "keystore.h"
+#include "bignum.h"
class CTransaction;
-class CKeyStore;
/** Signature hash types/flags */
enum
@@ -35,6 +36,20 @@ enum txnouttype
TX_MULTISIG,
};
+class CNoDestination {
+public:
+ friend bool operator==(const CNoDestination &a, const CNoDestination &b) { return true; }
+ friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; }
+};
+
+/** A txout script template with a specific destination. It is either:
+ * * CNoDestination: no destination set
+ * * CKeyID: TX_PUBKEYHASH destination
+ * * CScriptID: TX_SCRIPTHASH destination
+ * A CTxDestination is the internal data type encoded in a CBitcoinAddress
+ */
+typedef boost::variant<CNoDestination, CKeyID, CScriptID> CTxDestination;
+
const char* GetTxnOutputType(txnouttype t);
/** Script opcodes */
@@ -521,13 +536,8 @@ class CScript : public std::vector<unsigned char>
}
- void SetBitcoinAddress(const CBitcoinAddress& address);
- void SetBitcoinAddress(const std::vector<unsigned char>& vchPubKey)
- {
- SetBitcoinAddress(CBitcoinAddress(vchPubKey));
- }
+ void SetDestination(const CTxDestination& address);
void SetMultisig(int nRequired, const std::vector<CKey>& keys);
- void SetPayToScriptHash(const CScript& subscript);
void PrintHex() const
@@ -562,6 +572,11 @@ class CScript : public std::vector<unsigned char>
{
printf("%s\n", ToString().c_str());
}
+
+ CScriptID GetID() const
+ {
+ return CScriptID(Hash160(*this));
+ }
};
@@ -573,8 +588,9 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::v
int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions);
bool IsStandard(const CScript& scriptPubKey);
bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey);
-bool ExtractAddress(const CScript& scriptPubKey, CBitcoinAddress& addressRet);
-bool ExtractAddresses(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CBitcoinAddress>& addressRet, int& nRequiredRet);
+bool IsMine(const CKeyStore& keystore, const CTxDestination &dest);
+bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet);
+bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);
bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL);
bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, bool fValidatePayToScriptHash, int nHashType);
View
10 src/test/DoS_tests.cpp
@@ -161,7 +161,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
tx.vin[0].scriptSig << OP_1;
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
- tx.vout[0].scriptPubKey.SetBitcoinAddress(key.GetPubKey());
+ tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
CDataStream ds(SER_DISK, CLIENT_VERSION);
ds << tx;
@@ -179,7 +179,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
tx.vin[0].prevout.hash = txPrev.GetHash();
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
- tx.vout[0].scriptPubKey.SetBitcoinAddress(key.GetPubKey());
+ tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
SignSignature(keystore, txPrev, tx, 0);
CDataStream ds(SER_DISK, CLIENT_VERSION);
@@ -195,7 +195,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
CTransaction tx;
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
- tx.vout[0].scriptPubKey.SetBitcoinAddress(key.GetPubKey());
+ tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
tx.vin.resize(500);
for (unsigned int j = 0; j < tx.vin.size(); j++)
{
@@ -244,7 +244,7 @@ BOOST_AUTO_TEST_CASE(DoS_checkSig)
tx.vin[0].scriptSig << OP_1;
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
- tx.vout[0].scriptPubKey.SetBitcoinAddress(key.GetPubKey());
+ tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
CDataStream ds(SER_DISK, CLIENT_VERSION);
ds << tx;
@@ -255,7 +255,7 @@ BOOST_AUTO_TEST_CASE(DoS_checkSig)
CTransaction tx;
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
- tx.vout[0].scriptPubKey.SetBitcoinAddress(key.GetPubKey());
+ tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
tx.vin.resize(NPREV);
for (unsigned int j = 0; j < tx.vin.size(); j++)
{
View
4 src/test/base58_tests.cpp
@@ -1,8 +1,6 @@
#include <boost/test/unit_test.hpp>
-#include "main.h"
-#include "wallet.h"
-#include "util.h"
+#include "base58.h"
BOOST_AUTO_TEST_SUITE(base58_tests)
View
27 src/test/key_tests.cpp
@@ -10,11 +10,18 @@
using namespace std;
-static const string strSecret1 ("5HxWvvfubhXpYYpS3tJkw6fq9jE9j18THftkZjHHfmFiWtmAbrj");
-static const string strSecret2 ("5KC4ejrDjv152FGwP386VD1i2NYc5KkfSMyv1nGy1VGDxGHqVY3");
-static const string strSecret1C("Kwr371tjA9u2rFSMZjTNun2PXXP3WPZu2afRHTcta6KxEUdm1vEw");
-static const string strSecret2C("L3Hq7a8FEQwJkW1M2GNKDW28546Vp5miewcCzSqUD9kCAXrJdS3g");
-static const string strAddress1("1HV9Lc3sNHZxwj4Zk6fB38tEmBryq2cBiF");
+static const string strSecret1 ("5HxWvvfubhXpYYpS3tJkw6fq9jE9j18THftkZjHHfmFiWtmAbrj");
+static const string strSecret2 ("5KC4ejrDjv152FGwP386VD1i2NYc5KkfSMyv1nGy1VGDxGHqVY3");
+static const string strSecret1C ("Kwr371tjA9u2rFSMZjTNun2PXXP3WPZu2afRHTcta6KxEUdm1vEw");
+static const string strSecret2C ("L3Hq7a8FEQwJkW1M2GNKDW28546Vp5miewcCzSqUD9kCAXrJdS3g");
+static const CBitcoinAddress addr1 ("1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ");
+static const CBitcoinAddress addr2 ("1F5y5E5FMc5YzdJtB9hLaUe43GDxEKXENJ");
+static const CBitcoinAddress addr1C("1NoJrossxPBKfCHuJXT4HadJrXRE9Fxiqs");
+static const CBitcoinAddress addr2C("1CRj2HyM1CXWzHAXLQtiGLyggNT9WQqsDs");
+
+
+static const string strAddressBad("1HV9Lc3sNHZxwj4Zk6fB38tEmBryq2cBiF");
+
#ifdef KEY_TESTS_DUMPINFO
void dumpKeyInfo(uint256 privkey)
@@ -53,7 +60,7 @@ BOOST_AUTO_TEST_CASE(key_test1)
BOOST_CHECK( bsecret2.SetString (strSecret2));
BOOST_CHECK( bsecret1C.SetString(strSecret1C));
BOOST_CHECK( bsecret2C.SetString(strSecret2C));
- BOOST_CHECK(!baddress1.SetString(strAddress1));
+ BOOST_CHECK(!baddress1.SetString(strAddressBad));
bool fCompressed;
CSecret secret1 = bsecret1.GetSecret (fCompressed);
@@ -74,10 +81,10 @@ BOOST_AUTO_TEST_CASE(key_test1)
key1C.SetSecret(secret1, true);
key2C.SetSecret(secret2, true);
- BOOST_CHECK(CBitcoinAddress(key1.GetPubKey ()).ToString() == "1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ");
- BOOST_CHECK(CBitcoinAddress(key2.GetPubKey ()).ToString() == "1F5y5E5FMc5YzdJtB9hLaUe43GDxEKXENJ");
- BOOST_CHECK(CBitcoinAddress(key1C.GetPubKey()).ToString() == "1NoJrossxPBKfCHuJXT4HadJrXRE9Fxiqs");
- BOOST_CHECK(CBitcoinAddress(key2C.GetPubKey()).ToString() == "1CRj2HyM1CXWzHAXLQtiGLyggNT9WQqsDs");
+ BOOST_CHECK(addr1.Get() == CTxDestination(key1.GetPubKey().GetID()));
+ BOOST_CHECK(addr2.Get() == CTxDestination(key2.GetPubKey().GetID()));
+ BOOST_CHECK(addr1C.Get() == CTxDestination(key1C.GetPubKey().GetID()));
+ BOOST_CHECK(addr2C.Get() == CTxDestination(key2C.GetPubKey().GetID()));
for (int n=0; n<16; n++)
{
View
34 src/test/multisig_tests.cpp
@@ -175,12 +175,12 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
//
CBasicKeyStore keystore, emptykeystore, partialkeystore;
CKey key[3];
- CBitcoinAddress keyaddr[3];
+ CTxDestination keyaddr[3];
for (int i = 0; i < 3; i++)
{
key[i].MakeNewKey(true);
keystore.AddKey(key[i]);
- keyaddr[i].SetPubKey(key[i].GetPubKey());
+ keyaddr[i] = key[i].GetPubKey().GetID();
}
partialkeystore.AddKey(key[0]);
@@ -191,8 +191,8 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
s << key[0].GetPubKey() << OP_CHECKSIG;
BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK(solutions.size() == 1);
- CBitcoinAddress addr;
- BOOST_CHECK(ExtractAddress(s, addr));
+ CTxDestination addr;
+ BOOST_CHECK(ExtractDestination(s, addr));
BOOST_CHECK(addr == keyaddr[0]);
BOOST_CHECK(IsMine(keystore, s));
BOOST_CHECK(!IsMine(emptykeystore, s));
@@ -201,11 +201,11 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
vector<valtype> solutions;
txnouttype whichType;
CScript s;
- s << OP_DUP << OP_HASH160 << Hash160(key[0].GetPubKey().Raw()) << OP_EQUALVERIFY << OP_CHECKSIG;
+ s << OP_DUP << OP_HASH160 << key[0].GetPubKey().GetID() << OP_EQUALVERIFY << OP_CHECKSIG;
BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK(solutions.size() == 1);
- CBitcoinAddress addr;
- BOOST_CHECK(ExtractAddress(s, addr));
+ CTxDestination addr;
+ BOOST_CHECK(ExtractDestination(s, addr));
BOOST_CHECK(addr == keyaddr[0]);
BOOST_CHECK(IsMine(keystore, s));
BOOST_CHECK(!IsMine(emptykeystore, s));
@@ -214,11 +214,11 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
vector<valtype> solutions;
txnouttype whichType;
CScript s;
- s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey().Raw() << OP_2 << OP_CHECKMULTISIG;
+ s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK_EQUAL(solutions.size(), 4);
- CBitcoinAddress addr;
- BOOST_CHECK(!ExtractAddress(s, addr));
+ CTxDestination addr;
+ BOOST_CHECK(!ExtractDestination(s, addr));
BOOST_CHECK(IsMine(keystore, s));
BOOST_CHECK(!IsMine(emptykeystore, s));
BOOST_CHECK(!IsMine(partialkeystore, s));
@@ -227,12 +227,12 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
vector<valtype> solutions;
txnouttype whichType;
CScript s;
- s << OP_1 << key[0].GetPubKey().Raw() << key[1].GetPubKey().Raw() << OP_2 << OP_CHECKMULTISIG;
+ s << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK_EQUAL(solutions.size(), 4);
- vector<CBitcoinAddress> addrs;
+ vector<CTxDestination> addrs;
int nRequired;
- BOOST_CHECK(ExtractAddresses(s, whichType, addrs, nRequired));
+ BOOST_CHECK(ExtractDestinations(s, whichType, addrs, nRequired));
BOOST_CHECK(addrs[0] == keyaddr[0]);
BOOST_CHECK(addrs[1] == keyaddr[1]);
BOOST_CHECK(nRequired = 1);
@@ -244,7 +244,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
vector<valtype> solutions;
txnouttype whichType;
CScript s;
- s << OP_2 << key[0].GetPubKey().Raw() << key[1].GetPubKey().Raw() << key[2].GetPubKey().Raw() << OP_3 << OP_CHECKMULTISIG;
+ s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG;
BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK(solutions.size() == 5);
}
@@ -262,13 +262,13 @@ BOOST_AUTO_TEST_CASE(multisig_Sign)
}
CScript a_and_b;
- a_and_b << OP_2 << key[0].GetPubKey().Raw() << key[1].GetPubKey().Raw() << OP_2 << OP_CHECKMULTISIG;
+ a_and_b << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
CScript a_or_b;
- a_or_b << OP_1 << key[0].GetPubKey().Raw() << key[1].GetPubKey().Raw() << OP_2 << OP_CHECKMULTISIG;
+ a_or_b << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
CScript escrow;
- escrow << OP_2 << key[0].GetPubKey().Raw() << key[1].GetPubKey().Raw() << key[2].GetPubKey().Raw() << OP_3 << OP_CHECKMULTISIG;
+ escrow << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG;
CTransaction txFrom; // Funding transaction
txFrom.vout.resize(3);
View
26 src/test/script_P2SH_tests.cpp
@@ -65,14 +65,14 @@ BOOST_AUTO_TEST_CASE(sign)
// different keys, straight/P2SH, pubkey/pubkeyhash
CScript standardScripts[4];
standardScripts[0] << key[0].GetPubKey() << OP_CHECKSIG;
- standardScripts[1].SetBitcoinAddress(key[1].GetPubKey());
+ standardScripts[1].SetDestination(key[1].GetPubKey().GetID());
standardScripts[2] << key[1].GetPubKey() << OP_CHECKSIG;
- standardScripts[3].SetBitcoinAddress(key[2].GetPubKey());
+ standardScripts[3].SetDestination(key[2].GetPubKey().GetID());
CScript evalScripts[4];
for (int i = 0; i < 4; i++)
{
keystore.AddCScript(standardScripts[i]);
- evalScripts[i].SetPayToScriptHash(standardScripts[i]);
+ evalScripts[i].SetDestination(standardScripts[i].GetID());
}
CTransaction txFrom; // Funding transaction:
@@ -122,7 +122,7 @@ BOOST_AUTO_TEST_CASE(norecurse)
invalidAsScript << OP_INVALIDOPCODE << OP_INVALIDOPCODE;
CScript p2sh;
- p2sh.SetPayToScriptHash(invalidAsScript);
+ p2sh.SetDestination(invalidAsScript.GetID());
CScript scriptSig;
scriptSig << Serialize(invalidAsScript);
@@ -133,7 +133,7 @@ BOOST_AUTO_TEST_CASE(norecurse)
// Try to recurse, and verification should succeed because
// the inner HASH160 <> EQUAL should only check the hash:
CScript p2sh2;
- p2sh2.SetPayToScriptHash(p2sh);
+ p2sh2.SetDestination(p2sh.GetID());
CScript scriptSig2;
scriptSig2 << Serialize(invalidAsScript) << Serialize(p2sh);
@@ -154,15 +154,15 @@ BOOST_AUTO_TEST_CASE(set)
}
CScript inner[4];
- inner[0].SetBitcoinAddress(key[0].GetPubKey());
+ inner[0].SetDestination(key[0].GetPubKey().GetID());
inner[1].SetMultisig(2, std::vector<CKey>(keys.begin(), keys.begin()+2));
inner[2].SetMultisig(1, std::vector<CKey>(keys.begin(), keys.begin()+2));
inner[3].SetMultisig(2, std::vector<CKey>(keys.begin(), keys.begin()+3));
CScript outer[4];
for (int i = 0; i < 4; i++)
{
- outer[i].SetPayToScriptHash(inner[i]);
+ outer[i].SetDestination(inner[i].GetID());
keystore.AddCScript(inner[i]);
}
@@ -232,7 +232,7 @@ BOOST_AUTO_TEST_CASE(switchover)
scriptSig << Serialize(notValid);
CScript fund;
- fund.SetPayToScriptHash(notValid);
+ fund.SetDestination(notValid.GetID());
// Validation should succeed under old rules (hash is correct):
@@ -258,9 +258,9 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txFrom.vout.resize(6);
// First three are standard:
- CScript pay1; pay1.SetBitcoinAddress(key[0].GetPubKey());
+ CScript pay1; pay1.SetDestination(key[0].GetPubKey().GetID());
keystore.AddCScript(pay1);
- CScript payScriptHash1; payScriptHash1.SetPayToScriptHash(pay1);
+ CScript payScriptHash1; payScriptHash1.SetDestination(pay1.GetID());
CScript pay1of3; pay1of3.SetMultisig(1, keys);
txFrom.vout[0].scriptPubKey = payScriptHash1;
@@ -278,13 +278,13 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
for (int i = 0; i < 11; i++)
oneOfEleven << key[0].GetPubKey();
oneOfEleven << OP_11 << OP_CHECKMULTISIG;
- txFrom.vout[5].scriptPubKey.SetPayToScriptHash(oneOfEleven);
+ txFrom.vout[5].scriptPubKey.SetDestination(oneOfEleven.GetID());
mapInputs[txFrom.GetHash()] = make_pair(CTxIndex(), txFrom);
CTransaction txTo;
txTo.vout.resize(1);
- txTo.vout[0].scriptPubKey.SetBitcoinAddress(key[1].GetPubKey());
+ txTo.vout[0].scriptPubKey.SetDestination(key[1].GetPubKey().GetID());
txTo.vin.resize(3);
txTo.vin[0].prevout.n = 0;
@@ -311,7 +311,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
CTransaction txToNonStd;
txToNonStd.vout.resize(1);
- txToNonStd.vout[0].scriptPubKey.SetBitcoinAddress(key[1].GetPubKey());
+ txToNonStd.vout[0].scriptPubKey.SetDestination(key[1].GetPubKey().GetID());
txToNonStd.vin.resize(2);
txToNonStd.vin[0].prevout.n = 4;
txToNonStd.vin[0].prevout.hash = txFrom.GetHash();
View
4 src/test/sigopcount_tests.cpp
@@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount)
BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 21);
CScript p2sh;
- p2sh.SetPayToScriptHash(s1);
+ p2sh.SetDestination(s1.GetID());
CScript scriptSig;
scriptSig << OP_0 << Serialize(s1);
BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig), 3);
@@ -49,7 +49,7 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount)
BOOST_CHECK_EQUAL(s2.GetSigOpCount(true), 3);
BOOST_CHECK_EQUAL(s2.GetSigOpCount(false), 20);
- p2sh.SetPayToScriptHash(s2);
+ p2sh.SetDestination(s2.GetID());
BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(true), 0);
BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(false), 0);
CScript scriptSig2;
View
4 src/test/transaction_tests.cpp
@@ -52,9 +52,9 @@ SetupDummyInputs(CBasicKeyStore& keystoreRet, MapPrevTx& inputsRet)
dummyTransactions[1].vout.resize(2);
dummyTransactions[1].vout[0].nValue = 21*CENT;
- dummyTransactions[1].vout[0].scriptPubKey.SetBitcoinAddress(key[2].GetPubKey());
+ dummyTransactions[1].vout[0].scriptPubKey.SetDestination(key[2].