Add CashAddr Address Format
Ported from Bitcoin Unlimited, Bitcoin ABC
This commit is contained in:
@@ -4,9 +4,9 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "amount.h"
|
||||
#include "base58.h"
|
||||
#include "chain.h"
|
||||
#include "core_io.h"
|
||||
#include "dstencode.h"
|
||||
#include "init.h"
|
||||
#include "main.h"
|
||||
#include "net.h"
|
||||
@@ -167,18 +167,17 @@ UniValue getnewaddress(const UniValue& params, bool fHelp)
|
||||
|
||||
pwalletMain->SetAddressBook(keyID, strAccount, "receive");
|
||||
|
||||
return CBitcoinAddress(keyID).ToString();
|
||||
return EncodeDestination(keyID);
|
||||
}
|
||||
|
||||
|
||||
CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
|
||||
CTxDestination GetAccountAddress(string strAccount, bool bForceNew=false)
|
||||
{
|
||||
CPubKey pubKey;
|
||||
if (!pwalletMain->GetAccountPubkey(pubKey, strAccount, bForceNew)) {
|
||||
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
|
||||
}
|
||||
|
||||
return CBitcoinAddress(pubKey.GetID());
|
||||
return pubKey.GetID();
|
||||
}
|
||||
|
||||
UniValue getaccountaddress(const UniValue& params, bool fHelp)
|
||||
@@ -208,7 +207,7 @@ UniValue getaccountaddress(const UniValue& params, bool fHelp)
|
||||
|
||||
UniValue ret(UniValue::VSTR);
|
||||
|
||||
ret = GetAccountAddress(strAccount).ToString();
|
||||
ret = EncodeDestination(GetAccountAddress(strAccount));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -244,10 +243,9 @@ UniValue getrawchangeaddress(const UniValue& params, bool fHelp)
|
||||
|
||||
CKeyID keyID = vchPubKey.GetID();
|
||||
|
||||
return CBitcoinAddress(keyID).ToString();
|
||||
return EncodeDestination(keyID);
|
||||
}
|
||||
|
||||
|
||||
UniValue setaccount(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
@@ -267,25 +265,28 @@ UniValue setaccount(const UniValue& params, bool fHelp)
|
||||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
CBitcoinAddress address(params[0].get_str());
|
||||
if (!address.IsValid())
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
|
||||
CTxDestination dest = DecodeDestination(params[0].get_str());
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
|
||||
"Invalid Bitcoin address");
|
||||
}
|
||||
|
||||
string strAccount;
|
||||
if (params.size() > 1)
|
||||
strAccount = AccountFromValue(params[1]);
|
||||
|
||||
// Only add the account if the address is yours.
|
||||
if (IsMine(*pwalletMain, address.Get()))
|
||||
if (IsMine(*pwalletMain, dest))
|
||||
{
|
||||
// Detect when changing the account of an address that is the 'unused current key' of another account:
|
||||
if (pwalletMain->mapAddressBook.count(address.Get()))
|
||||
// Detect when changing the account of an address that is the 'unused
|
||||
// current key' of another account:
|
||||
if (pwalletMain->mapAddressBook.count(dest))
|
||||
{
|
||||
string strOldAccount = pwalletMain->mapAddressBook[address.Get()].name;
|
||||
if (address == GetAccountAddress(strOldAccount))
|
||||
std::string strOldAccount = pwalletMain->mapAddressBook[dest].name;
|
||||
if (dest == GetAccountAddress(strOldAccount))
|
||||
GetAccountAddress(strOldAccount, true);
|
||||
}
|
||||
pwalletMain->SetAddressBook(address.Get(), strAccount, "receive");
|
||||
pwalletMain->SetAddressBook(dest, strAccount, "receive");
|
||||
}
|
||||
else
|
||||
throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address");
|
||||
@@ -293,7 +294,6 @@ UniValue setaccount(const UniValue& params, bool fHelp)
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
|
||||
UniValue getaccount(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
@@ -314,18 +314,21 @@ UniValue getaccount(const UniValue& params, bool fHelp)
|
||||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
CBitcoinAddress address(params[0].get_str());
|
||||
if (!address.IsValid())
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
|
||||
CTxDestination dest = DecodeDestination(params[0].get_str());
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
|
||||
"Invalid Bitcoin address");
|
||||
}
|
||||
|
||||
string strAccount;
|
||||
map<CTxDestination, CAddressBookData>::iterator mi = pwalletMain->mapAddressBook.find(address.Get());
|
||||
if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.name.empty())
|
||||
std::string strAccount;
|
||||
std::map<CTxDestination, CAddressBookData>::iterator mi =
|
||||
pwalletMain->mapAddressBook.find(dest);
|
||||
if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.name.empty()) {
|
||||
strAccount = (*mi).second.name;
|
||||
}
|
||||
return strAccount;
|
||||
}
|
||||
|
||||
|
||||
UniValue getaddressesbyaccount(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
@@ -353,12 +356,13 @@ UniValue getaddressesbyaccount(const UniValue& params, bool fHelp)
|
||||
|
||||
// Find all addresses that have the given account
|
||||
UniValue ret(UniValue::VARR);
|
||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook)
|
||||
{
|
||||
const CBitcoinAddress& address = item.first;
|
||||
const string& strName = item.second.name;
|
||||
if (strName == strAccount)
|
||||
ret.push_back(address.ToString());
|
||||
for (const std::pair<CTxDestination, CAddressBookData> &item :
|
||||
pwalletMain->mapAddressBook) {
|
||||
const CTxDestination &dest = item.first;
|
||||
const std::string &strName = item.second.name;
|
||||
if (strName == strAccount) {
|
||||
ret.push_back(EncodeDestination(dest));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -427,9 +431,10 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp)
|
||||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
CBitcoinAddress address(params[0].get_str());
|
||||
if (!address.IsValid())
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
|
||||
CTxDestination dest = DecodeDestination(params[0].get_str());
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
|
||||
}
|
||||
|
||||
// Amount
|
||||
CAmount nAmount = AmountFromValue(params[1]);
|
||||
@@ -449,7 +454,7 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp)
|
||||
|
||||
EnsureWalletIsUnlocked();
|
||||
|
||||
SendMoney(address.Get(), nAmount, fSubtractFeeFromAmount, wtx);
|
||||
SendMoney(dest, nAmount, fSubtractFeeFromAmount, wtx);
|
||||
|
||||
return wtx.GetHash().GetHex();
|
||||
}
|
||||
@@ -485,18 +490,20 @@ UniValue listaddressgroupings(const UniValue& params, bool fHelp)
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
UniValue jsonGroupings(UniValue::VARR);
|
||||
map<CTxDestination, CAmount> balances = pwalletMain->GetAddressBalances();
|
||||
BOOST_FOREACH(set<CTxDestination> grouping, pwalletMain->GetAddressGroupings())
|
||||
{
|
||||
std::map<CTxDestination, CAmount> balances =
|
||||
pwalletMain->GetAddressBalances();
|
||||
for (const std::set<CTxDestination> &grouping :
|
||||
pwalletMain->GetAddressGroupings()) {
|
||||
UniValue jsonGrouping(UniValue::VARR);
|
||||
BOOST_FOREACH(CTxDestination address, grouping)
|
||||
{
|
||||
for (const CTxDestination &address : grouping) {
|
||||
UniValue addressInfo(UniValue::VARR);
|
||||
addressInfo.push_back(CBitcoinAddress(address).ToString());
|
||||
addressInfo.push_back(EncodeDestination(address));
|
||||
addressInfo.push_back(ValueFromAmount(balances[address]));
|
||||
{
|
||||
if (pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwalletMain->mapAddressBook.end())
|
||||
addressInfo.push_back(pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get())->second.name);
|
||||
|
||||
if (pwalletMain->mapAddressBook.find(address) !=
|
||||
pwalletMain->mapAddressBook.end()) {
|
||||
addressInfo.push_back(
|
||||
pwalletMain->mapAddressBook.find(address)->second.name);
|
||||
}
|
||||
jsonGrouping.push_back(addressInfo);
|
||||
}
|
||||
@@ -538,16 +545,16 @@ UniValue signmessage(const UniValue& params, bool fHelp)
|
||||
string strAddress = params[0].get_str();
|
||||
string strMessage = params[1].get_str();
|
||||
|
||||
CBitcoinAddress addr(strAddress);
|
||||
if (!addr.IsValid())
|
||||
CTxDestination dest = DecodeDestination(strAddress);
|
||||
if (!IsValidDestination(dest))
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
|
||||
|
||||
CKeyID keyID;
|
||||
if (!addr.GetKeyID(keyID))
|
||||
const CKeyID *keyID = boost::get<CKeyID>(&dest);
|
||||
if (!keyID)
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
|
||||
|
||||
CKey key;
|
||||
if (!pwalletMain->GetKey(keyID, key))
|
||||
if (!pwalletMain->GetKey(*keyID, key))
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available");
|
||||
|
||||
CHashWriter ss(SER_GETHASH, 0);
|
||||
@@ -589,10 +596,11 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp)
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
// Bitcoin address
|
||||
CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
|
||||
if (!address.IsValid())
|
||||
CTxDestination dest = DecodeDestination(params[0].get_str());
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
|
||||
CScript scriptPubKey = GetScriptForDestination(address.Get());
|
||||
}
|
||||
CScript scriptPubKey = GetScriptForDestination(dest);
|
||||
if (!IsMine(*pwalletMain, scriptPubKey))
|
||||
return ValueFromAmount(0);
|
||||
|
||||
@@ -609,7 +617,7 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp)
|
||||
if (wtx.IsCoinBase() || !CheckFinalTx(wtx))
|
||||
continue;
|
||||
|
||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||
for (const CTxOut &txout : wtx.vout)
|
||||
if (txout.scriptPubKey == scriptPubKey)
|
||||
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
||||
nAmount += txout.nValue;
|
||||
@@ -618,7 +626,6 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp)
|
||||
return ValueFromAmount(nAmount);
|
||||
}
|
||||
|
||||
|
||||
UniValue getreceivedbyaccount(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
@@ -853,10 +860,12 @@ UniValue sendfrom(const UniValue& params, bool fHelp)
|
||||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
string strAccount = AccountFromValue(params[0]);
|
||||
CBitcoinAddress address(params[1].get_str());
|
||||
if (!address.IsValid())
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
|
||||
std::string strAccount = AccountFromValue(params[0]);
|
||||
CTxDestination dest = DecodeDestination(params[1].get_str());
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
|
||||
"Invalid Bitcoin address");
|
||||
}
|
||||
CAmount nAmount = AmountFromValue(params[2]);
|
||||
if (nAmount <= 0)
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
|
||||
@@ -878,7 +887,7 @@ UniValue sendfrom(const UniValue& params, bool fHelp)
|
||||
if (nAmount > nBalance)
|
||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
|
||||
|
||||
SendMoney(address.Get(), nAmount, false, wtx);
|
||||
SendMoney(dest, nAmount, false, wtx);
|
||||
|
||||
return wtx.GetHash().GetHex();
|
||||
}
|
||||
@@ -942,22 +951,27 @@ UniValue sendmany(const UniValue& params, bool fHelp)
|
||||
if (params.size() > 4)
|
||||
subtractFeeFromAmount = params[4].get_array();
|
||||
|
||||
set<CBitcoinAddress> setAddress;
|
||||
vector<CRecipient> vecSend;
|
||||
std::set<CTxDestination> destinations;
|
||||
std::vector<CRecipient> vecSend;
|
||||
|
||||
CAmount totalAmount = 0;
|
||||
vector<string> keys = sendTo.getKeys();
|
||||
BOOST_FOREACH(const string& name_, keys)
|
||||
{
|
||||
CBitcoinAddress address(name_);
|
||||
if (!address.IsValid())
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+name_);
|
||||
std::vector<std::string> keys = sendTo.getKeys();
|
||||
for (const std::string &name_ : keys) {
|
||||
CTxDestination dest = DecodeDestination(name_);
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,
|
||||
std::string("Invalid Bitcoin address: ") +
|
||||
name_);
|
||||
}
|
||||
|
||||
if (setAddress.count(address))
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_);
|
||||
setAddress.insert(address);
|
||||
if (destinations.count(dest)) {
|
||||
throw JSONRPCError(
|
||||
RPC_INVALID_PARAMETER,
|
||||
std::string("Invalid parameter, duplicated address: ") + name_);
|
||||
}
|
||||
destinations.insert(dest);
|
||||
|
||||
CScript scriptPubKey = GetScriptForDestination(address.Get());
|
||||
CScript scriptPubKey = GetScriptForDestination(dest);
|
||||
CAmount nAmount = AmountFromValue(sendTo[name_]);
|
||||
if (nAmount <= 0)
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
|
||||
@@ -1043,7 +1057,7 @@ UniValue addmultisigaddress(const UniValue& params, bool fHelp)
|
||||
pwalletMain->AddCScript(inner);
|
||||
|
||||
pwalletMain->SetAddressBook(innerID, strAccount, "send");
|
||||
return CBitcoinAddress(innerID).ToString();
|
||||
return EncodeDestination(innerID);
|
||||
}
|
||||
|
||||
|
||||
@@ -1079,11 +1093,13 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
|
||||
filter = filter | ISMINE_WATCH_ONLY;
|
||||
|
||||
// Tally
|
||||
map<CBitcoinAddress, tallyitem> mapTally;
|
||||
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
|
||||
std::map<CTxDestination, tallyitem> mapTally;
|
||||
for (std::map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
|
||||
it != pwalletMain->mapWallet.end(); ++it)
|
||||
{
|
||||
const CWalletTx& wtx = (*it).second;
|
||||
const CWalletTx &wtx = (*it).second;
|
||||
|
||||
// CValidationState state;
|
||||
if (wtx.IsCoinBase() || !CheckFinalTx(wtx))
|
||||
continue;
|
||||
|
||||
@@ -1091,7 +1107,7 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
|
||||
if (nDepth < nMinDepth)
|
||||
continue;
|
||||
|
||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||
for (const CTxOut &txout : wtx.vout)
|
||||
{
|
||||
CTxDestination address;
|
||||
if (!ExtractDestination(txout.scriptPubKey, address))
|
||||
@@ -1112,12 +1128,12 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
|
||||
|
||||
// Reply
|
||||
UniValue ret(UniValue::VARR);
|
||||
map<string, tallyitem> mapAccountTally;
|
||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook)
|
||||
std::map<std::string, tallyitem> mapAccountTally;
|
||||
for (const std::pair<CTxDestination, CAddressBookData> &item : pwalletMain->mapAddressBook)
|
||||
{
|
||||
const CBitcoinAddress& address = item.first;
|
||||
const string& strAccount = item.second.name;
|
||||
map<CBitcoinAddress, tallyitem>::iterator it = mapTally.find(address);
|
||||
const CTxDestination &dest = item.first;
|
||||
const std::string &strAccount = item.second.name;
|
||||
std::map<CTxDestination, tallyitem>::iterator it = mapTally.find(dest);
|
||||
if (it == mapTally.end() && !fIncludeEmpty)
|
||||
continue;
|
||||
|
||||
@@ -1142,17 +1158,23 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
if(fIsWatchonly)
|
||||
{
|
||||
obj.push_back(Pair("involvesWatchonly", true));
|
||||
obj.push_back(Pair("address", address.ToString()));
|
||||
obj.push_back(Pair("account", strAccount));
|
||||
obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
|
||||
obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
|
||||
}
|
||||
obj.push_back(Pair("address", EncodeDestination(dest)));
|
||||
obj.push_back(Pair("account", strAccount));
|
||||
obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
|
||||
obj.push_back(
|
||||
Pair("confirmations",
|
||||
(nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
|
||||
if (!fByAccounts)
|
||||
{
|
||||
obj.push_back(Pair("label", strAccount));
|
||||
}
|
||||
UniValue transactions(UniValue::VARR);
|
||||
if (it != mapTally.end())
|
||||
{
|
||||
BOOST_FOREACH(const uint256& item, (*it).second.txids)
|
||||
for (const uint256 &item : (*it).second.txids)
|
||||
{
|
||||
transactions.push_back(item.GetHex());
|
||||
}
|
||||
@@ -1258,11 +1280,10 @@ UniValue listreceivedbyaccount(const UniValue& params, bool fHelp)
|
||||
return ListReceived(params, true);
|
||||
}
|
||||
|
||||
static void MaybePushAddress(UniValue & entry, const CTxDestination &dest)
|
||||
{
|
||||
CBitcoinAddress addr;
|
||||
if (addr.Set(dest))
|
||||
entry.push_back(Pair("address", addr.ToString()));
|
||||
static void MaybePushAddress(UniValue &entry, const CTxDestination &dest) {
|
||||
if (IsValidDestination(dest)) {
|
||||
entry.push_back(Pair("address", EncodeDestination(dest)));
|
||||
}
|
||||
}
|
||||
|
||||
void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter)
|
||||
@@ -2357,17 +2378,17 @@ UniValue listunspent(const UniValue& params, bool fHelp)
|
||||
if (params.size() > 1)
|
||||
nMaxDepth = params[1].get_int();
|
||||
|
||||
set<CBitcoinAddress> setAddress;
|
||||
set<CTxDestination> destinations;
|
||||
if (params.size() > 2) {
|
||||
UniValue inputs = params[2].get_array();
|
||||
for (unsigned int idx = 0; idx < inputs.size(); idx++) {
|
||||
const UniValue& input = inputs[idx];
|
||||
CBitcoinAddress address(input.get_str());
|
||||
if (!address.IsValid())
|
||||
CTxDestination address = DecodeDestination(input.get_str());
|
||||
if (!IsValidDestination(address))
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+input.get_str());
|
||||
if (setAddress.count(address))
|
||||
if (destinations.count(address))
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str());
|
||||
setAddress.insert(address);
|
||||
destinations.insert(address);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2384,7 +2405,7 @@ UniValue listunspent(const UniValue& params, bool fHelp)
|
||||
const CScript& scriptPubKey = out.tx->vout[out.i].scriptPubKey;
|
||||
bool fValidAddress = ExtractDestination(scriptPubKey, address);
|
||||
|
||||
if (setAddress.size() && (!fValidAddress || !setAddress.count(address)))
|
||||
if (destinations.size() && (!fValidAddress || !destinations.count(address)))
|
||||
continue;
|
||||
|
||||
UniValue entry(UniValue::VOBJ);
|
||||
@@ -2392,7 +2413,7 @@ UniValue listunspent(const UniValue& params, bool fHelp)
|
||||
entry.push_back(Pair("vout", out.i));
|
||||
|
||||
if (fValidAddress) {
|
||||
entry.push_back(Pair("address", CBitcoinAddress(address).ToString()));
|
||||
entry.push_back(Pair("address", EncodeDestination(address)));
|
||||
|
||||
if (pwalletMain->mapAddressBook.count(address))
|
||||
entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name));
|
||||
@@ -2476,7 +2497,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
|
||||
// backward compatibility bool only fallback
|
||||
includeWatching = params[1].get_bool();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VOBJ));
|
||||
|
||||
UniValue options = params[1];
|
||||
@@ -2492,12 +2513,13 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
|
||||
true, true);
|
||||
|
||||
if (options.exists("changeAddress")) {
|
||||
CBitcoinAddress address(options["changeAddress"].get_str());
|
||||
CTxDestination dest =
|
||||
DecodeDestination(options["changeAddress"].get_str());
|
||||
|
||||
if (!address.IsValid())
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "changeAddress must be a valid bitcoin address");
|
||||
|
||||
changeAddress = address.Get();
|
||||
changeAddress = dest;
|
||||
}
|
||||
|
||||
if (options.exists("changePosition"))
|
||||
|
||||
Reference in New Issue
Block a user