Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/rpcwallet.cpp
Show First 20 Lines • Show All 3,990 Lines • ▼ Show 20 Lines | response.pushKV("stop_height", result.last_scanned_height | ||||
: UniValue()); | : UniValue()); | ||||
return response; | return response; | ||||
} | } | ||||
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) const { | ||||
bool include_addresses = false) const { | |||||
// Always present: script type and redeemscript | // Always present: script type and redeemscript | ||||
std::vector<std::vector<uint8_t>> solutions_data; | std::vector<std::vector<uint8_t>> solutions_data; | ||||
txnouttype which_type = Solver(subscript, solutions_data); | txnouttype which_type = Solver(subscript, 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); | |||||
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 = DescribeAddress(embedded); | UniValue detail = DescribeAddress(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, GetConfig())); | subobj.pushKV("address", EncodeDestination(embedded, GetConfig())); | ||||
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. | ||||
if (subobj.exists("pubkey")) { | if (subobj.exists("pubkey")) { | ||||
obj.pushKV("pubkey", subobj["pubkey"]); | obj.pushKV("pubkey", subobj["pubkey"]); | ||||
} | } | ||||
obj.pushKV("embedded", std::move(subobj)); | obj.pushKV("embedded", std::move(subobj)); | ||||
if (include_addresses) { | |||||
a.push_back(EncodeDestination(embedded, GetConfig())); | |||||
} | |||||
} else if (which_type == TX_MULTISIG) { | } else if (which_type == TX_MULTISIG) { | ||||
// Also report some information on multisig scripts (which do not | // Also report some information on multisig scripts (which do not | ||||
// have a corresponding address). | // have a corresponding address). | ||||
// TODO: abstract out the common functionality between this logic | // TODO: abstract out the common functionality between this logic | ||||
// and ExtractDestinations. | // and ExtractDestinations. | ||||
obj.pushKV("sigsrequired", solutions_data[0][0]); | obj.pushKV("sigsrequired", solutions_data[0][0]); | ||||
UniValue pubkeys(UniValue::VARR); | UniValue pubkeys(UniValue::VARR); | ||||
for (size_t i = 1; i < solutions_data.size() - 1; ++i) { | for (size_t i = 1; i < solutions_data.size() - 1; ++i) { | ||||
CPubKey key(solutions_data[i].begin(), solutions_data[i].end()); | CPubKey key(solutions_data[i].begin(), solutions_data[i].end()); | ||||
if (include_addresses) { | |||||
a.push_back(EncodeDestination(key.GetID(), GetConfig())); | |||||
} | |||||
pubkeys.push_back(HexStr(key.begin(), key.end())); | pubkeys.push_back(HexStr(key.begin(), key.end())); | ||||
} | } | ||||
obj.pushKV("pubkeys", std::move(pubkeys)); | obj.pushKV("pubkeys", std::move(pubkeys)); | ||||
} | } | ||||
// The "addresses" field is confusing because it refers to public keys | |||||
// using their P2PKH address. For that reason, only add the 'addresses' | |||||
// field when needed for backward compatibility. New applications can | |||||
// use the 'pubkeys' field for inspecting multisig participants. | |||||
if (include_addresses) { | |||||
obj.pushKV("addresses", std::move(a)); | |||||
} | |||||
} | } | ||||
explicit DescribeWalletAddressVisitor(CWallet *_pwallet) | explicit DescribeWalletAddressVisitor(CWallet *_pwallet) | ||||
: pwallet(_pwallet) {} | : pwallet(_pwallet) {} | ||||
UniValue operator()(const CNoDestination &dest) const { | UniValue operator()(const CNoDestination &dest) const { | ||||
return UniValue(UniValue::VOBJ); | return UniValue(UniValue::VOBJ); | ||||
} | } | ||||
UniValue operator()(const CKeyID &keyID) const { | UniValue operator()(const CKeyID &keyID) const { | ||||
UniValue obj(UniValue::VOBJ); | UniValue obj(UniValue::VOBJ); | ||||
CPubKey vchPubKey; | CPubKey vchPubKey; | ||||
if (pwallet && pwallet->GetPubKey(keyID, vchPubKey)) { | if (pwallet && pwallet->GetPubKey(keyID, vchPubKey)) { | ||||
obj.pushKV("pubkey", HexStr(vchPubKey)); | obj.pushKV("pubkey", HexStr(vchPubKey)); | ||||
obj.pushKV("iscompressed", vchPubKey.IsCompressed()); | obj.pushKV("iscompressed", vchPubKey.IsCompressed()); | ||||
} | } | ||||
return obj; | return obj; | ||||
} | } | ||||
UniValue operator()(const CScriptID &scriptID) const { | 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); | ||||
} | } | ||||
return obj; | return obj; | ||||
} | } | ||||
}; | }; | ||||
static UniValue DescribeWalletAddress(CWallet *pwallet, | static UniValue DescribeWalletAddress(CWallet *pwallet, | ||||
const CTxDestination &dest) { | const CTxDestination &dest) { | ||||
UniValue ret(UniValue::VOBJ); | UniValue ret(UniValue::VOBJ); | ||||
▲ Show 20 Lines • Show All 735 Lines • Show Last 20 Lines |