Merge pull request #1357 from sipa/keyid
Refactor: split CKeyID/CScriptID/CTxDestination from CBitcoinAddress
This commit is contained in:
commit
a52c7a1b65
28 changed files with 579 additions and 400 deletions
101
src/base58.h
101
src/base58.h
|
@ -19,6 +19,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "bignum.h"
|
#include "bignum.h"
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
|
#include "script.h"
|
||||||
|
|
||||||
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
@ -258,6 +259,18 @@ public:
|
||||||
* Script-hash-addresses have version 5 (or 196 testnet).
|
* Script-hash-addresses have version 5 (or 196 testnet).
|
||||||
* The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
|
* 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
|
class CBitcoinAddress : public CBase58Data
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -269,21 +282,19 @@ public:
|
||||||
SCRIPT_ADDRESS_TEST = 196,
|
SCRIPT_ADDRESS_TEST = 196,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool SetHash160(const uint160& hash160)
|
bool Set(const CKeyID &id) {
|
||||||
{
|
SetData(fTestNet ? PUBKEY_ADDRESS_TEST : PUBKEY_ADDRESS, &id, 20);
|
||||||
SetData(fTestNet ? PUBKEY_ADDRESS_TEST : PUBKEY_ADDRESS, &hash160, 20);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPubKey(const std::vector<unsigned char>& vchPubKey)
|
bool Set(const CScriptID &id) {
|
||||||
{
|
SetData(fTestNet ? SCRIPT_ADDRESS_TEST : SCRIPT_ADDRESS, &id, 20);
|
||||||
SetHash160(Hash160(vchPubKey));
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetScriptHash160(const uint160& hash160)
|
bool Set(const CTxDestination &dest)
|
||||||
{
|
{
|
||||||
SetData(fTestNet ? SCRIPT_ADDRESS_TEST : SCRIPT_ADDRESS, &hash160, 20);
|
return boost::apply_visitor(CBitcoinAddressVisitor(this), dest);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsValid() const
|
bool IsValid() const
|
||||||
|
@ -315,27 +326,14 @@ public:
|
||||||
}
|
}
|
||||||
return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize;
|
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()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CBitcoinAddress(uint160 hash160In)
|
CBitcoinAddress(const CTxDestination &dest)
|
||||||
{
|
{
|
||||||
SetHash160(hash160In);
|
Set(dest);
|
||||||
}
|
|
||||||
|
|
||||||
CBitcoinAddress(const std::vector<unsigned char>& vchPubKey)
|
|
||||||
{
|
|
||||||
SetPubKey(vchPubKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CBitcoinAddress(const std::string& strAddress)
|
CBitcoinAddress(const std::string& strAddress)
|
||||||
|
@ -348,15 +346,58 @@ public:
|
||||||
SetString(pszAddress);
|
SetString(pszAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint160 GetHash160() const
|
CTxDestination Get() const {
|
||||||
{
|
if (!IsValid())
|
||||||
assert(vchData.size() == 20);
|
return CNoDestination();
|
||||||
uint160 hash160;
|
switch (nVersion) {
|
||||||
memcpy(&hash160, &vchData[0], 20);
|
case PUBKEY_ADDRESS:
|
||||||
return hash160;
|
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 */
|
/** A base58-encoded secret key */
|
||||||
class CBitcoinSecret : public CBase58Data
|
class CBitcoinSecret : public CBase58Data
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
|
#include "base58.h"
|
||||||
#include "bitcoinrpc.h"
|
#include "bitcoinrpc.h"
|
||||||
|
|
||||||
#undef printf
|
#undef printf
|
||||||
|
@ -184,10 +185,10 @@ ScriptSigToJSON(const CTxIn& txin, Object& out)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
txnouttype type;
|
txnouttype type;
|
||||||
vector<CBitcoinAddress> addresses;
|
vector<CTxDestination> addresses;
|
||||||
int nRequired;
|
int nRequired;
|
||||||
|
|
||||||
if (!ExtractAddresses(txprev.vout[txin.prevout.n].scriptPubKey, type,
|
if (!ExtractDestinations(txprev.vout[txin.prevout.n].scriptPubKey, type,
|
||||||
addresses, nRequired))
|
addresses, nRequired))
|
||||||
{
|
{
|
||||||
out.push_back(Pair("type", GetTxnOutputType(TX_NONSTANDARD)));
|
out.push_back(Pair("type", GetTxnOutputType(TX_NONSTANDARD)));
|
||||||
|
@ -202,8 +203,8 @@ ScriptSigToJSON(const CTxIn& txin, Object& out)
|
||||||
}
|
}
|
||||||
|
|
||||||
Array a;
|
Array a;
|
||||||
BOOST_FOREACH(const CBitcoinAddress& addr, addresses)
|
BOOST_FOREACH(const CTxDestination& addr, addresses)
|
||||||
a.push_back(addr.ToString());
|
a.push_back(CBitcoinAddress(addr).ToString());
|
||||||
out.push_back(Pair("addresses", a));
|
out.push_back(Pair("addresses", a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,13 +212,13 @@ void
|
||||||
ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out)
|
ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out)
|
||||||
{
|
{
|
||||||
txnouttype type;
|
txnouttype type;
|
||||||
vector<CBitcoinAddress> addresses;
|
vector<CTxDestination> addresses;
|
||||||
int nRequired;
|
int nRequired;
|
||||||
|
|
||||||
out.push_back(Pair("asm", scriptPubKey.ToString()));
|
out.push_back(Pair("asm", scriptPubKey.ToString()));
|
||||||
out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
|
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)));
|
out.push_back(Pair("type", GetTxnOutputType(TX_NONSTANDARD)));
|
||||||
return;
|
return;
|
||||||
|
@ -227,8 +228,8 @@ ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out)
|
||||||
out.push_back(Pair("type", GetTxnOutputType(type)));
|
out.push_back(Pair("type", GetTxnOutputType(type)));
|
||||||
|
|
||||||
Array a;
|
Array a;
|
||||||
BOOST_FOREACH(const CBitcoinAddress& addr, addresses)
|
BOOST_FOREACH(const CTxDestination& addr, addresses)
|
||||||
a.push_back(addr.ToString());
|
a.push_back(CBitcoinAddress(addr).ToString());
|
||||||
out.push_back(Pair("addresses", a));
|
out.push_back(Pair("addresses", a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,14 +591,14 @@ Value getnewaddress(const Array& params, bool fHelp)
|
||||||
pwalletMain->TopUpKeyPool();
|
pwalletMain->TopUpKeyPool();
|
||||||
|
|
||||||
// Generate a new key that is added to wallet
|
// Generate a new key that is added to wallet
|
||||||
std::vector<unsigned char> newKey;
|
CPubKey newKey;
|
||||||
if (!pwalletMain->GetKeyFromPool(newKey, false))
|
if (!pwalletMain->GetKeyFromPool(newKey, false))
|
||||||
throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -611,12 +612,12 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
|
||||||
bool bKeyUsed = false;
|
bool bKeyUsed = false;
|
||||||
|
|
||||||
// Check if the current key has been used
|
// Check if the current key has been used
|
||||||
if (!account.vchPubKey.empty())
|
if (account.vchPubKey.IsValid())
|
||||||
{
|
{
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey;
|
||||||
scriptPubKey.SetBitcoinAddress(account.vchPubKey);
|
scriptPubKey.SetDestination(account.vchPubKey.GetID());
|
||||||
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
|
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
|
||||||
it != pwalletMain->mapWallet.end() && !account.vchPubKey.empty();
|
it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid();
|
||||||
++it)
|
++it)
|
||||||
{
|
{
|
||||||
const CWalletTx& wtx = (*it).second;
|
const CWalletTx& wtx = (*it).second;
|
||||||
|
@ -627,16 +628,16 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a new key
|
// Generate a new key
|
||||||
if (account.vchPubKey.empty() || bForceNew || bKeyUsed)
|
if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed)
|
||||||
{
|
{
|
||||||
if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
|
if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
|
||||||
throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
|
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);
|
walletdb.WriteAccount(strAccount, account);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CBitcoinAddress(account.vchPubKey);
|
return CBitcoinAddress(account.vchPubKey.GetID());
|
||||||
}
|
}
|
||||||
|
|
||||||
Value getaccountaddress(const Array& params, bool fHelp)
|
Value getaccountaddress(const Array& params, bool fHelp)
|
||||||
|
@ -675,14 +676,14 @@ Value setaccount(const Array& params, bool fHelp)
|
||||||
strAccount = AccountFromValue(params[1]);
|
strAccount = AccountFromValue(params[1]);
|
||||||
|
|
||||||
// Detect when changing the account of an address that is the 'unused current key' of another account:
|
// 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))
|
if (address == GetAccountAddress(strOldAccount))
|
||||||
GetAccountAddress(strOldAccount, true);
|
GetAccountAddress(strOldAccount, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pwalletMain->SetAddressBookName(address, strAccount);
|
pwalletMain->SetAddressBookName(address.Get(), strAccount);
|
||||||
|
|
||||||
return Value::null;
|
return Value::null;
|
||||||
}
|
}
|
||||||
|
@ -700,7 +701,7 @@ Value getaccount(const Array& params, bool fHelp)
|
||||||
throw JSONRPCError(-5, "Invalid Bitcoin address");
|
throw JSONRPCError(-5, "Invalid Bitcoin address");
|
||||||
|
|
||||||
string strAccount;
|
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())
|
if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty())
|
||||||
strAccount = (*mi).second;
|
strAccount = (*mi).second;
|
||||||
return strAccount;
|
return strAccount;
|
||||||
|
@ -769,7 +770,7 @@ Value sendtoaddress(const Array& params, bool fHelp)
|
||||||
if (pwalletMain->IsLocked())
|
if (pwalletMain->IsLocked())
|
||||||
throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
|
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 != "")
|
if (strError != "")
|
||||||
throw JSONRPCError(-4, strError);
|
throw JSONRPCError(-4, strError);
|
||||||
|
|
||||||
|
@ -792,8 +793,12 @@ Value signmessage(const Array& params, bool fHelp)
|
||||||
if (!addr.IsValid())
|
if (!addr.IsValid())
|
||||||
throw JSONRPCError(-3, "Invalid address");
|
throw JSONRPCError(-3, "Invalid address");
|
||||||
|
|
||||||
|
CKeyID keyID;
|
||||||
|
if (!addr.GetKeyID(keyID))
|
||||||
|
throw JSONRPCError(-3, "Address does not refer to key");
|
||||||
|
|
||||||
CKey key;
|
CKey key;
|
||||||
if (!pwalletMain->GetKey(addr, key))
|
if (!pwalletMain->GetKey(keyID, key))
|
||||||
throw JSONRPCError(-4, "Private key not available");
|
throw JSONRPCError(-4, "Private key not available");
|
||||||
|
|
||||||
CDataStream ss(SER_GETHASH, 0);
|
CDataStream ss(SER_GETHASH, 0);
|
||||||
|
@ -822,6 +827,10 @@ Value verifymessage(const Array& params, bool fHelp)
|
||||||
if (!addr.IsValid())
|
if (!addr.IsValid())
|
||||||
throw JSONRPCError(-3, "Invalid address");
|
throw JSONRPCError(-3, "Invalid address");
|
||||||
|
|
||||||
|
CKeyID keyID;
|
||||||
|
if (!addr.GetKeyID(keyID))
|
||||||
|
throw JSONRPCError(-3, "Address does not refer to key");
|
||||||
|
|
||||||
bool fInvalid = false;
|
bool fInvalid = false;
|
||||||
vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
|
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))
|
if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig))
|
||||||
return false;
|
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;
|
CScript scriptPubKey;
|
||||||
if (!address.IsValid())
|
if (!address.IsValid())
|
||||||
throw JSONRPCError(-5, "Invalid Bitcoin address");
|
throw JSONRPCError(-5, "Invalid Bitcoin address");
|
||||||
scriptPubKey.SetBitcoinAddress(address);
|
scriptPubKey.SetDestination(address.Get());
|
||||||
if (!IsMine(*pwalletMain,scriptPubKey))
|
if (!IsMine(*pwalletMain,scriptPubKey))
|
||||||
return (double)0.0;
|
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;
|
const string& strName = item.second;
|
||||||
if (strName == strAccount)
|
if (strName == strAccount)
|
||||||
setAddress.insert(address);
|
setAddress.insert(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Value getreceivedbyaccount(const Array& params, bool fHelp)
|
Value getreceivedbyaccount(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() < 1 || params.size() > 2)
|
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
|
// Get the set of pub keys assigned to account
|
||||||
string strAccount = AccountFromValue(params[0]);
|
string strAccount = AccountFromValue(params[0]);
|
||||||
set<CBitcoinAddress> setAddress;
|
set<CTxDestination> setAddress;
|
||||||
GetAccountAddresses(strAccount, setAddress);
|
GetAccountAddresses(strAccount, setAddress);
|
||||||
|
|
||||||
// Tally
|
// Tally
|
||||||
|
@ -918,8 +926,8 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
|
||||||
|
|
||||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||||
{
|
{
|
||||||
CBitcoinAddress address;
|
CTxDestination address;
|
||||||
if (ExtractAddress(txout.scriptPubKey, address) && pwalletMain->HaveKey(address) && setAddress.count(address))
|
if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address))
|
||||||
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
||||||
nAmount += txout.nValue;
|
nAmount += txout.nValue;
|
||||||
}
|
}
|
||||||
|
@ -990,15 +998,15 @@ Value getbalance(const Array& params, bool fHelp)
|
||||||
int64 allGeneratedImmature, allGeneratedMature, allFee;
|
int64 allGeneratedImmature, allGeneratedMature, allFee;
|
||||||
allGeneratedImmature = allGeneratedMature = allFee = 0;
|
allGeneratedImmature = allGeneratedMature = allFee = 0;
|
||||||
string strSentAccount;
|
string strSentAccount;
|
||||||
list<pair<CBitcoinAddress, int64> > listReceived;
|
list<pair<CTxDestination, int64> > listReceived;
|
||||||
list<pair<CBitcoinAddress, int64> > listSent;
|
list<pair<CTxDestination, int64> > listSent;
|
||||||
wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
|
wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
|
||||||
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
|
BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listReceived)
|
||||||
nBalance += r.second;
|
nBalance += r.second;
|
||||||
}
|
}
|
||||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listSent)
|
BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listSent)
|
||||||
nBalance -= r.second;
|
nBalance -= r.second;
|
||||||
nBalance -= allFee;
|
nBalance -= allFee;
|
||||||
nBalance += allGeneratedMature;
|
nBalance += allGeneratedMature;
|
||||||
|
@ -1094,7 +1102,7 @@ Value sendfrom(const Array& params, bool fHelp)
|
||||||
throw JSONRPCError(-6, "Account has insufficient funds");
|
throw JSONRPCError(-6, "Account has insufficient funds");
|
||||||
|
|
||||||
// Send
|
// Send
|
||||||
string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
|
string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
|
||||||
if (strError != "")
|
if (strError != "")
|
||||||
throw JSONRPCError(-4, strError);
|
throw JSONRPCError(-4, strError);
|
||||||
|
|
||||||
|
@ -1136,7 +1144,7 @@ Value sendmany(const Array& params, bool fHelp)
|
||||||
setAddress.insert(address);
|
setAddress.insert(address);
|
||||||
|
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey;
|
||||||
scriptPubKey.SetBitcoinAddress(address);
|
scriptPubKey.SetDestination(address.Get());
|
||||||
int64 nAmount = AmountFromValue(s.value_);
|
int64 nAmount = AmountFromValue(s.value_);
|
||||||
totalAmount += nAmount;
|
totalAmount += nAmount;
|
||||||
|
|
||||||
|
@ -1200,22 +1208,23 @@ Value addmultisigaddress(const Array& params, bool fHelp)
|
||||||
CBitcoinAddress address(ks);
|
CBitcoinAddress address(ks);
|
||||||
if (address.IsValid())
|
if (address.IsValid())
|
||||||
{
|
{
|
||||||
if (address.IsScript())
|
CKeyID keyID;
|
||||||
|
if (!address.GetKeyID(keyID))
|
||||||
throw runtime_error(
|
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()));
|
||||||
std::vector<unsigned char> vchPubKey;
|
CPubKey vchPubKey;
|
||||||
if (!pwalletMain->GetPubKey(address, vchPubKey))
|
if (!pwalletMain->GetPubKey(keyID, vchPubKey))
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
strprintf("no full public key for address %s",ks.c_str()));
|
strprintf("no full public key for address %s",ks.c_str()));
|
||||||
if (vchPubKey.empty() || !pubkeys[i].SetPubKey(vchPubKey))
|
if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey))
|
||||||
throw runtime_error(" Invalid public key: "+ks);
|
throw runtime_error(" Invalid public key: "+ks);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case 2: hex public key
|
// Case 2: hex public key
|
||||||
else if (IsHex(ks))
|
else if (IsHex(ks))
|
||||||
{
|
{
|
||||||
vector<unsigned char> vchPubKey = ParseHex(ks);
|
CPubKey vchPubKey(ParseHex(ks));
|
||||||
if (vchPubKey.empty() || !pubkeys[i].SetPubKey(vchPubKey))
|
if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey))
|
||||||
throw runtime_error(" Invalid public key: "+ks);
|
throw runtime_error(" Invalid public key: "+ks);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1227,16 +1236,11 @@ Value addmultisigaddress(const Array& params, bool fHelp)
|
||||||
// Construct using pay-to-script-hash:
|
// Construct using pay-to-script-hash:
|
||||||
CScript inner;
|
CScript inner;
|
||||||
inner.SetMultisig(nRequired, pubkeys);
|
inner.SetMultisig(nRequired, pubkeys);
|
||||||
|
CScriptID innerID = inner.GetID();
|
||||||
uint160 scriptHash = Hash160(inner);
|
|
||||||
CScript scriptPubKey;
|
|
||||||
scriptPubKey.SetPayToScriptHash(inner);
|
|
||||||
pwalletMain->AddCScript(inner);
|
pwalletMain->AddCScript(inner);
|
||||||
CBitcoinAddress address;
|
|
||||||
address.SetScriptHash160(scriptHash);
|
|
||||||
|
|
||||||
pwalletMain->SetAddressBookName(address, strAccount);
|
pwalletMain->SetAddressBookName(innerID, strAccount);
|
||||||
return address.ToString();
|
return CBitcoinAddress(innerID).ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1278,8 +1282,8 @@ Value ListReceived(const Array& params, bool fByAccounts)
|
||||||
|
|
||||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||||
{
|
{
|
||||||
CBitcoinAddress address;
|
CTxDestination address;
|
||||||
if (!ExtractAddress(txout.scriptPubKey, address) || !pwalletMain->HaveKey(address) || !address.IsValid())
|
if (!ExtractDestination(txout.scriptPubKey, address) || !IsMine(*pwalletMain, address))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
tallyitem& item = mapTally[address];
|
tallyitem& item = mapTally[address];
|
||||||
|
@ -1376,8 +1380,8 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
|
||||||
{
|
{
|
||||||
int64 nGeneratedImmature, nGeneratedMature, nFee;
|
int64 nGeneratedImmature, nGeneratedMature, nFee;
|
||||||
string strSentAccount;
|
string strSentAccount;
|
||||||
list<pair<CBitcoinAddress, int64> > listReceived;
|
list<pair<CTxDestination, int64> > listReceived;
|
||||||
list<pair<CBitcoinAddress, int64> > listSent;
|
list<pair<CTxDestination, int64> > listSent;
|
||||||
|
|
||||||
wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
|
wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
|
||||||
|
|
||||||
|
@ -1406,11 +1410,11 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
|
||||||
// Sent
|
// Sent
|
||||||
if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
|
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;
|
Object entry;
|
||||||
entry.push_back(Pair("account", strSentAccount));
|
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("category", "send"));
|
||||||
entry.push_back(Pair("amount", ValueFromAmount(-s.second)));
|
entry.push_back(Pair("amount", ValueFromAmount(-s.second)));
|
||||||
entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
|
entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
|
||||||
|
@ -1423,7 +1427,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
|
||||||
// Received
|
// Received
|
||||||
if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
|
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;
|
string account;
|
||||||
if (pwalletMain->mapAddressBook.count(r.first))
|
if (pwalletMain->mapAddressBook.count(r.first))
|
||||||
|
@ -1432,7 +1436,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
|
||||||
{
|
{
|
||||||
Object entry;
|
Object entry;
|
||||||
entry.push_back(Pair("account", account));
|
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("category", "receive"));
|
||||||
entry.push_back(Pair("amount", ValueFromAmount(r.second)));
|
entry.push_back(Pair("amount", ValueFromAmount(r.second)));
|
||||||
if (fLong)
|
if (fLong)
|
||||||
|
@ -1547,8 +1551,8 @@ Value listaccounts(const Array& params, bool fHelp)
|
||||||
nMinDepth = params[0].get_int();
|
nMinDepth = params[0].get_int();
|
||||||
|
|
||||||
map<string, int64> mapAccountBalances;
|
map<string, int64> mapAccountBalances;
|
||||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& entry, pwalletMain->mapAddressBook) {
|
BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& entry, pwalletMain->mapAddressBook) {
|
||||||
if (pwalletMain->HaveKey(entry.first)) // This address belongs to me
|
if (IsMine(*pwalletMain, entry.first)) // This address belongs to me
|
||||||
mapAccountBalances[entry.second] = 0;
|
mapAccountBalances[entry.second] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1557,16 +1561,16 @@ Value listaccounts(const Array& params, bool fHelp)
|
||||||
const CWalletTx& wtx = (*it).second;
|
const CWalletTx& wtx = (*it).second;
|
||||||
int64 nGeneratedImmature, nGeneratedMature, nFee;
|
int64 nGeneratedImmature, nGeneratedMature, nFee;
|
||||||
string strSentAccount;
|
string strSentAccount;
|
||||||
list<pair<CBitcoinAddress, int64> > listReceived;
|
list<pair<CTxDestination, int64> > listReceived;
|
||||||
list<pair<CBitcoinAddress, int64> > listSent;
|
list<pair<CTxDestination, int64> > listSent;
|
||||||
wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
|
wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
|
||||||
mapAccountBalances[strSentAccount] -= nFee;
|
mapAccountBalances[strSentAccount] -= nFee;
|
||||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
|
BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& s, listSent)
|
||||||
mapAccountBalances[strSentAccount] -= s.second;
|
mapAccountBalances[strSentAccount] -= s.second;
|
||||||
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
||||||
{
|
{
|
||||||
mapAccountBalances[""] += nGeneratedMature;
|
mapAccountBalances[""] += nGeneratedMature;
|
||||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
|
BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& r, listReceived)
|
||||||
if (pwalletMain->mapAddressBook.count(r.first))
|
if (pwalletMain->mapAddressBook.count(r.first))
|
||||||
mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
|
mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
|
||||||
else
|
else
|
||||||
|
@ -1932,6 +1936,40 @@ Value encryptwallet(const Array& params, bool fHelp)
|
||||||
return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet";
|
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)
|
Value validateaddress(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
|
@ -1947,42 +1985,17 @@ Value validateaddress(const Array& params, bool fHelp)
|
||||||
ret.push_back(Pair("isvalid", isValid));
|
ret.push_back(Pair("isvalid", isValid));
|
||||||
if (isValid)
|
if (isValid)
|
||||||
{
|
{
|
||||||
// Call Hash160ToAddress() so we always return current ADDRESSVERSION
|
CTxDestination dest = address.Get();
|
||||||
// version of the address:
|
|
||||||
string currentAddress = address.ToString();
|
string currentAddress = address.ToString();
|
||||||
ret.push_back(Pair("address", currentAddress));
|
ret.push_back(Pair("address", currentAddress));
|
||||||
if (pwalletMain->HaveKey(address))
|
bool fMine = IsMine(*pwalletMain, dest);
|
||||||
{
|
ret.push_back(Pair("ismine", fMine));
|
||||||
ret.push_back(Pair("ismine", true));
|
if (fMine) {
|
||||||
std::vector<unsigned char> vchPubKey;
|
Object detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
|
||||||
pwalletMain->GetPubKey(address, vchPubKey);
|
ret.insert(ret.end(), detail.begin(), detail.end());
|
||||||
ret.push_back(Pair("pubkey", HexStr(vchPubKey)));
|
|
||||||
CKey key;
|
|
||||||
key.SetPubKey(vchPubKey);
|
|
||||||
ret.push_back(Pair("iscompressed", key.IsCompressed()));
|
|
||||||
}
|
}
|
||||||
else if (pwalletMain->HaveCScript(address.GetHash160()))
|
if (pwalletMain->mapAddressBook.count(dest))
|
||||||
{
|
ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest]));
|
||||||
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));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ret.push_back(Pair("ismine", false));
|
|
||||||
if (pwalletMain->mapAddressBook.count(address))
|
|
||||||
ret.push_back(Pair("account", pwalletMain->mapAddressBook[address]));
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -605,11 +605,11 @@ bool AppInit2()
|
||||||
// Create new keyUser and set as default key
|
// Create new keyUser and set as default key
|
||||||
RandAddSeedPerfmon();
|
RandAddSeedPerfmon();
|
||||||
|
|
||||||
std::vector<unsigned char> newDefaultKey;
|
CPubKey newDefaultKey;
|
||||||
if (!pwalletMain->GetKeyFromPool(newDefaultKey, false))
|
if (!pwalletMain->GetKeyFromPool(newDefaultKey, false))
|
||||||
strErrors << _("Cannot initialize keypool") << "\n";
|
strErrors << _("Cannot initialize keypool") << "\n";
|
||||||
pwalletMain->SetDefaultKey(newDefaultKey);
|
pwalletMain->SetDefaultKey(newDefaultKey);
|
||||||
if (!pwalletMain->SetAddressBookName(CBitcoinAddress(pwalletMain->vchDefaultKey), ""))
|
if (!pwalletMain->SetAddressBookName(pwalletMain->vchDefaultKey.GetID(), ""))
|
||||||
strErrors << _("Cannot write default address") << "\n";
|
strErrors << _("Cannot write default address") << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
src/key.cpp
12
src/key.cpp
|
@ -239,18 +239,18 @@ CPrivKey CKey::GetPrivKey() const
|
||||||
return vchPrivKey;
|
return vchPrivKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CKey::SetPubKey(const std::vector<unsigned char>& vchPubKey)
|
bool CKey::SetPubKey(const CPubKey& vchPubKey)
|
||||||
{
|
{
|
||||||
const unsigned char* pbegin = &vchPubKey[0];
|
const unsigned char* pbegin = &vchPubKey.vchPubKey[0];
|
||||||
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
|
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.vchPubKey.size()))
|
||||||
return false;
|
return false;
|
||||||
fSet = true;
|
fSet = true;
|
||||||
if (vchPubKey.size() == 33)
|
if (vchPubKey.vchPubKey.size() == 33)
|
||||||
SetCompressedPubKey();
|
SetCompressedPubKey();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<unsigned char> CKey::GetPubKey() const
|
CPubKey CKey::GetPubKey() const
|
||||||
{
|
{
|
||||||
int nSize = i2o_ECPublicKey(pkey, NULL);
|
int nSize = i2o_ECPublicKey(pkey, NULL);
|
||||||
if (!nSize)
|
if (!nSize)
|
||||||
|
@ -259,7 +259,7 @@ std::vector<unsigned char> CKey::GetPubKey() const
|
||||||
unsigned char* pbegin = &vchPubKey[0];
|
unsigned char* pbegin = &vchPubKey[0];
|
||||||
if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
|
if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
|
||||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
|
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
|
||||||
return vchPubKey;
|
return CPubKey(vchPubKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CKey::Sign(uint256 hash, std::vector<unsigned char>& vchSig)
|
bool CKey::Sign(uint256 hash, std::vector<unsigned char>& vchSig)
|
||||||
|
|
60
src/key.h
60
src/key.h
|
@ -9,7 +9,9 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "allocators.h"
|
#include "allocators.h"
|
||||||
|
#include "serialize.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#include <openssl/ec.h> // for EC_KEY definition
|
#include <openssl/ec.h> // for EC_KEY definition
|
||||||
|
|
||||||
|
@ -42,6 +44,60 @@ public:
|
||||||
explicit key_error(const std::string& str) : std::runtime_error(str) {}
|
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;
|
||||||
|
friend class CKey;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CPubKey() { }
|
||||||
|
CPubKey(const std::vector<unsigned char> &vchPubKeyIn) : vchPubKey(vchPubKeyIn) { }
|
||||||
|
friend bool operator==(const CPubKey &a, const CPubKey &b) { return a.vchPubKey == b.vchPubKey; }
|
||||||
|
friend bool operator!=(const CPubKey &a, const CPubKey &b) { return a.vchPubKey != b.vchPubKey; }
|
||||||
|
friend bool operator<(const CPubKey &a, const CPubKey &b) { return a.vchPubKey < b.vchPubKey; }
|
||||||
|
|
||||||
|
IMPLEMENT_SERIALIZE(
|
||||||
|
READWRITE(vchPubKey);
|
||||||
|
)
|
||||||
|
|
||||||
|
CKeyID GetID() const {
|
||||||
|
return CKeyID(Hash160(vchPubKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint256 GetHash() const {
|
||||||
|
return Hash(vchPubKey.begin(), vchPubKey.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsValid() const {
|
||||||
|
return vchPubKey.size() == 33 || vchPubKey.size() == 65;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsCompressed() const {
|
||||||
|
return vchPubKey.size() == 33;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> Raw() const {
|
||||||
|
return vchPubKey;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// secure_allocator is defined in serialize.h
|
// secure_allocator is defined in serialize.h
|
||||||
// CPrivKey is a serialized private key, with all parameters included (279 bytes)
|
// CPrivKey is a serialized private key, with all parameters included (279 bytes)
|
||||||
|
@ -78,8 +134,8 @@ public:
|
||||||
bool SetSecret(const CSecret& vchSecret, bool fCompressed = false);
|
bool SetSecret(const CSecret& vchSecret, bool fCompressed = false);
|
||||||
CSecret GetSecret(bool &fCompressed) const;
|
CSecret GetSecret(bool &fCompressed) const;
|
||||||
CPrivKey GetPrivKey() const;
|
CPrivKey GetPrivKey() const;
|
||||||
bool SetPubKey(const std::vector<unsigned char>& vchPubKey);
|
bool SetPubKey(const CPubKey& vchPubKey);
|
||||||
std::vector<unsigned char> GetPubKey() const;
|
CPubKey GetPubKey() const;
|
||||||
|
|
||||||
bool Sign(uint256 hash, std::vector<unsigned char>& vchSig);
|
bool Sign(uint256 hash, std::vector<unsigned char>& vchSig);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "keystore.h"
|
#include "keystore.h"
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
|
|
||||||
bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char> &vchPubKeyOut) const
|
bool CKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
|
||||||
{
|
{
|
||||||
CKey key;
|
CKey key;
|
||||||
if (!GetKey(address, key))
|
if (!GetKey(address, key))
|
||||||
|
@ -21,7 +21,7 @@ bool CBasicKeyStore::AddKey(const CKey& key)
|
||||||
CSecret secret = key.GetSecret(fCompressed);
|
CSecret secret = key.GetSecret(fCompressed);
|
||||||
{
|
{
|
||||||
LOCK(cs_KeyStore);
|
LOCK(cs_KeyStore);
|
||||||
mapKeys[CBitcoinAddress(key.GetPubKey())] = make_pair(secret, fCompressed);
|
mapKeys[key.GetPubKey().GetID()] = make_pair(secret, fCompressed);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -30,12 +30,12 @@ bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs_KeyStore);
|
LOCK(cs_KeyStore);
|
||||||
mapScripts[Hash160(redeemScript)] = redeemScript;
|
mapScripts[redeemScript.GetID()] = redeemScript;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBasicKeyStore::HaveCScript(const uint160& hash) const
|
bool CBasicKeyStore::HaveCScript(const CScriptID& hash) const
|
||||||
{
|
{
|
||||||
bool result;
|
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);
|
LOCK(cs_KeyStore);
|
||||||
|
@ -97,10 +97,10 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
||||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
|
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
|
||||||
for (; mi != mapCryptedKeys.end(); ++mi)
|
for (; mi != mapCryptedKeys.end(); ++mi)
|
||||||
{
|
{
|
||||||
const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
|
const CPubKey &vchPubKey = (*mi).second.first;
|
||||||
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
|
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
|
||||||
CSecret vchSecret;
|
CSecret vchSecret;
|
||||||
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
|
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
|
||||||
return false;
|
return false;
|
||||||
if (vchSecret.size() != 32)
|
if (vchSecret.size() != 32)
|
||||||
return false;
|
return false;
|
||||||
|
@ -128,9 +128,9 @@ bool CCryptoKeyStore::AddKey(const CKey& key)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::vector<unsigned char> vchCryptedSecret;
|
std::vector<unsigned char> vchCryptedSecret;
|
||||||
std::vector<unsigned char> vchPubKey = key.GetPubKey();
|
CPubKey vchPubKey = key.GetPubKey();
|
||||||
bool fCompressed;
|
bool fCompressed;
|
||||||
if (!EncryptSecret(vMasterKey, key.GetSecret(fCompressed), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
|
if (!EncryptSecret(vMasterKey, key.GetSecret(fCompressed), vchPubKey.GetHash(), vchCryptedSecret))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret))
|
if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret))
|
||||||
|
@ -140,19 +140,19 @@ bool CCryptoKeyStore::AddKey(const CKey& key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
|
bool CCryptoKeyStore::AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs_KeyStore);
|
LOCK(cs_KeyStore);
|
||||||
if (!SetCrypted())
|
if (!SetCrypted())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
mapCryptedKeys[CBitcoinAddress(vchPubKey)] = make_pair(vchPubKey, vchCryptedSecret);
|
mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
|
bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey& keyOut) const
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs_KeyStore);
|
LOCK(cs_KeyStore);
|
||||||
|
@ -162,10 +162,10 @@ bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
|
||||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
|
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
|
||||||
if (mi != mapCryptedKeys.end())
|
if (mi != mapCryptedKeys.end())
|
||||||
{
|
{
|
||||||
const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
|
const CPubKey &vchPubKey = (*mi).second.first;
|
||||||
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
|
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
|
||||||
CSecret vchSecret;
|
CSecret vchSecret;
|
||||||
if (!DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
|
if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
|
||||||
return false;
|
return false;
|
||||||
if (vchSecret.size() != 32)
|
if (vchSecret.size() != 32)
|
||||||
return false;
|
return false;
|
||||||
|
@ -177,7 +177,7 @@ bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const
|
bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs_KeyStore);
|
LOCK(cs_KeyStore);
|
||||||
|
@ -207,10 +207,10 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
|
||||||
CKey key;
|
CKey key;
|
||||||
if (!key.SetSecret(mKey.second.first, mKey.second.second))
|
if (!key.SetSecret(mKey.second.first, mKey.second.second))
|
||||||
return false;
|
return false;
|
||||||
const std::vector<unsigned char> vchPubKey = key.GetPubKey();
|
const CPubKey vchPubKey = key.GetPubKey();
|
||||||
std::vector<unsigned char> vchCryptedSecret;
|
std::vector<unsigned char> vchCryptedSecret;
|
||||||
bool fCompressed;
|
bool fCompressed;
|
||||||
if (!EncryptSecret(vMasterKeyIn, key.GetSecret(fCompressed), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
|
if (!EncryptSecret(vMasterKeyIn, key.GetSecret(fCompressed), vchPubKey.GetHash(), vchCryptedSecret))
|
||||||
return false;
|
return false;
|
||||||
if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
|
if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
#include "crypter.h"
|
#include "crypter.h"
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "base58.h"
|
|
||||||
#include <boost/signals2/signal.hpp>
|
#include <boost/signals2/signal.hpp>
|
||||||
|
|
||||||
class CScript;
|
class CScript;
|
||||||
|
@ -25,17 +24,17 @@ public:
|
||||||
virtual bool AddKey(const CKey& key) =0;
|
virtual bool AddKey(const CKey& key) =0;
|
||||||
|
|
||||||
// Check whether a key corresponding to a given address is present in the store.
|
// Check whether a key corresponding to a given address is present in the store.
|
||||||
virtual bool HaveKey(const CBitcoinAddress &address) const =0;
|
virtual bool HaveKey(const CKeyID &address) const =0;
|
||||||
virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0;
|
virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0;
|
||||||
virtual void GetKeys(std::set<CBitcoinAddress> &setAddress) const =0;
|
virtual void GetKeys(std::set<CKeyID> &setAddress) const =0;
|
||||||
virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
|
virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
|
||||||
|
|
||||||
// Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013
|
// Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013
|
||||||
virtual bool AddCScript(const CScript& redeemScript) =0;
|
virtual bool AddCScript(const CScript& redeemScript) =0;
|
||||||
virtual bool HaveCScript(const uint160 &hash) const =0;
|
virtual bool HaveCScript(const CScriptID &hash) const =0;
|
||||||
virtual bool GetCScript(const uint160 &hash, CScript& redeemScriptOut) 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;
|
CKey key;
|
||||||
if (!GetKey(address, key))
|
if (!GetKey(address, key))
|
||||||
|
@ -45,8 +44,8 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<CBitcoinAddress, std::pair<CSecret, bool> > KeyMap;
|
typedef std::map<CKeyID, std::pair<CSecret, bool> > KeyMap;
|
||||||
typedef std::map<uint160, CScript > ScriptMap;
|
typedef std::map<CScriptID, CScript > ScriptMap;
|
||||||
|
|
||||||
/** Basic key store, that keeps keys in an address->secret map */
|
/** Basic key store, that keeps keys in an address->secret map */
|
||||||
class CBasicKeyStore : public CKeyStore
|
class CBasicKeyStore : public CKeyStore
|
||||||
|
@ -57,7 +56,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool AddKey(const CKey& key);
|
bool AddKey(const CKey& key);
|
||||||
bool HaveKey(const CBitcoinAddress &address) const
|
bool HaveKey(const CKeyID &address) const
|
||||||
{
|
{
|
||||||
bool result;
|
bool result;
|
||||||
{
|
{
|
||||||
|
@ -66,7 +65,7 @@ public:
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
void GetKeys(std::set<CBitcoinAddress> &setAddress) const
|
void GetKeys(std::set<CKeyID> &setAddress) const
|
||||||
{
|
{
|
||||||
setAddress.clear();
|
setAddress.clear();
|
||||||
{
|
{
|
||||||
|
@ -79,7 +78,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool GetKey(const CBitcoinAddress &address, CKey &keyOut) const
|
bool GetKey(const CKeyID &address, CKey &keyOut) const
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs_KeyStore);
|
LOCK(cs_KeyStore);
|
||||||
|
@ -94,11 +93,11 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
virtual bool AddCScript(const CScript& redeemScript);
|
virtual bool AddCScript(const CScript& redeemScript);
|
||||||
virtual bool HaveCScript(const uint160 &hash) const;
|
virtual bool HaveCScript(const CScriptID &hash) const;
|
||||||
virtual bool GetCScript(const uint160 &hash, CScript& redeemScriptOut) const;
|
virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<CBitcoinAddress, std::pair<std::vector<unsigned char>, std::vector<unsigned char> > > CryptedKeyMap;
|
typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
|
||||||
|
|
||||||
/** Keystore which keeps the private keys encrypted.
|
/** Keystore which keeps the private keys encrypted.
|
||||||
* It derives from the basic key store, which is used if no encryption is active.
|
* It derives from the basic key store, which is used if no encryption is active.
|
||||||
|
@ -146,9 +145,9 @@ public:
|
||||||
|
|
||||||
bool Lock();
|
bool Lock();
|
||||||
|
|
||||||
virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
|
virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
|
||||||
bool AddKey(const CKey& key);
|
bool AddKey(const CKey& key);
|
||||||
bool HaveKey(const CBitcoinAddress &address) const
|
bool HaveKey(const CKeyID &address) const
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs_KeyStore);
|
LOCK(cs_KeyStore);
|
||||||
|
@ -158,9 +157,9 @@ public:
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const;
|
bool GetKey(const CKeyID &address, CKey& keyOut) const;
|
||||||
bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
|
bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
|
||||||
void GetKeys(std::set<CBitcoinAddress> &setAddress) const
|
void GetKeys(std::set<CKeyID> &setAddress) const
|
||||||
{
|
{
|
||||||
if (!IsCrypted())
|
if (!IsCrypted())
|
||||||
{
|
{
|
||||||
|
|
|
@ -2304,7 +2304,7 @@ unsigned char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
|
||||||
|
|
||||||
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||||
{
|
{
|
||||||
static map<CService, vector<unsigned char> > mapReuseKey;
|
static map<CService, CPubKey> mapReuseKey;
|
||||||
RandAddSeedPerfmon();
|
RandAddSeedPerfmon();
|
||||||
if (fDebug)
|
if (fDebug)
|
||||||
printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size());
|
printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size());
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "walletmodel.h"
|
#include "walletmodel.h"
|
||||||
|
|
||||||
#include "wallet.h"
|
#include "wallet.h"
|
||||||
|
#include "base58.h"
|
||||||
|
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
|
@ -58,11 +59,11 @@ public:
|
||||||
cachedAddressTable.clear();
|
cachedAddressTable.clear();
|
||||||
{
|
{
|
||||||
LOCK(wallet->cs_wallet);
|
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 CBitcoinAddress& address = item.first;
|
||||||
const std::string& strName = item.second;
|
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,
|
cachedAddressTable.append(AddressTableEntry(fMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending,
|
||||||
QString::fromStdString(strName),
|
QString::fromStdString(strName),
|
||||||
QString::fromStdString(address.ToString())));
|
QString::fromStdString(address.ToString())));
|
||||||
|
@ -220,7 +221,8 @@ bool AddressTableModel::setData(const QModelIndex & index, const QVariant & valu
|
||||||
switch(index.column())
|
switch(index.column())
|
||||||
{
|
{
|
||||||
case Label:
|
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;
|
break;
|
||||||
case Address:
|
case Address:
|
||||||
// Refuse to set invalid address, set error status and return false
|
// 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);
|
LOCK(wallet->cs_wallet);
|
||||||
// Remove old entry
|
// Remove old entry
|
||||||
wallet->DelAddressBookName(rec->address.toStdString());
|
wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get());
|
||||||
// Add new entry with new address
|
// 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;
|
break;
|
||||||
|
@ -314,7 +316,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
|
||||||
// Check for duplicate addresses
|
// Check for duplicate addresses
|
||||||
{
|
{
|
||||||
LOCK(wallet->cs_wallet);
|
LOCK(wallet->cs_wallet);
|
||||||
if(wallet->mapAddressBook.count(strAddress))
|
if(wallet->mapAddressBook.count(CBitcoinAddress(strAddress).Get()))
|
||||||
{
|
{
|
||||||
editStatus = DUPLICATE_ADDRESS;
|
editStatus = DUPLICATE_ADDRESS;
|
||||||
return QString();
|
return QString();
|
||||||
|
@ -331,13 +333,13 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
|
||||||
editStatus = WALLET_UNLOCK_FAILURE;
|
editStatus = WALLET_UNLOCK_FAILURE;
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
std::vector<unsigned char> newKey;
|
CPubKey newKey;
|
||||||
if(!wallet->GetKeyFromPool(newKey, true))
|
if(!wallet->GetKeyFromPool(newKey, true))
|
||||||
{
|
{
|
||||||
editStatus = KEY_GENERATION_FAILURE;
|
editStatus = KEY_GENERATION_FAILURE;
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
strAddress = CBitcoinAddress(newKey).ToString();
|
strAddress = CBitcoinAddress(newKey.GetID()).ToString();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -346,7 +348,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
|
||||||
// Add entry
|
// Add entry
|
||||||
{
|
{
|
||||||
LOCK(wallet->cs_wallet);
|
LOCK(wallet->cs_wallet);
|
||||||
wallet->SetAddressBookName(strAddress, strLabel);
|
wallet->SetAddressBookName(CBitcoinAddress(strAddress).Get(), strLabel);
|
||||||
}
|
}
|
||||||
return QString::fromStdString(strAddress);
|
return QString::fromStdString(strAddress);
|
||||||
}
|
}
|
||||||
|
@ -363,7 +365,7 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex & paren
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
LOCK(wallet->cs_wallet);
|
LOCK(wallet->cs_wallet);
|
||||||
wallet->DelAddressBookName(rec->address.toStdString());
|
wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -375,7 +377,7 @@ QString AddressTableModel::labelForAddress(const QString &address) const
|
||||||
{
|
{
|
||||||
LOCK(wallet->cs_wallet);
|
LOCK(wallet->cs_wallet);
|
||||||
CBitcoinAddress address_parsed(address.toStdString());
|
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())
|
if (mi != wallet->mapAddressBook.end())
|
||||||
{
|
{
|
||||||
return QString::fromStdString(mi->second);
|
return QString::fromStdString(mi->second);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "wallet.h"
|
#include "wallet.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
|
#include "base58.h"
|
||||||
|
|
||||||
#include "messagepage.h"
|
#include "messagepage.h"
|
||||||
#include "ui_messagepage.h"
|
#include "ui_messagepage.h"
|
||||||
|
@ -83,6 +84,13 @@ void MessagePage::on_signMessage_clicked()
|
||||||
QMessageBox::Abort, QMessageBox::Abort);
|
QMessageBox::Abort, QMessageBox::Abort);
|
||||||
return;
|
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());
|
WalletModel::UnlockContext ctx(model->requestUnlock());
|
||||||
if(!ctx.isValid())
|
if(!ctx.isValid())
|
||||||
|
@ -92,7 +100,7 @@ void MessagePage::on_signMessage_clicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
CKey key;
|
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::critical(this, tr("Error signing"), tr("Private key for %1 is not available.").arg(address),
|
||||||
QMessageBox::Abort, QMessageBox::Abort);
|
QMessageBox::Abort, QMessageBox::Abort);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "wallet.h"
|
#include "wallet.h"
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
|
#include "base58.h"
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
@ -85,14 +86,14 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
||||||
{
|
{
|
||||||
if (wallet->IsMine(txout))
|
if (wallet->IsMine(txout))
|
||||||
{
|
{
|
||||||
CBitcoinAddress address;
|
CTxDestination address;
|
||||||
if (ExtractAddress(txout.scriptPubKey, address) && wallet->HaveKey(address))
|
if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
|
||||||
{
|
{
|
||||||
if (wallet->mapAddressBook.count(address))
|
if (wallet->mapAddressBook.count(address))
|
||||||
{
|
{
|
||||||
strHTML += tr("<b>From:</b> ") + tr("unknown") + "<br>";
|
strHTML += tr("<b>From:</b> ") + tr("unknown") + "<br>";
|
||||||
strHTML += tr("<b>To:</b> ");
|
strHTML += tr("<b>To:</b> ");
|
||||||
strHTML += GUIUtil::HtmlEscape(address.ToString());
|
strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString());
|
||||||
if (!wallet->mapAddressBook[address].empty())
|
if (!wallet->mapAddressBook[address].empty())
|
||||||
strHTML += tr(" (yours, label: ") + GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + ")";
|
strHTML += tr(" (yours, label: ") + GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + ")";
|
||||||
else
|
else
|
||||||
|
@ -115,8 +116,9 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
||||||
// Online transaction
|
// Online transaction
|
||||||
strAddress = wtx.mapValue["to"];
|
strAddress = wtx.mapValue["to"];
|
||||||
strHTML += tr("<b>To:</b> ");
|
strHTML += tr("<b>To:</b> ");
|
||||||
if (wallet->mapAddressBook.count(strAddress) && !wallet->mapAddressBook[strAddress].empty())
|
CTxDestination dest = CBitcoinAddress(strAddress).Get();
|
||||||
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[strAddress]) + " ";
|
if (wallet->mapAddressBook.count(dest) && !wallet->mapAddressBook[dest].empty())
|
||||||
|
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[dest]) + " ";
|
||||||
strHTML += GUIUtil::HtmlEscape(strAddress) + "<br>";
|
strHTML += GUIUtil::HtmlEscape(strAddress) + "<br>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,13 +172,13 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
||||||
if (wtx.mapValue["to"].empty())
|
if (wtx.mapValue["to"].empty())
|
||||||
{
|
{
|
||||||
// Offline transaction
|
// Offline transaction
|
||||||
CBitcoinAddress address;
|
CTxDestination address;
|
||||||
if (ExtractAddress(txout.scriptPubKey, address))
|
if (ExtractDestination(txout.scriptPubKey, address))
|
||||||
{
|
{
|
||||||
strHTML += tr("<b>To:</b> ");
|
strHTML += tr("<b>To:</b> ");
|
||||||
if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].empty())
|
if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].empty())
|
||||||
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + " ";
|
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + " ";
|
||||||
strHTML += GUIUtil::HtmlEscape(address.ToString());
|
strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString());
|
||||||
strHTML += "<br>";
|
strHTML += "<br>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,12 +262,12 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
||||||
{
|
{
|
||||||
strHTML += "<li>";
|
strHTML += "<li>";
|
||||||
const CTxOut &vout = prev.vout[prevout.n];
|
const CTxOut &vout = prev.vout[prevout.n];
|
||||||
CBitcoinAddress address;
|
CTxDestination address;
|
||||||
if (ExtractAddress(vout.scriptPubKey, address))
|
if (ExtractDestination(vout.scriptPubKey, address))
|
||||||
{
|
{
|
||||||
if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].empty())
|
if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].empty())
|
||||||
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + " ";
|
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 + " Amount=" + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC,vout.nValue);
|
||||||
strHTML = strHTML + " IsMine=" + (wallet->IsMine(vout) ? "true" : "false") + "</li>";
|
strHTML = strHTML + " IsMine=" + (wallet->IsMine(vout) ? "true" : "false") + "</li>";
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "transactionrecord.h"
|
#include "transactionrecord.h"
|
||||||
|
|
||||||
#include "wallet.h"
|
#include "wallet.h"
|
||||||
|
#include "base58.h"
|
||||||
|
|
||||||
/* Return positive answer if transaction should be shown in list.
|
/* Return positive answer if transaction should be shown in list.
|
||||||
*/
|
*/
|
||||||
|
@ -50,7 +51,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
|
||||||
if(wallet->IsMine(txout))
|
if(wallet->IsMine(txout))
|
||||||
{
|
{
|
||||||
TransactionRecord sub(hash, nTime);
|
TransactionRecord sub(hash, nTime);
|
||||||
CBitcoinAddress address;
|
CTxDestination address;
|
||||||
sub.idx = parts.size(); // sequence number
|
sub.idx = parts.size(); // sequence number
|
||||||
sub.credit = txout.nValue;
|
sub.credit = txout.nValue;
|
||||||
if (wtx.IsCoinBase())
|
if (wtx.IsCoinBase())
|
||||||
|
@ -58,11 +59,11 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
|
||||||
// Generated
|
// Generated
|
||||||
sub.type = TransactionRecord::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
|
// Received by Bitcoin Address
|
||||||
sub.type = TransactionRecord::RecvWithAddress;
|
sub.type = TransactionRecord::RecvWithAddress;
|
||||||
sub.address = address.ToString();
|
sub.address = CBitcoinAddress(address).ToString();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -113,12 +114,12 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CBitcoinAddress address;
|
CTxDestination address;
|
||||||
if (ExtractAddress(txout.scriptPubKey, address))
|
if (ExtractDestination(txout.scriptPubKey, address))
|
||||||
{
|
{
|
||||||
// Sent to Bitcoin Address
|
// Sent to Bitcoin Address
|
||||||
sub.type = TransactionRecord::SendToAddress;
|
sub.type = TransactionRecord::SendToAddress;
|
||||||
sub.address = address.ToString();
|
sub.address = CBitcoinAddress(address).ToString();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "walletmodel.h"
|
#include "walletmodel.h"
|
||||||
#include "addresstablemodel.h"
|
#include "addresstablemodel.h"
|
||||||
#include "guiutil.h"
|
#include "guiutil.h"
|
||||||
|
#include "base58.h"
|
||||||
|
|
||||||
VerifyMessageDialog::VerifyMessageDialog(AddressTableModel *addressModel, QWidget *parent) :
|
VerifyMessageDialog::VerifyMessageDialog(AddressTableModel *addressModel, QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
|
@ -62,7 +63,7 @@ bool VerifyMessageDialog::checkAddress()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CBitcoinAddress address(key.GetPubKey());
|
CBitcoinAddress address(key.GetPubKey().GetID());
|
||||||
QString qStringAddress = QString::fromStdString(address.ToString());
|
QString qStringAddress = QString::fromStdString(address.ToString());
|
||||||
ui->lnAddress->setText(qStringAddress);
|
ui->lnAddress->setText(qStringAddress);
|
||||||
ui->copyToClipboard->setEnabled(true);
|
ui->copyToClipboard->setEnabled(true);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
#include "wallet.h"
|
#include "wallet.h"
|
||||||
#include "walletdb.h" // for BackupWallet
|
#include "walletdb.h" // for BackupWallet
|
||||||
|
#include "base58.h"
|
||||||
|
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
|
||||||
|
@ -137,7 +138,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
|
||||||
foreach(const SendCoinsRecipient &rcp, recipients)
|
foreach(const SendCoinsRecipient &rcp, recipients)
|
||||||
{
|
{
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey;
|
||||||
scriptPubKey.SetBitcoinAddress(rcp.address.toStdString());
|
scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
|
||||||
vecSend.push_back(make_pair(scriptPubKey, rcp.amount));
|
vecSend.push_back(make_pair(scriptPubKey, rcp.amount));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,16 +170,17 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
|
||||||
foreach(const SendCoinsRecipient &rcp, recipients)
|
foreach(const SendCoinsRecipient &rcp, recipients)
|
||||||
{
|
{
|
||||||
std::string strAddress = rcp.address.toStdString();
|
std::string strAddress = rcp.address.toStdString();
|
||||||
|
CTxDestination dest = CBitcoinAddress(strAddress).Get();
|
||||||
std::string strLabel = rcp.label.toStdString();
|
std::string strLabel = rcp.label.toStdString();
|
||||||
{
|
{
|
||||||
LOCK(wallet->cs_wallet);
|
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
|
// Check if we have a new address or an updated label
|
||||||
if (mi == wallet->mapAddressBook.end() || mi->second != strLabel)
|
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);
|
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,
|
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(QString, QString::fromStdString(label)),
|
||||||
Q_ARG(bool, isMine),
|
Q_ARG(bool, isMine),
|
||||||
Q_ARG(int, status));
|
Q_ARG(int, status));
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "init.h" // for pwalletMain
|
#include "init.h" // for pwalletMain
|
||||||
#include "bitcoinrpc.h"
|
#include "bitcoinrpc.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
|
#include "base58.h"
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
@ -51,8 +52,7 @@ Value importprivkey(const Array& params, bool fHelp)
|
||||||
bool fCompressed;
|
bool fCompressed;
|
||||||
CSecret secret = vchSecret.GetSecret(fCompressed);
|
CSecret secret = vchSecret.GetSecret(fCompressed);
|
||||||
key.SetSecret(secret, fCompressed);
|
key.SetSecret(secret, fCompressed);
|
||||||
CBitcoinAddress vchAddress = CBitcoinAddress(key.GetPubKey());
|
CKeyID vchAddress = key.GetPubKey().GetID();
|
||||||
|
|
||||||
{
|
{
|
||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
|
|
||||||
|
@ -80,9 +80,12 @@ Value dumpprivkey(const Array& params, bool fHelp)
|
||||||
CBitcoinAddress address;
|
CBitcoinAddress address;
|
||||||
if (!address.SetString(strAddress))
|
if (!address.SetString(strAddress))
|
||||||
throw JSONRPCError(-5, "Invalid Bitcoin address");
|
throw JSONRPCError(-5, "Invalid Bitcoin address");
|
||||||
|
CKeyID keyID;
|
||||||
|
if (!address.GetKeyID(keyID))
|
||||||
|
throw JSONRPCError(-3, "Address does not refer to a key");
|
||||||
CSecret vchSecret;
|
CSecret vchSecret;
|
||||||
bool fCompressed;
|
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");
|
throw JSONRPCError(-4,"Private key for address " + strAddress + " is not known");
|
||||||
return CBitcoinSecret(vchSecret, fCompressed).ToString();
|
return CBitcoinSecret(vchSecret, fCompressed).ToString();
|
||||||
}
|
}
|
||||||
|
|
119
src/script.cpp
119
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;
|
CKey key;
|
||||||
if (!keystore.GetKey(address, 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++)
|
for (vector<valtype>::const_iterator it = multisigdata.begin()+1; it != multisigdata.begin()+multisigdata.size()-1; it++)
|
||||||
{
|
{
|
||||||
const valtype& pubkey = *it;
|
const valtype& pubkey = *it;
|
||||||
CBitcoinAddress address;
|
CKeyID keyID = CPubKey(pubkey).GetID();
|
||||||
address.SetPubKey(pubkey);
|
if (Sign1(keyID, keystore, hash, nHashType, scriptSigRet))
|
||||||
if (Sign1(address, keystore, hash, nHashType, scriptSigRet))
|
|
||||||
{
|
{
|
||||||
++nSigned;
|
++nSigned;
|
||||||
if (nSigned == nRequired) break;
|
if (nSigned == nRequired) break;
|
||||||
|
@ -1360,22 +1359,22 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash
|
||||||
if (!Solver(scriptPubKey, whichTypeRet, vSolutions))
|
if (!Solver(scriptPubKey, whichTypeRet, vSolutions))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CBitcoinAddress address;
|
CKeyID keyID;
|
||||||
switch (whichTypeRet)
|
switch (whichTypeRet)
|
||||||
{
|
{
|
||||||
case TX_NONSTANDARD:
|
case TX_NONSTANDARD:
|
||||||
return false;
|
return false;
|
||||||
case TX_PUBKEY:
|
case TX_PUBKEY:
|
||||||
address.SetPubKey(vSolutions[0]);
|
keyID = CPubKey(vSolutions[0]).GetID();
|
||||||
return Sign1(address, keystore, hash, nHashType, scriptSigRet);
|
return Sign1(keyID, keystore, hash, nHashType, scriptSigRet);
|
||||||
case TX_PUBKEYHASH:
|
case TX_PUBKEYHASH:
|
||||||
address.SetHash160(uint160(vSolutions[0]));
|
keyID = CKeyID(uint160(vSolutions[0]));
|
||||||
if (!Sign1(address, keystore, hash, nHashType, scriptSigRet))
|
if (!Sign1(keyID, keystore, hash, nHashType, scriptSigRet))
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
valtype vch;
|
CPubKey vch;
|
||||||
keystore.GetPubKey(address, vch);
|
keystore.GetPubKey(keyID, vch);
|
||||||
scriptSigRet << vch;
|
scriptSigRet << vch;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -1436,14 +1435,30 @@ unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore)
|
||||||
unsigned int nResult = 0;
|
unsigned int nResult = 0;
|
||||||
BOOST_FOREACH(const valtype& pubkey, pubkeys)
|
BOOST_FOREACH(const valtype& pubkey, pubkeys)
|
||||||
{
|
{
|
||||||
CBitcoinAddress address;
|
CKeyID keyID = CPubKey(pubkey).GetID();
|
||||||
address.SetPubKey(pubkey);
|
if (keystore.HaveKey(keyID))
|
||||||
if (keystore.HaveKey(address))
|
|
||||||
++nResult;
|
++nResult;
|
||||||
}
|
}
|
||||||
return 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)
|
bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
|
||||||
{
|
{
|
||||||
vector<valtype> vSolutions;
|
vector<valtype> vSolutions;
|
||||||
|
@ -1451,21 +1466,21 @@ bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
|
||||||
if (!Solver(scriptPubKey, whichType, vSolutions))
|
if (!Solver(scriptPubKey, whichType, vSolutions))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CBitcoinAddress address;
|
CKeyID keyID;
|
||||||
switch (whichType)
|
switch (whichType)
|
||||||
{
|
{
|
||||||
case TX_NONSTANDARD:
|
case TX_NONSTANDARD:
|
||||||
return false;
|
return false;
|
||||||
case TX_PUBKEY:
|
case TX_PUBKEY:
|
||||||
address.SetPubKey(vSolutions[0]);
|
keyID = CPubKey(vSolutions[0]).GetID();
|
||||||
return keystore.HaveKey(address);
|
return keystore.HaveKey(keyID);
|
||||||
case TX_PUBKEYHASH:
|
case TX_PUBKEYHASH:
|
||||||
address.SetHash160(uint160(vSolutions[0]));
|
keyID = CKeyID(uint160(vSolutions[0]));
|
||||||
return keystore.HaveKey(address);
|
return keystore.HaveKey(keyID);
|
||||||
case TX_SCRIPTHASH:
|
case TX_SCRIPTHASH:
|
||||||
{
|
{
|
||||||
CScript subscript;
|
CScript subscript;
|
||||||
if (!keystore.GetCScript(uint160(vSolutions[0]), subscript))
|
if (!keystore.GetCScript(CScriptID(uint160(vSolutions[0])), subscript))
|
||||||
return false;
|
return false;
|
||||||
return IsMine(keystore, subscript);
|
return IsMine(keystore, subscript);
|
||||||
}
|
}
|
||||||
|
@ -1483,7 +1498,7 @@ bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExtractAddress(const CScript& scriptPubKey, CBitcoinAddress& addressRet)
|
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
||||||
{
|
{
|
||||||
vector<valtype> vSolutions;
|
vector<valtype> vSolutions;
|
||||||
txnouttype whichType;
|
txnouttype whichType;
|
||||||
|
@ -1492,24 +1507,24 @@ bool ExtractAddress(const CScript& scriptPubKey, CBitcoinAddress& addressRet)
|
||||||
|
|
||||||
if (whichType == TX_PUBKEY)
|
if (whichType == TX_PUBKEY)
|
||||||
{
|
{
|
||||||
addressRet.SetPubKey(vSolutions[0]);
|
addressRet = CPubKey(vSolutions[0]).GetID();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (whichType == TX_PUBKEYHASH)
|
else if (whichType == TX_PUBKEYHASH)
|
||||||
{
|
{
|
||||||
addressRet.SetHash160(uint160(vSolutions[0]));
|
addressRet = CKeyID(uint160(vSolutions[0]));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (whichType == TX_SCRIPTHASH)
|
else if (whichType == TX_SCRIPTHASH)
|
||||||
{
|
{
|
||||||
addressRet.SetScriptHash160(uint160(vSolutions[0]));
|
addressRet = CScriptID(uint160(vSolutions[0]));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Multisig txns have more than one address...
|
// Multisig txns have more than one address...
|
||||||
return false;
|
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();
|
addressRet.clear();
|
||||||
typeRet = TX_NONSTANDARD;
|
typeRet = TX_NONSTANDARD;
|
||||||
|
@ -1522,21 +1537,16 @@ bool ExtractAddresses(const CScript& scriptPubKey, txnouttype& typeRet, vector<C
|
||||||
nRequiredRet = vSolutions.front()[0];
|
nRequiredRet = vSolutions.front()[0];
|
||||||
for (unsigned int i = 1; i < vSolutions.size()-1; i++)
|
for (unsigned int i = 1; i < vSolutions.size()-1; i++)
|
||||||
{
|
{
|
||||||
CBitcoinAddress address;
|
CTxDestination address = CPubKey(vSolutions[i]).GetID();
|
||||||
address.SetPubKey(vSolutions[i]);
|
|
||||||
addressRet.push_back(address);
|
addressRet.push_back(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nRequiredRet = 1;
|
nRequiredRet = 1;
|
||||||
CBitcoinAddress address;
|
CTxDestination address;
|
||||||
if (typeRet == TX_PUBKEYHASH)
|
if (!ExtractDestination(scriptPubKey, address))
|
||||||
address.SetHash160(uint160(vSolutions.front()));
|
return false;
|
||||||
else if (typeRet == TX_SCRIPTHASH)
|
|
||||||
address.SetScriptHash160(uint160(vSolutions.front()));
|
|
||||||
else if (typeRet == TX_PUBKEY)
|
|
||||||
address.SetPubKey(vSolutions.front());
|
|
||||||
addressRet.push_back(address);
|
addressRet.push_back(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1694,13 +1704,34 @@ bool CScript::IsPayToScriptHash() const
|
||||||
this->at(22) == OP_EQUAL);
|
this->at(22) == OP_EQUAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScript::SetBitcoinAddress(const CBitcoinAddress& address)
|
class CScriptVisitor : public boost::static_visitor<bool>
|
||||||
{
|
{
|
||||||
this->clear();
|
private:
|
||||||
if (address.IsScript())
|
CScript *script;
|
||||||
*this << OP_HASH160 << address.GetHash160() << OP_EQUAL;
|
public:
|
||||||
else
|
CScriptVisitor(CScript *scriptin) { script = scriptin; }
|
||||||
*this << OP_DUP << OP_HASH160 << address.GetHash160() << OP_EQUALVERIFY << OP_CHECKSIG;
|
|
||||||
|
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)
|
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 << key.GetPubKey();
|
||||||
*this << EncodeOP_N(keys.size()) << OP_CHECKMULTISIG;
|
*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;
|
|
||||||
}
|
|
||||||
|
|
44
src/script.h
44
src/script.h
|
@ -5,15 +5,16 @@
|
||||||
#ifndef H_BITCOIN_SCRIPT
|
#ifndef H_BITCOIN_SCRIPT
|
||||||
#define H_BITCOIN_SCRIPT
|
#define H_BITCOIN_SCRIPT
|
||||||
|
|
||||||
#include "base58.h"
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/variant.hpp>
|
||||||
|
|
||||||
|
#include "keystore.h"
|
||||||
|
#include "bignum.h"
|
||||||
|
|
||||||
class CTransaction;
|
class CTransaction;
|
||||||
class CKeyStore;
|
|
||||||
|
|
||||||
/** Signature hash types/flags */
|
/** Signature hash types/flags */
|
||||||
enum
|
enum
|
||||||
|
@ -35,6 +36,20 @@ enum txnouttype
|
||||||
TX_MULTISIG,
|
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);
|
const char* GetTxnOutputType(txnouttype t);
|
||||||
|
|
||||||
/** Script opcodes */
|
/** Script opcodes */
|
||||||
|
@ -320,6 +335,12 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CScript& operator<<(const CPubKey& key)
|
||||||
|
{
|
||||||
|
std::vector<unsigned char> vchKey = key.Raw();
|
||||||
|
return (*this) << vchKey;
|
||||||
|
}
|
||||||
|
|
||||||
CScript& operator<<(const CBigNum& b)
|
CScript& operator<<(const CBigNum& b)
|
||||||
{
|
{
|
||||||
*this << b.getvch();
|
*this << b.getvch();
|
||||||
|
@ -515,13 +536,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SetBitcoinAddress(const CBitcoinAddress& address);
|
void SetDestination(const CTxDestination& address);
|
||||||
void SetBitcoinAddress(const std::vector<unsigned char>& vchPubKey)
|
|
||||||
{
|
|
||||||
SetBitcoinAddress(CBitcoinAddress(vchPubKey));
|
|
||||||
}
|
|
||||||
void SetMultisig(int nRequired, const std::vector<CKey>& keys);
|
void SetMultisig(int nRequired, const std::vector<CKey>& keys);
|
||||||
void SetPayToScriptHash(const CScript& subscript);
|
|
||||||
|
|
||||||
|
|
||||||
void PrintHex() const
|
void PrintHex() const
|
||||||
|
@ -556,6 +572,11 @@ public:
|
||||||
{
|
{
|
||||||
printf("%s\n", ToString().c_str());
|
printf("%s\n", ToString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CScriptID GetID() const
|
||||||
|
{
|
||||||
|
return CScriptID(Hash160(*this));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -567,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);
|
int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions);
|
||||||
bool IsStandard(const CScript& scriptPubKey);
|
bool IsStandard(const CScript& scriptPubKey);
|
||||||
bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey);
|
bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey);
|
||||||
bool ExtractAddress(const CScript& scriptPubKey, CBitcoinAddress& addressRet);
|
bool IsMine(const CKeyStore& keystore, const CTxDestination &dest);
|
||||||
bool ExtractAddresses(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CBitcoinAddress>& addressRet, int& nRequiredRet);
|
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 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);
|
bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, bool fValidatePayToScriptHash, int nHashType);
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
|
||||||
tx.vin[0].scriptSig << OP_1;
|
tx.vin[0].scriptSig << OP_1;
|
||||||
tx.vout.resize(1);
|
tx.vout.resize(1);
|
||||||
tx.vout[0].nValue = 1*CENT;
|
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);
|
CDataStream ds(SER_DISK, CLIENT_VERSION);
|
||||||
ds << tx;
|
ds << tx;
|
||||||
|
@ -179,7 +179,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
|
||||||
tx.vin[0].prevout.hash = txPrev.GetHash();
|
tx.vin[0].prevout.hash = txPrev.GetHash();
|
||||||
tx.vout.resize(1);
|
tx.vout.resize(1);
|
||||||
tx.vout[0].nValue = 1*CENT;
|
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);
|
SignSignature(keystore, txPrev, tx, 0);
|
||||||
|
|
||||||
CDataStream ds(SER_DISK, CLIENT_VERSION);
|
CDataStream ds(SER_DISK, CLIENT_VERSION);
|
||||||
|
@ -195,7 +195,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
|
||||||
CTransaction tx;
|
CTransaction tx;
|
||||||
tx.vout.resize(1);
|
tx.vout.resize(1);
|
||||||
tx.vout[0].nValue = 1*CENT;
|
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);
|
tx.vin.resize(500);
|
||||||
for (unsigned int j = 0; j < tx.vin.size(); j++)
|
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.vin[0].scriptSig << OP_1;
|
||||||
tx.vout.resize(1);
|
tx.vout.resize(1);
|
||||||
tx.vout[0].nValue = 1*CENT;
|
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);
|
CDataStream ds(SER_DISK, CLIENT_VERSION);
|
||||||
ds << tx;
|
ds << tx;
|
||||||
|
@ -255,7 +255,7 @@ BOOST_AUTO_TEST_CASE(DoS_checkSig)
|
||||||
CTransaction tx;
|
CTransaction tx;
|
||||||
tx.vout.resize(1);
|
tx.vout.resize(1);
|
||||||
tx.vout[0].nValue = 1*CENT;
|
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);
|
tx.vin.resize(NPREV);
|
||||||
for (unsigned int j = 0; j < tx.vin.size(); j++)
|
for (unsigned int j = 0; j < tx.vin.size(); j++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
#include "main.h"
|
#include "base58.h"
|
||||||
#include "wallet.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE(base58_tests)
|
BOOST_AUTO_TEST_SUITE(base58_tests)
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,18 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static const string strSecret1 ("5HxWvvfubhXpYYpS3tJkw6fq9jE9j18THftkZjHHfmFiWtmAbrj");
|
static const string strSecret1 ("5HxWvvfubhXpYYpS3tJkw6fq9jE9j18THftkZjHHfmFiWtmAbrj");
|
||||||
static const string strSecret2 ("5KC4ejrDjv152FGwP386VD1i2NYc5KkfSMyv1nGy1VGDxGHqVY3");
|
static const string strSecret2 ("5KC4ejrDjv152FGwP386VD1i2NYc5KkfSMyv1nGy1VGDxGHqVY3");
|
||||||
static const string strSecret1C("Kwr371tjA9u2rFSMZjTNun2PXXP3WPZu2afRHTcta6KxEUdm1vEw");
|
static const string strSecret1C ("Kwr371tjA9u2rFSMZjTNun2PXXP3WPZu2afRHTcta6KxEUdm1vEw");
|
||||||
static const string strSecret2C("L3Hq7a8FEQwJkW1M2GNKDW28546Vp5miewcCzSqUD9kCAXrJdS3g");
|
static const string strSecret2C ("L3Hq7a8FEQwJkW1M2GNKDW28546Vp5miewcCzSqUD9kCAXrJdS3g");
|
||||||
static const string strAddress1("1HV9Lc3sNHZxwj4Zk6fB38tEmBryq2cBiF");
|
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
|
#ifdef KEY_TESTS_DUMPINFO
|
||||||
void dumpKeyInfo(uint256 privkey)
|
void dumpKeyInfo(uint256 privkey)
|
||||||
|
@ -53,7 +60,7 @@ BOOST_AUTO_TEST_CASE(key_test1)
|
||||||
BOOST_CHECK( bsecret2.SetString (strSecret2));
|
BOOST_CHECK( bsecret2.SetString (strSecret2));
|
||||||
BOOST_CHECK( bsecret1C.SetString(strSecret1C));
|
BOOST_CHECK( bsecret1C.SetString(strSecret1C));
|
||||||
BOOST_CHECK( bsecret2C.SetString(strSecret2C));
|
BOOST_CHECK( bsecret2C.SetString(strSecret2C));
|
||||||
BOOST_CHECK(!baddress1.SetString(strAddress1));
|
BOOST_CHECK(!baddress1.SetString(strAddressBad));
|
||||||
|
|
||||||
bool fCompressed;
|
bool fCompressed;
|
||||||
CSecret secret1 = bsecret1.GetSecret (fCompressed);
|
CSecret secret1 = bsecret1.GetSecret (fCompressed);
|
||||||
|
@ -74,10 +81,10 @@ BOOST_AUTO_TEST_CASE(key_test1)
|
||||||
key1C.SetSecret(secret1, true);
|
key1C.SetSecret(secret1, true);
|
||||||
key2C.SetSecret(secret2, true);
|
key2C.SetSecret(secret2, true);
|
||||||
|
|
||||||
BOOST_CHECK(CBitcoinAddress(key1.GetPubKey ()).ToString() == "1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ");
|
BOOST_CHECK(addr1.Get() == CTxDestination(key1.GetPubKey().GetID()));
|
||||||
BOOST_CHECK(CBitcoinAddress(key2.GetPubKey ()).ToString() == "1F5y5E5FMc5YzdJtB9hLaUe43GDxEKXENJ");
|
BOOST_CHECK(addr2.Get() == CTxDestination(key2.GetPubKey().GetID()));
|
||||||
BOOST_CHECK(CBitcoinAddress(key1C.GetPubKey()).ToString() == "1NoJrossxPBKfCHuJXT4HadJrXRE9Fxiqs");
|
BOOST_CHECK(addr1C.Get() == CTxDestination(key1C.GetPubKey().GetID()));
|
||||||
BOOST_CHECK(CBitcoinAddress(key2C.GetPubKey()).ToString() == "1CRj2HyM1CXWzHAXLQtiGLyggNT9WQqsDs");
|
BOOST_CHECK(addr2C.Get() == CTxDestination(key2C.GetPubKey().GetID()));
|
||||||
|
|
||||||
for (int n=0; n<16; n++)
|
for (int n=0; n<16; n++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -175,12 +175,12 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
|
||||||
//
|
//
|
||||||
CBasicKeyStore keystore, emptykeystore, partialkeystore;
|
CBasicKeyStore keystore, emptykeystore, partialkeystore;
|
||||||
CKey key[3];
|
CKey key[3];
|
||||||
CBitcoinAddress keyaddr[3];
|
CTxDestination keyaddr[3];
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
key[i].MakeNewKey(true);
|
key[i].MakeNewKey(true);
|
||||||
keystore.AddKey(key[i]);
|
keystore.AddKey(key[i]);
|
||||||
keyaddr[i].SetPubKey(key[i].GetPubKey());
|
keyaddr[i] = key[i].GetPubKey().GetID();
|
||||||
}
|
}
|
||||||
partialkeystore.AddKey(key[0]);
|
partialkeystore.AddKey(key[0]);
|
||||||
|
|
||||||
|
@ -191,8 +191,8 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
|
||||||
s << key[0].GetPubKey() << OP_CHECKSIG;
|
s << key[0].GetPubKey() << OP_CHECKSIG;
|
||||||
BOOST_CHECK(Solver(s, whichType, solutions));
|
BOOST_CHECK(Solver(s, whichType, solutions));
|
||||||
BOOST_CHECK(solutions.size() == 1);
|
BOOST_CHECK(solutions.size() == 1);
|
||||||
CBitcoinAddress addr;
|
CTxDestination addr;
|
||||||
BOOST_CHECK(ExtractAddress(s, addr));
|
BOOST_CHECK(ExtractDestination(s, addr));
|
||||||
BOOST_CHECK(addr == keyaddr[0]);
|
BOOST_CHECK(addr == keyaddr[0]);
|
||||||
BOOST_CHECK(IsMine(keystore, s));
|
BOOST_CHECK(IsMine(keystore, s));
|
||||||
BOOST_CHECK(!IsMine(emptykeystore, s));
|
BOOST_CHECK(!IsMine(emptykeystore, s));
|
||||||
|
@ -201,11 +201,11 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
|
||||||
vector<valtype> solutions;
|
vector<valtype> solutions;
|
||||||
txnouttype whichType;
|
txnouttype whichType;
|
||||||
CScript s;
|
CScript s;
|
||||||
s << OP_DUP << OP_HASH160 << Hash160(key[0].GetPubKey()) << 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(Solver(s, whichType, solutions));
|
||||||
BOOST_CHECK(solutions.size() == 1);
|
BOOST_CHECK(solutions.size() == 1);
|
||||||
CBitcoinAddress addr;
|
CTxDestination addr;
|
||||||
BOOST_CHECK(ExtractAddress(s, addr));
|
BOOST_CHECK(ExtractDestination(s, addr));
|
||||||
BOOST_CHECK(addr == keyaddr[0]);
|
BOOST_CHECK(addr == keyaddr[0]);
|
||||||
BOOST_CHECK(IsMine(keystore, s));
|
BOOST_CHECK(IsMine(keystore, s));
|
||||||
BOOST_CHECK(!IsMine(emptykeystore, s));
|
BOOST_CHECK(!IsMine(emptykeystore, s));
|
||||||
|
@ -217,8 +217,8 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
|
||||||
s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << 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(Solver(s, whichType, solutions));
|
||||||
BOOST_CHECK_EQUAL(solutions.size(), 4);
|
BOOST_CHECK_EQUAL(solutions.size(), 4);
|
||||||
CBitcoinAddress addr;
|
CTxDestination addr;
|
||||||
BOOST_CHECK(!ExtractAddress(s, addr));
|
BOOST_CHECK(!ExtractDestination(s, addr));
|
||||||
BOOST_CHECK(IsMine(keystore, s));
|
BOOST_CHECK(IsMine(keystore, s));
|
||||||
BOOST_CHECK(!IsMine(emptykeystore, s));
|
BOOST_CHECK(!IsMine(emptykeystore, s));
|
||||||
BOOST_CHECK(!IsMine(partialkeystore, s));
|
BOOST_CHECK(!IsMine(partialkeystore, s));
|
||||||
|
@ -230,9 +230,9 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
|
||||||
s << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << 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(Solver(s, whichType, solutions));
|
||||||
BOOST_CHECK_EQUAL(solutions.size(), 4);
|
BOOST_CHECK_EQUAL(solutions.size(), 4);
|
||||||
vector<CBitcoinAddress> addrs;
|
vector<CTxDestination> addrs;
|
||||||
int nRequired;
|
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[0] == keyaddr[0]);
|
||||||
BOOST_CHECK(addrs[1] == keyaddr[1]);
|
BOOST_CHECK(addrs[1] == keyaddr[1]);
|
||||||
BOOST_CHECK(nRequired = 1);
|
BOOST_CHECK(nRequired = 1);
|
||||||
|
|
|
@ -65,14 +65,14 @@ BOOST_AUTO_TEST_CASE(sign)
|
||||||
// different keys, straight/P2SH, pubkey/pubkeyhash
|
// different keys, straight/P2SH, pubkey/pubkeyhash
|
||||||
CScript standardScripts[4];
|
CScript standardScripts[4];
|
||||||
standardScripts[0] << key[0].GetPubKey() << OP_CHECKSIG;
|
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[2] << key[1].GetPubKey() << OP_CHECKSIG;
|
||||||
standardScripts[3].SetBitcoinAddress(key[2].GetPubKey());
|
standardScripts[3].SetDestination(key[2].GetPubKey().GetID());
|
||||||
CScript evalScripts[4];
|
CScript evalScripts[4];
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
keystore.AddCScript(standardScripts[i]);
|
keystore.AddCScript(standardScripts[i]);
|
||||||
evalScripts[i].SetPayToScriptHash(standardScripts[i]);
|
evalScripts[i].SetDestination(standardScripts[i].GetID());
|
||||||
}
|
}
|
||||||
|
|
||||||
CTransaction txFrom; // Funding transaction:
|
CTransaction txFrom; // Funding transaction:
|
||||||
|
@ -122,7 +122,7 @@ BOOST_AUTO_TEST_CASE(norecurse)
|
||||||
invalidAsScript << OP_INVALIDOPCODE << OP_INVALIDOPCODE;
|
invalidAsScript << OP_INVALIDOPCODE << OP_INVALIDOPCODE;
|
||||||
|
|
||||||
CScript p2sh;
|
CScript p2sh;
|
||||||
p2sh.SetPayToScriptHash(invalidAsScript);
|
p2sh.SetDestination(invalidAsScript.GetID());
|
||||||
|
|
||||||
CScript scriptSig;
|
CScript scriptSig;
|
||||||
scriptSig << Serialize(invalidAsScript);
|
scriptSig << Serialize(invalidAsScript);
|
||||||
|
@ -133,7 +133,7 @@ BOOST_AUTO_TEST_CASE(norecurse)
|
||||||
// Try to recurse, and verification should succeed because
|
// Try to recurse, and verification should succeed because
|
||||||
// the inner HASH160 <> EQUAL should only check the hash:
|
// the inner HASH160 <> EQUAL should only check the hash:
|
||||||
CScript p2sh2;
|
CScript p2sh2;
|
||||||
p2sh2.SetPayToScriptHash(p2sh);
|
p2sh2.SetDestination(p2sh.GetID());
|
||||||
CScript scriptSig2;
|
CScript scriptSig2;
|
||||||
scriptSig2 << Serialize(invalidAsScript) << Serialize(p2sh);
|
scriptSig2 << Serialize(invalidAsScript) << Serialize(p2sh);
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ BOOST_AUTO_TEST_CASE(set)
|
||||||
}
|
}
|
||||||
|
|
||||||
CScript inner[4];
|
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[1].SetMultisig(2, std::vector<CKey>(keys.begin(), keys.begin()+2));
|
||||||
inner[2].SetMultisig(1, 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));
|
inner[3].SetMultisig(2, std::vector<CKey>(keys.begin(), keys.begin()+3));
|
||||||
|
@ -162,7 +162,7 @@ BOOST_AUTO_TEST_CASE(set)
|
||||||
CScript outer[4];
|
CScript outer[4];
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
outer[i].SetPayToScriptHash(inner[i]);
|
outer[i].SetDestination(inner[i].GetID());
|
||||||
keystore.AddCScript(inner[i]);
|
keystore.AddCScript(inner[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ BOOST_AUTO_TEST_CASE(switchover)
|
||||||
scriptSig << Serialize(notValid);
|
scriptSig << Serialize(notValid);
|
||||||
|
|
||||||
CScript fund;
|
CScript fund;
|
||||||
fund.SetPayToScriptHash(notValid);
|
fund.SetDestination(notValid.GetID());
|
||||||
|
|
||||||
|
|
||||||
// Validation should succeed under old rules (hash is correct):
|
// Validation should succeed under old rules (hash is correct):
|
||||||
|
@ -258,9 +258,9 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
||||||
txFrom.vout.resize(6);
|
txFrom.vout.resize(6);
|
||||||
|
|
||||||
// First three are standard:
|
// First three are standard:
|
||||||
CScript pay1; pay1.SetBitcoinAddress(key[0].GetPubKey());
|
CScript pay1; pay1.SetDestination(key[0].GetPubKey().GetID());
|
||||||
keystore.AddCScript(pay1);
|
keystore.AddCScript(pay1);
|
||||||
CScript payScriptHash1; payScriptHash1.SetPayToScriptHash(pay1);
|
CScript payScriptHash1; payScriptHash1.SetDestination(pay1.GetID());
|
||||||
CScript pay1of3; pay1of3.SetMultisig(1, keys);
|
CScript pay1of3; pay1of3.SetMultisig(1, keys);
|
||||||
|
|
||||||
txFrom.vout[0].scriptPubKey = payScriptHash1;
|
txFrom.vout[0].scriptPubKey = payScriptHash1;
|
||||||
|
@ -278,13 +278,13 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
||||||
for (int i = 0; i < 11; i++)
|
for (int i = 0; i < 11; i++)
|
||||||
oneOfEleven << key[0].GetPubKey();
|
oneOfEleven << key[0].GetPubKey();
|
||||||
oneOfEleven << OP_11 << OP_CHECKMULTISIG;
|
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);
|
mapInputs[txFrom.GetHash()] = make_pair(CTxIndex(), txFrom);
|
||||||
|
|
||||||
CTransaction txTo;
|
CTransaction txTo;
|
||||||
txTo.vout.resize(1);
|
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.resize(3);
|
||||||
txTo.vin[0].prevout.n = 0;
|
txTo.vin[0].prevout.n = 0;
|
||||||
|
@ -311,7 +311,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
||||||
|
|
||||||
CTransaction txToNonStd;
|
CTransaction txToNonStd;
|
||||||
txToNonStd.vout.resize(1);
|
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.resize(2);
|
||||||
txToNonStd.vin[0].prevout.n = 4;
|
txToNonStd.vin[0].prevout.n = 4;
|
||||||
txToNonStd.vin[0].prevout.hash = txFrom.GetHash();
|
txToNonStd.vin[0].prevout.hash = txFrom.GetHash();
|
||||||
|
|
|
@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount)
|
||||||
BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 21);
|
BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 21);
|
||||||
|
|
||||||
CScript p2sh;
|
CScript p2sh;
|
||||||
p2sh.SetPayToScriptHash(s1);
|
p2sh.SetDestination(s1.GetID());
|
||||||
CScript scriptSig;
|
CScript scriptSig;
|
||||||
scriptSig << OP_0 << Serialize(s1);
|
scriptSig << OP_0 << Serialize(s1);
|
||||||
BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig), 3);
|
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(true), 3);
|
||||||
BOOST_CHECK_EQUAL(s2.GetSigOpCount(false), 20);
|
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(true), 0);
|
||||||
BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(false), 0);
|
BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(false), 0);
|
||||||
CScript scriptSig2;
|
CScript scriptSig2;
|
||||||
|
|
|
@ -52,9 +52,9 @@ SetupDummyInputs(CBasicKeyStore& keystoreRet, MapPrevTx& inputsRet)
|
||||||
|
|
||||||
dummyTransactions[1].vout.resize(2);
|
dummyTransactions[1].vout.resize(2);
|
||||||
dummyTransactions[1].vout[0].nValue = 21*CENT;
|
dummyTransactions[1].vout[0].nValue = 21*CENT;
|
||||||
dummyTransactions[1].vout[0].scriptPubKey.SetBitcoinAddress(key[2].GetPubKey());
|
dummyTransactions[1].vout[0].scriptPubKey.SetDestination(key[2].GetPubKey().GetID());
|
||||||
dummyTransactions[1].vout[1].nValue = 22*CENT;
|
dummyTransactions[1].vout[1].nValue = 22*CENT;
|
||||||
dummyTransactions[1].vout[1].scriptPubKey.SetBitcoinAddress(key[3].GetPubKey());
|
dummyTransactions[1].vout[1].scriptPubKey.SetDestination(key[3].GetPubKey().GetID());
|
||||||
inputsRet[dummyTransactions[1].GetHash()] = make_pair(CTxIndex(), dummyTransactions[1]);
|
inputsRet[dummyTransactions[1].GetHash()] = make_pair(CTxIndex(), dummyTransactions[1]);
|
||||||
|
|
||||||
return dummyTransactions;
|
return dummyTransactions;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "walletdb.h"
|
#include "walletdb.h"
|
||||||
#include "crypter.h"
|
#include "crypter.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
|
#include "base58.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -16,7 +17,7 @@ using namespace std;
|
||||||
// mapWallet
|
// mapWallet
|
||||||
//
|
//
|
||||||
|
|
||||||
std::vector<unsigned char> CWallet::GenerateNewKey()
|
CPubKey CWallet::GenerateNewKey()
|
||||||
{
|
{
|
||||||
bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
|
bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ bool CWallet::AddKey(const CKey& key)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector<unsigned char> &vchCryptedSecret)
|
bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector<unsigned char> &vchCryptedSecret)
|
||||||
{
|
{
|
||||||
if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
|
if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
|
||||||
return false;
|
return false;
|
||||||
|
@ -361,16 +362,16 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
|
||||||
#ifndef QT_GUI
|
#ifndef QT_GUI
|
||||||
// If default receiving address gets used, replace it with a new one
|
// If default receiving address gets used, replace it with a new one
|
||||||
CScript scriptDefaultKey;
|
CScript scriptDefaultKey;
|
||||||
scriptDefaultKey.SetBitcoinAddress(vchDefaultKey);
|
scriptDefaultKey.SetDestination(vchDefaultKey.GetID());
|
||||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||||
{
|
{
|
||||||
if (txout.scriptPubKey == scriptDefaultKey)
|
if (txout.scriptPubKey == scriptDefaultKey)
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> newDefaultKey;
|
CPubKey newDefaultKey;
|
||||||
if (GetKeyFromPool(newDefaultKey, false))
|
if (GetKeyFromPool(newDefaultKey, false))
|
||||||
{
|
{
|
||||||
SetDefaultKey(newDefaultKey);
|
SetDefaultKey(newDefaultKey);
|
||||||
SetAddressBookName(CBitcoinAddress(vchDefaultKey), "");
|
SetAddressBookName(vchDefaultKey.GetID(), "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -455,7 +456,7 @@ int64 CWallet::GetDebit(const CTxIn &txin) const
|
||||||
|
|
||||||
bool CWallet::IsChange(const CTxOut& txout) const
|
bool CWallet::IsChange(const CTxOut& txout) const
|
||||||
{
|
{
|
||||||
CBitcoinAddress address;
|
CTxDestination address;
|
||||||
|
|
||||||
// TODO: fix handling of 'change' outputs. The assumption is that any
|
// TODO: fix handling of 'change' outputs. The assumption is that any
|
||||||
// payment to a TX_PUBKEYHASH that is mine but isn't in the address book
|
// payment to a TX_PUBKEYHASH that is mine but isn't in the address book
|
||||||
|
@ -464,7 +465,7 @@ bool CWallet::IsChange(const CTxOut& txout) const
|
||||||
// a better way of identifying which outputs are 'the send' and which are
|
// a better way of identifying which outputs are 'the send' and which are
|
||||||
// 'the change' will need to be implemented (maybe extend CWalletTx to remember
|
// 'the change' will need to be implemented (maybe extend CWalletTx to remember
|
||||||
// which output, if any, was change).
|
// which output, if any, was change).
|
||||||
if (ExtractAddress(txout.scriptPubKey, address) && HaveKey(address))
|
if (ExtractDestination(txout.scriptPubKey, address) && ::IsMine(*this, address))
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
if (!mapAddressBook.count(address))
|
if (!mapAddressBook.count(address))
|
||||||
|
@ -517,8 +518,8 @@ int CWalletTx::GetRequestCount() const
|
||||||
return nRequests;
|
return nRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<CBitcoinAddress, int64> >& listReceived,
|
void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<CTxDestination, int64> >& listReceived,
|
||||||
list<pair<CBitcoinAddress, int64> >& listSent, int64& nFee, string& strSentAccount) const
|
list<pair<CTxDestination, int64> >& listSent, int64& nFee, string& strSentAccount) const
|
||||||
{
|
{
|
||||||
nGeneratedImmature = nGeneratedMature = nFee = 0;
|
nGeneratedImmature = nGeneratedMature = nFee = 0;
|
||||||
listReceived.clear();
|
listReceived.clear();
|
||||||
|
@ -545,13 +546,12 @@ void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, l
|
||||||
// Sent/received.
|
// Sent/received.
|
||||||
BOOST_FOREACH(const CTxOut& txout, vout)
|
BOOST_FOREACH(const CTxOut& txout, vout)
|
||||||
{
|
{
|
||||||
CBitcoinAddress address;
|
CTxDestination address;
|
||||||
vector<unsigned char> vchPubKey;
|
vector<unsigned char> vchPubKey;
|
||||||
if (!ExtractAddress(txout.scriptPubKey, address))
|
if (!ExtractDestination(txout.scriptPubKey, address))
|
||||||
{
|
{
|
||||||
printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
|
printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
|
||||||
this->GetHash().ToString().c_str());
|
this->GetHash().ToString().c_str());
|
||||||
address = " unknown ";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't report 'change' txouts
|
// Don't report 'change' txouts
|
||||||
|
@ -575,25 +575,25 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, i
|
||||||
int64 allGeneratedImmature, allGeneratedMature, allFee;
|
int64 allGeneratedImmature, allGeneratedMature, allFee;
|
||||||
allGeneratedImmature = allGeneratedMature = allFee = 0;
|
allGeneratedImmature = allGeneratedMature = allFee = 0;
|
||||||
string strSentAccount;
|
string strSentAccount;
|
||||||
list<pair<CBitcoinAddress, int64> > listReceived;
|
list<pair<CTxDestination, int64> > listReceived;
|
||||||
list<pair<CBitcoinAddress, int64> > listSent;
|
list<pair<CTxDestination, int64> > listSent;
|
||||||
GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
|
GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
|
||||||
|
|
||||||
if (strAccount == "")
|
if (strAccount == "")
|
||||||
nGenerated = allGeneratedMature;
|
nGenerated = allGeneratedMature;
|
||||||
if (strAccount == strSentAccount)
|
if (strAccount == strSentAccount)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& s, listSent)
|
BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& s, listSent)
|
||||||
nSent += s.second;
|
nSent += s.second;
|
||||||
nFee = allFee;
|
nFee = allFee;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
LOCK(pwallet->cs_wallet);
|
LOCK(pwallet->cs_wallet);
|
||||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
|
BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listReceived)
|
||||||
{
|
{
|
||||||
if (pwallet->mapAddressBook.count(r.first))
|
if (pwallet->mapAddressBook.count(r.first))
|
||||||
{
|
{
|
||||||
map<CBitcoinAddress, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
|
map<CTxDestination, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
|
||||||
if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount)
|
if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount)
|
||||||
nReceived += r.second;
|
nReceived += r.second;
|
||||||
}
|
}
|
||||||
|
@ -1095,14 +1095,14 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW
|
||||||
// post-backup change.
|
// post-backup change.
|
||||||
|
|
||||||
// Reserve a new key pair from key pool
|
// Reserve a new key pair from key pool
|
||||||
vector<unsigned char> vchPubKey = reservekey.GetReservedKey();
|
CPubKey vchPubKey = reservekey.GetReservedKey();
|
||||||
// assert(mapKeys.count(vchPubKey));
|
// assert(mapKeys.count(vchPubKey));
|
||||||
|
|
||||||
// Fill a vout to ourself
|
// Fill a vout to ourself
|
||||||
// TODO: pass in scriptChange instead of reservekey so
|
// TODO: pass in scriptChange instead of reservekey so
|
||||||
// change transaction isn't always pay-to-bitcoin-address
|
// change transaction isn't always pay-to-bitcoin-address
|
||||||
CScript scriptChange;
|
CScript scriptChange;
|
||||||
scriptChange.SetBitcoinAddress(vchPubKey);
|
scriptChange.SetDestination(vchPubKey.GetID());
|
||||||
|
|
||||||
// Insert change txn at random position:
|
// Insert change txn at random position:
|
||||||
vector<CTxOut>::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size());
|
vector<CTxOut>::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size());
|
||||||
|
@ -1240,7 +1240,7 @@ string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
string CWallet::SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
|
string CWallet::SendMoneyToDestination(const CTxDestination& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
|
||||||
{
|
{
|
||||||
// Check amount
|
// Check amount
|
||||||
if (nValue <= 0)
|
if (nValue <= 0)
|
||||||
|
@ -1250,7 +1250,7 @@ string CWallet::SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64
|
||||||
|
|
||||||
// Parse Bitcoin address
|
// Parse Bitcoin address
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey;
|
||||||
scriptPubKey.SetBitcoinAddress(address);
|
scriptPubKey.SetDestination(address);
|
||||||
|
|
||||||
return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee);
|
return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee);
|
||||||
}
|
}
|
||||||
|
@ -1278,30 +1278,30 @@ int CWallet::LoadWallet(bool& fFirstRunRet)
|
||||||
|
|
||||||
if (nLoadWalletRet != DB_LOAD_OK)
|
if (nLoadWalletRet != DB_LOAD_OK)
|
||||||
return nLoadWalletRet;
|
return nLoadWalletRet;
|
||||||
fFirstRunRet = vchDefaultKey.empty();
|
fFirstRunRet = !vchDefaultKey.IsValid();
|
||||||
|
|
||||||
CreateThread(ThreadFlushWalletDB, &strWalletFile);
|
CreateThread(ThreadFlushWalletDB, &strWalletFile);
|
||||||
return DB_LOAD_OK;
|
return DB_LOAD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& strName)
|
bool CWallet::SetAddressBookName(const CTxDestination& address, const string& strName)
|
||||||
{
|
{
|
||||||
std::map<CBitcoinAddress, std::string>::iterator mi = mapAddressBook.find(address);
|
std::map<CTxDestination, std::string>::iterator mi = mapAddressBook.find(address);
|
||||||
mapAddressBook[address] = strName;
|
mapAddressBook[address] = strName;
|
||||||
NotifyAddressBookChanged(this, address.ToString(), strName, HaveKey(address), (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED);
|
NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address), (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED);
|
||||||
if (!fFileBacked)
|
if (!fFileBacked)
|
||||||
return false;
|
return false;
|
||||||
return CWalletDB(strWalletFile).WriteName(address.ToString(), strName);
|
return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::DelAddressBookName(const CBitcoinAddress& address)
|
bool CWallet::DelAddressBookName(const CTxDestination& address)
|
||||||
{
|
{
|
||||||
mapAddressBook.erase(address);
|
mapAddressBook.erase(address);
|
||||||
NotifyAddressBookChanged(this, address.ToString(), "", HaveKey(address), CT_DELETED);
|
NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), CT_DELETED);
|
||||||
if (!fFileBacked)
|
if (!fFileBacked)
|
||||||
return false;
|
return false;
|
||||||
return CWalletDB(strWalletFile).EraseName(address.ToString());
|
return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1332,7 +1332,7 @@ bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::SetDefaultKey(const std::vector<unsigned char> &vchPubKey)
|
bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
|
||||||
{
|
{
|
||||||
if (fFileBacked)
|
if (fFileBacked)
|
||||||
{
|
{
|
||||||
|
@ -1408,7 +1408,7 @@ bool CWallet::TopUpKeyPool()
|
||||||
void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
|
void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
|
||||||
{
|
{
|
||||||
nIndex = -1;
|
nIndex = -1;
|
||||||
keypool.vchPubKey.clear();
|
keypool.vchPubKey = CPubKey();
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
|
|
||||||
|
@ -1425,9 +1425,9 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
|
||||||
setKeyPool.erase(setKeyPool.begin());
|
setKeyPool.erase(setKeyPool.begin());
|
||||||
if (!walletdb.ReadPool(nIndex, keypool))
|
if (!walletdb.ReadPool(nIndex, keypool))
|
||||||
throw runtime_error("ReserveKeyFromKeyPool() : read failed");
|
throw runtime_error("ReserveKeyFromKeyPool() : read failed");
|
||||||
if (!HaveKey(Hash160(keypool.vchPubKey)))
|
if (!HaveKey(keypool.vchPubKey.GetID()))
|
||||||
throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
|
throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
|
||||||
assert(!keypool.vchPubKey.empty());
|
assert(keypool.vchPubKey.IsValid());
|
||||||
printf("keypool reserve %"PRI64d"\n", nIndex);
|
printf("keypool reserve %"PRI64d"\n", nIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1468,7 +1468,7 @@ void CWallet::ReturnKey(int64 nIndex)
|
||||||
printf("keypool return %"PRI64d"\n", nIndex);
|
printf("keypool return %"PRI64d"\n", nIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::GetKeyFromPool(vector<unsigned char>& result, bool fAllowReuse)
|
bool CWallet::GetKeyFromPool(CPubKey& result, bool fAllowReuse)
|
||||||
{
|
{
|
||||||
int64 nIndex = 0;
|
int64 nIndex = 0;
|
||||||
CKeyPool keypool;
|
CKeyPool keypool;
|
||||||
|
@ -1477,7 +1477,7 @@ bool CWallet::GetKeyFromPool(vector<unsigned char>& result, bool fAllowReuse)
|
||||||
ReserveKeyFromKeyPool(nIndex, keypool);
|
ReserveKeyFromKeyPool(nIndex, keypool);
|
||||||
if (nIndex == -1)
|
if (nIndex == -1)
|
||||||
{
|
{
|
||||||
if (fAllowReuse && !vchDefaultKey.empty())
|
if (fAllowReuse && vchDefaultKey.IsValid())
|
||||||
{
|
{
|
||||||
result = vchDefaultKey;
|
result = vchDefaultKey;
|
||||||
return true;
|
return true;
|
||||||
|
@ -1503,7 +1503,7 @@ int64 CWallet::GetOldestKeyPoolTime()
|
||||||
return keypool.nTime;
|
return keypool.nTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<unsigned char> CReserveKey::GetReservedKey()
|
CPubKey CReserveKey::GetReservedKey()
|
||||||
{
|
{
|
||||||
if (nIndex == -1)
|
if (nIndex == -1)
|
||||||
{
|
{
|
||||||
|
@ -1517,7 +1517,7 @@ vector<unsigned char> CReserveKey::GetReservedKey()
|
||||||
vchPubKey = pwallet->vchDefaultKey;
|
vchPubKey = pwallet->vchDefaultKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(!vchPubKey.empty());
|
assert(vchPubKey.IsValid());
|
||||||
return vchPubKey;
|
return vchPubKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1526,7 +1526,7 @@ void CReserveKey::KeepKey()
|
||||||
if (nIndex != -1)
|
if (nIndex != -1)
|
||||||
pwallet->KeepKey(nIndex);
|
pwallet->KeepKey(nIndex);
|
||||||
nIndex = -1;
|
nIndex = -1;
|
||||||
vchPubKey.clear();
|
vchPubKey = CPubKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CReserveKey::ReturnKey()
|
void CReserveKey::ReturnKey()
|
||||||
|
@ -1534,10 +1534,10 @@ void CReserveKey::ReturnKey()
|
||||||
if (nIndex != -1)
|
if (nIndex != -1)
|
||||||
pwallet->ReturnKey(nIndex);
|
pwallet->ReturnKey(nIndex);
|
||||||
nIndex = -1;
|
nIndex = -1;
|
||||||
vchPubKey.clear();
|
vchPubKey = CPubKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallet::GetAllReserveAddresses(set<CBitcoinAddress>& setAddress)
|
void CWallet::GetAllReserveKeys(set<CKeyID>& setAddress)
|
||||||
{
|
{
|
||||||
setAddress.clear();
|
setAddress.clear();
|
||||||
|
|
||||||
|
@ -1549,11 +1549,11 @@ void CWallet::GetAllReserveAddresses(set<CBitcoinAddress>& setAddress)
|
||||||
CKeyPool keypool;
|
CKeyPool keypool;
|
||||||
if (!walletdb.ReadPool(id, keypool))
|
if (!walletdb.ReadPool(id, keypool))
|
||||||
throw runtime_error("GetAllReserveKeyHashes() : read failed");
|
throw runtime_error("GetAllReserveKeyHashes() : read failed");
|
||||||
CBitcoinAddress address(keypool.vchPubKey);
|
assert(keypool.vchPubKey.IsValid());
|
||||||
assert(!keypool.vchPubKey.empty());
|
CKeyID keyID = keypool.vchPubKey.GetID();
|
||||||
if (!HaveKey(address))
|
if (!HaveKey(keyID))
|
||||||
throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool");
|
throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool");
|
||||||
setAddress.insert(address);
|
setAddress.insert(keyID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
40
src/wallet.h
40
src/wallet.h
|
@ -32,14 +32,14 @@ class CKeyPool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int64 nTime;
|
int64 nTime;
|
||||||
std::vector<unsigned char> vchPubKey;
|
CPubKey vchPubKey;
|
||||||
|
|
||||||
CKeyPool()
|
CKeyPool()
|
||||||
{
|
{
|
||||||
nTime = GetTime();
|
nTime = GetTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
CKeyPool(const std::vector<unsigned char>& vchPubKeyIn)
|
CKeyPool(const CPubKey& vchPubKeyIn)
|
||||||
{
|
{
|
||||||
nTime = GetTime();
|
nTime = GetTime();
|
||||||
vchPubKey = vchPubKeyIn;
|
vchPubKey = vchPubKeyIn;
|
||||||
|
@ -105,16 +105,16 @@ public:
|
||||||
std::map<uint256, CWalletTx> mapWallet;
|
std::map<uint256, CWalletTx> mapWallet;
|
||||||
std::map<uint256, int> mapRequestCount;
|
std::map<uint256, int> mapRequestCount;
|
||||||
|
|
||||||
std::map<CBitcoinAddress, std::string> mapAddressBook;
|
std::map<CTxDestination, std::string> mapAddressBook;
|
||||||
|
|
||||||
std::vector<unsigned char> vchDefaultKey;
|
CPubKey vchDefaultKey;
|
||||||
|
|
||||||
// check whether we are allowed to upgrade (or already support) to the named feature
|
// check whether we are allowed to upgrade (or already support) to the named feature
|
||||||
bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; }
|
bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; }
|
||||||
|
|
||||||
// keystore implementation
|
// keystore implementation
|
||||||
// Generate a new key
|
// Generate a new key
|
||||||
std::vector<unsigned char> GenerateNewKey();
|
CPubKey GenerateNewKey();
|
||||||
// Adds a key to the store, and saves it to disk.
|
// Adds a key to the store, and saves it to disk.
|
||||||
bool AddKey(const CKey& key);
|
bool AddKey(const CKey& key);
|
||||||
// Adds a key to the store, without saving it to disk (used by LoadWallet)
|
// Adds a key to the store, without saving it to disk (used by LoadWallet)
|
||||||
|
@ -123,9 +123,9 @@ public:
|
||||||
bool LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
|
bool LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
|
||||||
|
|
||||||
// Adds an encrypted key to the store, and saves it to disk.
|
// Adds an encrypted key to the store, and saves it to disk.
|
||||||
bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
|
bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
|
||||||
// Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
|
// Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
|
||||||
bool LoadCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { SetMinVersion(FEATURE_WALLETCRYPT); return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); }
|
bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { SetMinVersion(FEATURE_WALLETCRYPT); return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); }
|
||||||
bool AddCScript(const CScript& redeemScript);
|
bool AddCScript(const CScript& redeemScript);
|
||||||
bool LoadCScript(const CScript& redeemScript) { return CCryptoKeyStore::AddCScript(redeemScript); }
|
bool LoadCScript(const CScript& redeemScript) { return CCryptoKeyStore::AddCScript(redeemScript); }
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ public:
|
||||||
bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
|
bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
|
||||||
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
|
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
|
||||||
std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
|
std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
|
||||||
std::string SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
|
std::string SendMoneyToDestination(const CTxDestination &address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
|
||||||
|
|
||||||
bool NewKeyPool();
|
bool NewKeyPool();
|
||||||
bool TopUpKeyPool();
|
bool TopUpKeyPool();
|
||||||
|
@ -156,9 +156,9 @@ public:
|
||||||
void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
|
void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
|
||||||
void KeepKey(int64 nIndex);
|
void KeepKey(int64 nIndex);
|
||||||
void ReturnKey(int64 nIndex);
|
void ReturnKey(int64 nIndex);
|
||||||
bool GetKeyFromPool(std::vector<unsigned char> &key, bool fAllowReuse=true);
|
bool GetKeyFromPool(CPubKey &key, bool fAllowReuse=true);
|
||||||
int64 GetOldestKeyPoolTime();
|
int64 GetOldestKeyPoolTime();
|
||||||
void GetAllReserveAddresses(std::set<CBitcoinAddress>& setAddress);
|
void GetAllReserveKeys(std::set<CKeyID>& setAddress);
|
||||||
|
|
||||||
bool IsMine(const CTxIn& txin) const;
|
bool IsMine(const CTxIn& txin) const;
|
||||||
int64 GetDebit(const CTxIn& txin) const;
|
int64 GetDebit(const CTxIn& txin) const;
|
||||||
|
@ -227,9 +227,9 @@ public:
|
||||||
|
|
||||||
int LoadWallet(bool& fFirstRunRet);
|
int LoadWallet(bool& fFirstRunRet);
|
||||||
|
|
||||||
bool SetAddressBookName(const CBitcoinAddress& address, const std::string& strName);
|
bool SetAddressBookName(const CTxDestination& address, const std::string& strName);
|
||||||
|
|
||||||
bool DelAddressBookName(const CBitcoinAddress& address);
|
bool DelAddressBookName(const CTxDestination& address);
|
||||||
|
|
||||||
void UpdatedTransaction(const uint256 &hashTx);
|
void UpdatedTransaction(const uint256 &hashTx);
|
||||||
|
|
||||||
|
@ -252,7 +252,7 @@ public:
|
||||||
|
|
||||||
bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx);
|
bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx);
|
||||||
|
|
||||||
bool SetDefaultKey(const std::vector<unsigned char> &vchPubKey);
|
bool SetDefaultKey(const CPubKey &vchPubKey);
|
||||||
|
|
||||||
// signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
|
// signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
|
||||||
bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false);
|
bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false);
|
||||||
|
@ -266,7 +266,7 @@ public:
|
||||||
/** Address book entry changed.
|
/** Address book entry changed.
|
||||||
* @note called with lock cs_wallet held.
|
* @note called with lock cs_wallet held.
|
||||||
*/
|
*/
|
||||||
boost::signals2::signal<void (CWallet *wallet, const std::string &address, const std::string &label, bool isMine, ChangeType status)> NotifyAddressBookChanged;
|
boost::signals2::signal<void (CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, ChangeType status)> NotifyAddressBookChanged;
|
||||||
|
|
||||||
/** Wallet transaction added, removed or updated.
|
/** Wallet transaction added, removed or updated.
|
||||||
* @note called with lock cs_wallet held.
|
* @note called with lock cs_wallet held.
|
||||||
|
@ -280,7 +280,7 @@ class CReserveKey
|
||||||
protected:
|
protected:
|
||||||
CWallet* pwallet;
|
CWallet* pwallet;
|
||||||
int64 nIndex;
|
int64 nIndex;
|
||||||
std::vector<unsigned char> vchPubKey;
|
CPubKey vchPubKey;
|
||||||
public:
|
public:
|
||||||
CReserveKey(CWallet* pwalletIn)
|
CReserveKey(CWallet* pwalletIn)
|
||||||
{
|
{
|
||||||
|
@ -295,7 +295,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReturnKey();
|
void ReturnKey();
|
||||||
std::vector<unsigned char> GetReservedKey();
|
CPubKey GetReservedKey();
|
||||||
void KeepKey();
|
void KeepKey();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -532,8 +532,8 @@ public:
|
||||||
return nChangeCached;
|
return nChangeCached;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list<std::pair<CBitcoinAddress, int64> >& listReceived,
|
void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list<std::pair<CTxDestination, int64> >& listReceived,
|
||||||
std::list<std::pair<CBitcoinAddress, int64> >& listSent, int64& nFee, std::string& strSentAccount) const;
|
std::list<std::pair<CTxDestination, int64> >& listSent, int64& nFee, std::string& strSentAccount) const;
|
||||||
|
|
||||||
void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived,
|
void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived,
|
||||||
int64& nSent, int64& nFee) const;
|
int64& nSent, int64& nFee) const;
|
||||||
|
@ -640,7 +640,7 @@ public:
|
||||||
class CAccount
|
class CAccount
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::vector<unsigned char> vchPubKey;
|
CPubKey vchPubKey;
|
||||||
|
|
||||||
CAccount()
|
CAccount()
|
||||||
{
|
{
|
||||||
|
@ -649,7 +649,7 @@ public:
|
||||||
|
|
||||||
void SetNull()
|
void SetNull()
|
||||||
{
|
{
|
||||||
vchPubKey.clear();
|
vchPubKey = CPubKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_SERIALIZE
|
IMPLEMENT_SERIALIZE
|
||||||
|
|
|
@ -104,7 +104,7 @@ void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountin
|
||||||
|
|
||||||
int CWalletDB::LoadWallet(CWallet* pwallet)
|
int CWalletDB::LoadWallet(CWallet* pwallet)
|
||||||
{
|
{
|
||||||
pwallet->vchDefaultKey.clear();
|
pwallet->vchDefaultKey = CPubKey();
|
||||||
int nFileVersion = 0;
|
int nFileVersion = 0;
|
||||||
vector<uint256> vWalletUpgrade;
|
vector<uint256> vWalletUpgrade;
|
||||||
bool fIsEncrypted = false;
|
bool fIsEncrypted = false;
|
||||||
|
@ -151,7 +151,7 @@ int CWalletDB::LoadWallet(CWallet* pwallet)
|
||||||
{
|
{
|
||||||
string strAddress;
|
string strAddress;
|
||||||
ssKey >> strAddress;
|
ssKey >> strAddress;
|
||||||
ssValue >> pwallet->mapAddressBook[strAddress];
|
ssValue >> pwallet->mapAddressBook[CBitcoinAddress(strAddress).Get()];
|
||||||
}
|
}
|
||||||
else if (strType == "tx")
|
else if (strType == "tx")
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#define BITCOIN_WALLETDB_H
|
#define BITCOIN_WALLETDB_H
|
||||||
|
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
|
#include "base58.h"
|
||||||
|
|
||||||
class CKeyPool;
|
class CKeyPool;
|
||||||
class CAccount;
|
class CAccount;
|
||||||
|
@ -59,27 +60,27 @@ public:
|
||||||
return Erase(std::make_pair(std::string("tx"), hash));
|
return Erase(std::make_pair(std::string("tx"), hash));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReadKey(const std::vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
|
bool ReadKey(const CPubKey& vchPubKey, CPrivKey& vchPrivKey)
|
||||||
{
|
{
|
||||||
vchPrivKey.clear();
|
vchPrivKey.clear();
|
||||||
return Read(std::make_pair(std::string("key"), vchPubKey), vchPrivKey);
|
return Read(std::make_pair(std::string("key"), vchPubKey.Raw()), vchPrivKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WriteKey(const std::vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
|
bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey)
|
||||||
{
|
{
|
||||||
nWalletDBUpdated++;
|
nWalletDBUpdated++;
|
||||||
return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false);
|
return Write(std::make_pair(std::string("key"), vchPubKey.Raw()), vchPrivKey, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WriteCryptedKey(const std::vector<unsigned char>& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, bool fEraseUnencryptedKey = true)
|
bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, bool fEraseUnencryptedKey = true)
|
||||||
{
|
{
|
||||||
nWalletDBUpdated++;
|
nWalletDBUpdated++;
|
||||||
if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false))
|
if (!Write(std::make_pair(std::string("ckey"), vchPubKey.Raw()), vchCryptedSecret, false))
|
||||||
return false;
|
return false;
|
||||||
if (fEraseUnencryptedKey)
|
if (fEraseUnencryptedKey)
|
||||||
{
|
{
|
||||||
Erase(std::make_pair(std::string("key"), vchPubKey));
|
Erase(std::make_pair(std::string("key"), vchPubKey.Raw()));
|
||||||
Erase(std::make_pair(std::string("wkey"), vchPubKey));
|
Erase(std::make_pair(std::string("wkey"), vchPubKey.Raw()));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -120,10 +121,10 @@ public:
|
||||||
return Read(std::string("defaultkey"), vchPubKey);
|
return Read(std::string("defaultkey"), vchPubKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WriteDefaultKey(const std::vector<unsigned char>& vchPubKey)
|
bool WriteDefaultKey(const CPubKey& vchPubKey)
|
||||||
{
|
{
|
||||||
nWalletDBUpdated++;
|
nWalletDBUpdated++;
|
||||||
return Write(std::string("defaultkey"), vchPubKey);
|
return Write(std::string("defaultkey"), vchPubKey.Raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReadPool(int64 nPool, CKeyPool& keypool)
|
bool ReadPool(int64 nPool, CKeyPool& keypool)
|
||||||
|
|
Loading…
Reference in a new issue