Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/misc.cpp
Show All 27 Lines | |||||
#include <univalue.h> | #include <univalue.h> | ||||
#include <cstdint> | #include <cstdint> | ||||
#ifdef HAVE_MALLOC_INFO | #ifdef HAVE_MALLOC_INFO | ||||
#include <malloc.h> | #include <malloc.h> | ||||
#endif | #endif | ||||
class DescribeAddressVisitor : public boost::static_visitor<UniValue> { | |||||
public: | |||||
explicit DescribeAddressVisitor() {} | |||||
UniValue operator()(const CNoDestination &dest) const { | |||||
return UniValue(UniValue::VOBJ); | |||||
} | |||||
UniValue operator()(const CKeyID &keyID) const { | |||||
UniValue obj(UniValue::VOBJ); | |||||
obj.pushKV("isscript", false); | |||||
return obj; | |||||
} | |||||
UniValue operator()(const CScriptID &scriptID) const { | |||||
UniValue obj(UniValue::VOBJ); | |||||
obj.pushKV("isscript", true); | |||||
return obj; | |||||
} | |||||
}; | |||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
class DescribeWalletAddressVisitor : public boost::static_visitor<UniValue> { | class DescribeWalletAddressVisitor : public boost::static_visitor<UniValue> { | ||||
public: | public: | ||||
CWallet *const pwallet; | CWallet *const pwallet; | ||||
void ProcessSubScript(const CScript &subscript, UniValue &obj, | void ProcessSubScript(const CScript &subscript, UniValue &obj, | ||||
bool include_addresses = false) const { | bool include_addresses = false) const { | ||||
// Always present: script type and redeemscript | // Always present: script type and redeemscript | ||||
txnouttype which_type; | txnouttype which_type; | ||||
std::vector<std::vector<uint8_t>> solutions_data; | std::vector<std::vector<uint8_t>> solutions_data; | ||||
Solver(subscript, which_type, solutions_data); | Solver(subscript, which_type, solutions_data); | ||||
obj.pushKV("script", GetTxnOutputType(which_type)); | obj.pushKV("script", GetTxnOutputType(which_type)); | ||||
obj.pushKV("hex", HexStr(subscript.begin(), subscript.end())); | obj.pushKV("hex", HexStr(subscript.begin(), subscript.end())); | ||||
CTxDestination embedded; | CTxDestination embedded; | ||||
UniValue a(UniValue::VARR); | UniValue a(UniValue::VARR); | ||||
if (ExtractDestination(subscript, embedded)) { | if (ExtractDestination(subscript, embedded)) { | ||||
// Only when the script corresponds to an address. | // Only when the script corresponds to an address. | ||||
UniValue subobj(UniValue::VOBJ); | UniValue subobj(UniValue::VOBJ); | ||||
UniValue detail = | UniValue detail = DescribeAddress(embedded); | ||||
boost::apply_visitor(DescribeAddressVisitor(), embedded); | |||||
subobj.pushKVs(detail); | subobj.pushKVs(detail); | ||||
UniValue wallet_detail = boost::apply_visitor(*this, embedded); | UniValue wallet_detail = boost::apply_visitor(*this, embedded); | ||||
subobj.pushKVs(wallet_detail); | subobj.pushKVs(wallet_detail); | ||||
subobj.pushKV("address", EncodeDestination(embedded)); | subobj.pushKV("address", EncodeDestination(embedded)); | ||||
subobj.pushKV("scriptPubKey", | subobj.pushKV("scriptPubKey", | ||||
HexStr(subscript.begin(), subscript.end())); | HexStr(subscript.begin(), subscript.end())); | ||||
// Always report the pubkey at the top level, so that | // Always report the pubkey at the top level, so that | ||||
// `getnewaddress()['pubkey']` always works. | // `getnewaddress()['pubkey']` always works. | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | UniValue operator()(const CScriptID &scriptID) const { | ||||
UniValue obj(UniValue::VOBJ); | UniValue obj(UniValue::VOBJ); | ||||
CScript subscript; | CScript subscript; | ||||
if (pwallet && pwallet->GetCScript(scriptID, subscript)) { | if (pwallet && pwallet->GetCScript(scriptID, subscript)) { | ||||
ProcessSubScript(subscript, obj, true); | ProcessSubScript(subscript, obj, true); | ||||
} | } | ||||
return obj; | return obj; | ||||
} | } | ||||
}; | }; | ||||
UniValue DescribeWalletAddress(CWallet *pwallet, const CTxDestination &dest) { | |||||
UniValue ret(UniValue::VOBJ); | |||||
UniValue detail = DescribeAddress(dest); | |||||
ret.pushKVs(detail); | |||||
ret.pushKVs( | |||||
boost::apply_visitor(DescribeWalletAddressVisitor(pwallet), dest)); | |||||
return ret; | |||||
} | |||||
#endif | #endif | ||||
static UniValue validateaddress(const Config &config, | static UniValue validateaddress(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 1) { | if (request.fHelp || request.params.size() != 1) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
"validateaddress \"address\"\n" | "validateaddress \"address\"\n" | ||||
"\nReturn information about the given bitcoin address.\n" | "\nReturn information about the given bitcoin address.\n" | ||||
▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | if (isValid) { | ||||
CScript scriptPubKey = GetScriptForDestination(dest); | CScript scriptPubKey = GetScriptForDestination(dest); | ||||
ret.pushKV("scriptPubKey", | ret.pushKV("scriptPubKey", | ||||
HexStr(scriptPubKey.begin(), scriptPubKey.end())); | HexStr(scriptPubKey.begin(), scriptPubKey.end())); | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
isminetype mine = pwallet ? IsMine(*pwallet, dest) : ISMINE_NO; | isminetype mine = pwallet ? IsMine(*pwallet, dest) : ISMINE_NO; | ||||
ret.pushKV("ismine", bool(mine & ISMINE_SPENDABLE)); | ret.pushKV("ismine", bool(mine & ISMINE_SPENDABLE)); | ||||
ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY)); | ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY)); | ||||
UniValue detail = boost::apply_visitor(DescribeAddressVisitor(), dest); | UniValue detail = DescribeWalletAddress(pwallet, dest); | ||||
ret.pushKVs(detail); | ret.pushKVs(detail); | ||||
UniValue wallet_detail = | |||||
boost::apply_visitor(DescribeWalletAddressVisitor(pwallet), dest); | |||||
ret.pushKVs(wallet_detail); | |||||
if (pwallet && pwallet->mapAddressBook.count(dest)) { | if (pwallet && pwallet->mapAddressBook.count(dest)) { | ||||
ret.pushKV("account", pwallet->mapAddressBook[dest].name); | ret.pushKV("account", pwallet->mapAddressBook[dest].name); | ||||
} | } | ||||
if (pwallet) { | if (pwallet) { | ||||
const CKeyMetadata *meta = nullptr; | const CKeyMetadata *meta = nullptr; | ||||
CKeyID key_id = GetKeyForDestination(*pwallet, dest); | CKeyID key_id = GetKeyForDestination(*pwallet, dest); | ||||
if (!key_id.IsNull()) { | if (!key_id.IsNull()) { | ||||
auto it = pwallet->mapKeyMetadata.find(key_id); | auto it = pwallet->mapKeyMetadata.find(key_id); | ||||
Show All 11 Lines | #ifdef ENABLE_WALLET | ||||
if (meta) { | if (meta) { | ||||
ret.pushKV("timestamp", meta->nCreateTime); | ret.pushKV("timestamp", meta->nCreateTime); | ||||
if (!meta->hdKeypath.empty()) { | if (!meta->hdKeypath.empty()) { | ||||
ret.pushKV("hdkeypath", meta->hdKeypath); | ret.pushKV("hdkeypath", meta->hdKeypath); | ||||
ret.pushKV("hdmasterkeyid", meta->hdMasterKeyID.GetHex()); | ret.pushKV("hdmasterkeyid", meta->hdMasterKeyID.GetHex()); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
#else | |||||
ret.pushKvs = DescribeAddress(dest); | |||||
#endif | #endif | ||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
// Needed even with !ENABLE_WALLET, to pass (ignored) pointers around | // Needed even with !ENABLE_WALLET, to pass (ignored) pointers around | ||||
class CWallet; | class CWallet; | ||||
▲ Show 20 Lines • Show All 373 Lines • Show Last 20 Lines |