|
|
@ -10,6 +10,7 @@ |
|
|
|
#include "bitcoinrpc.h" |
|
|
|
#include "bitcoinrpc.h" |
|
|
|
#include "init.h" |
|
|
|
#include "init.h" |
|
|
|
#include "base58.h" |
|
|
|
#include "base58.h" |
|
|
|
|
|
|
|
#include "main.h" |
|
|
|
|
|
|
|
|
|
|
|
using namespace std; |
|
|
|
using namespace std; |
|
|
|
using namespace boost; |
|
|
|
using namespace boost; |
|
|
@ -90,155 +91,51 @@ Value getinfo(const Array& params, bool fHelp) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Value getnewaddress(const Array& params, bool fHelp) |
|
|
|
Value createuserkey(const Array& params, bool fHelp) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (fHelp || params.size() > 1) |
|
|
|
if (fHelp || params.size() != 1) |
|
|
|
throw runtime_error( |
|
|
|
throw runtime_error( |
|
|
|
"getnewaddress [account]\n" |
|
|
|
"createuserkey <username>\n" |
|
|
|
"Returns a new Bitcoin address for receiving payments. " |
|
|
|
"Returns a new Bitcoin address for receiving payments. " |
|
|
|
"If [account] is specified (recommended), it is added to the address book " |
|
|
|
"If [account] is specified (recommended), it is added to the address book " |
|
|
|
"so payments received with the address will be credited to [account]."); |
|
|
|
"so payments received with the address will be credited to [account]."); |
|
|
|
|
|
|
|
|
|
|
|
// Parse the account first so we don't generate a key if there's an error
|
|
|
|
EnsureWalletIsUnlocked(); |
|
|
|
string strAccount; |
|
|
|
|
|
|
|
if (params.size() > 0) |
|
|
|
|
|
|
|
strAccount = AccountFromValue(params[0]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Generate a new key that is added to wallet
|
|
|
|
|
|
|
|
CPubKey newKey; |
|
|
|
|
|
|
|
if (!pwalletMain->GetKeyFromPool(newKey, false)) |
|
|
|
|
|
|
|
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); |
|
|
|
|
|
|
|
CKeyID keyID = newKey.GetID(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pwalletMain->SetAddressBookName(keyID, strAccount); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return CBitcoinAddress(keyID).ToString(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
CWalletDB walletdb(pwalletMain->strWalletFile); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CAccount account; |
|
|
|
|
|
|
|
walletdb.ReadAccount(strAccount, account); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool bKeyUsed = false; |
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
// Check if the current key has been used
|
|
|
|
|
|
|
|
if (account.vchPubKey.IsValid()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
CScript scriptPubKey; |
|
|
|
|
|
|
|
scriptPubKey.SetDestination(account.vchPubKey.GetID()); |
|
|
|
|
|
|
|
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); |
|
|
|
|
|
|
|
it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid(); |
|
|
|
|
|
|
|
++it) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
const CWalletTx& wtx = (*it).second; |
|
|
|
|
|
|
|
BOOST_FOREACH(const CTxOut& txout, wtx.vout) |
|
|
|
|
|
|
|
if (txout.scriptPubKey == scriptPubKey) |
|
|
|
|
|
|
|
bKeyUsed = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
// Generate a new key
|
|
|
|
|
|
|
|
if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false)) |
|
|
|
|
|
|
|
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pwalletMain->SetAddressBookName(account.vchPubKey.GetID(), strAccount); |
|
|
|
|
|
|
|
walletdb.WriteAccount(strAccount, account); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return CBitcoinAddress(account.vchPubKey.GetID()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Value getaccountaddress(const Array& params, bool fHelp) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (fHelp || params.size() != 1) |
|
|
|
|
|
|
|
throw runtime_error( |
|
|
|
|
|
|
|
"getaccountaddress <account>\n" |
|
|
|
|
|
|
|
"Returns the current Bitcoin address for receiving payments to this account."); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Parse the account first so we don't generate a key if there's an error
|
|
|
|
|
|
|
|
string strAccount = AccountFromValue(params[0]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Value ret; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ret = GetAccountAddress(strAccount).ToString(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Value setaccount(const Array& params, bool fHelp) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (fHelp || params.size() < 1 || params.size() > 2) |
|
|
|
|
|
|
|
throw runtime_error( |
|
|
|
|
|
|
|
"setaccount <bitcoinaddress> <account>\n" |
|
|
|
|
|
|
|
"Sets the account associated with the given address."); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CBitcoinAddress address(params[0].get_str()); |
|
|
|
|
|
|
|
if (!address.IsValid()) |
|
|
|
|
|
|
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string strAccount; |
|
|
|
|
|
|
|
if (params.size() > 1) |
|
|
|
|
|
|
|
strAccount = AccountFromValue(params[1]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Detect when changing the account of an address that is the 'unused current key' of another account:
|
|
|
|
|
|
|
|
if (pwalletMain->mapAddressBook.count(address.Get())) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
string strOldAccount = pwalletMain->mapAddressBook[address.Get()]; |
|
|
|
|
|
|
|
if (address == GetAccountAddress(strOldAccount)) |
|
|
|
|
|
|
|
GetAccountAddress(strOldAccount, true); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pwalletMain->SetAddressBookName(address.Get(), strAccount); |
|
|
|
string strUsername = params[0].get_str(); |
|
|
|
|
|
|
|
|
|
|
|
return Value::null; |
|
|
|
CKeyID keyID; |
|
|
|
} |
|
|
|
if( pwalletMain->GetKeyIdFromUsername(strUsername, keyID) ) |
|
|
|
|
|
|
|
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Error: this username exists in wallet"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint256 userhash = SerializeHash(strUsername); |
|
|
|
|
|
|
|
printf("usernamehash(%s) = %s\n", strUsername.c_str(), userhash.GetHex().c_str()); |
|
|
|
|
|
|
|
|
|
|
|
Value getaccount(const Array& params, bool fHelp) |
|
|
|
CTransaction txOut; |
|
|
|
{ |
|
|
|
uint256 hashBlock; |
|
|
|
if (fHelp || params.size() != 1) |
|
|
|
if( GetTransaction(userhash, txOut, hashBlock) ) |
|
|
|
throw runtime_error( |
|
|
|
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Error: this username exists in tx database"); |
|
|
|
"getaccount <bitcoinaddress>\n" |
|
|
|
|
|
|
|
"Returns the account associated with the given address."); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CBitcoinAddress address(params[0].get_str()); |
|
|
|
// Generate a new key that is added to wallet
|
|
|
|
if (!address.IsValid()) |
|
|
|
CPubKey newKey = pwalletMain->GenerateNewKey(strUsername); |
|
|
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); |
|
|
|
keyID = newKey.GetID(); |
|
|
|
|
|
|
|
|
|
|
|
string strAccount; |
|
|
|
return CBitcoinAddress(keyID).ToString(); |
|
|
|
map<CTxDestination, string>::iterator mi = pwalletMain->mapAddressBook.find(address.Get()); |
|
|
|
|
|
|
|
if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty()) |
|
|
|
|
|
|
|
strAccount = (*mi).second; |
|
|
|
|
|
|
|
return strAccount; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Value getaddressesbyaccount(const Array& params, bool fHelp) |
|
|
|
Value listusernames(const Array& params, bool fHelp) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (fHelp || params.size() != 1) |
|
|
|
if (fHelp || params.size() != 0) |
|
|
|
throw runtime_error( |
|
|
|
throw runtime_error( |
|
|
|
"getaddressesbyaccount <account>\n" |
|
|
|
"listusernames\n" |
|
|
|
"Returns the list of addresses for the given account."); |
|
|
|
"Returns the list of usernames."); |
|
|
|
|
|
|
|
|
|
|
|
string strAccount = AccountFromValue(params[0]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Find all addresses that have the given account
|
|
|
|
// Find all addresses that have the given account
|
|
|
|
Array ret; |
|
|
|
Array ret; |
|
|
|
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) |
|
|
|
BOOST_FOREACH(const PAIRTYPE(CKeyID, CKeyMetadata)& item, pwalletMain->mapKeyMetadata) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const CBitcoinAddress& address = item.first; |
|
|
|
ret.push_back(item.second.username); |
|
|
|
const string& strName = item.second; |
|
|
|
|
|
|
|
if (strName == strAccount) |
|
|
|
|
|
|
|
ret.push_back(address.ToString()); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return ret; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|