Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/misc.cpp
Show First 20 Lines • Show All 151 Lines • ▼ Show 20 Lines | UniValue operator()(const CScriptID &scriptID) const { | ||||
txnouttype whichType; | txnouttype whichType; | ||||
int nRequired; | int nRequired; | ||||
ExtractDestinations(subscript, whichType, addresses, nRequired); | ExtractDestinations(subscript, whichType, addresses, nRequired); | ||||
obj.push_back(Pair("script", GetTxnOutputType(whichType))); | obj.push_back(Pair("script", GetTxnOutputType(whichType))); | ||||
obj.push_back( | obj.push_back( | ||||
Pair("hex", HexStr(subscript.begin(), subscript.end()))); | Pair("hex", HexStr(subscript.begin(), subscript.end()))); | ||||
UniValue a(UniValue::VARR); | UniValue a(UniValue::VARR); | ||||
for (const CTxDestination &addr : addresses) { | for (const CTxDestination &addr : addresses) { | ||||
a.push_back(CBitcoinAddress(addr).ToString()); | a.push_back(EncodeDestination(addr)); | ||||
} | } | ||||
obj.push_back(Pair("addresses", a)); | obj.push_back(Pair("addresses", a)); | ||||
if (whichType == TX_MULTISIG) | if (whichType == TX_MULTISIG) | ||||
obj.push_back(Pair("sigsrequired", nRequired)); | obj.push_back(Pair("sigsrequired", nRequired)); | ||||
} | } | ||||
return obj; | return obj; | ||||
} | } | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | if (request.fHelp || request.params.size() != 1) | ||||
"\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")); | "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")); | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : nullptr); | LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : nullptr); | ||||
#else | #else | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
#endif | #endif | ||||
CBitcoinAddress address(request.params[0].get_str()); | CTxDestination dest = DecodeDestination(request.params[0].get_str()); | ||||
bool isValid = address.IsValid(); | bool isValid = IsValidDestination(dest); | ||||
UniValue ret(UniValue::VOBJ); | UniValue ret(UniValue::VOBJ); | ||||
ret.push_back(Pair("isvalid", isValid)); | ret.push_back(Pair("isvalid", isValid)); | ||||
if (isValid) { | if (isValid) { | ||||
CTxDestination dest = address.Get(); | std::string currentAddress = EncodeDestination(dest); | ||||
std::string currentAddress = address.ToString(); | |||||
ret.push_back(Pair("address", currentAddress)); | ret.push_back(Pair("address", currentAddress)); | ||||
CScript scriptPubKey = GetScriptForDestination(dest); | CScript scriptPubKey = GetScriptForDestination(dest); | ||||
ret.push_back(Pair("scriptPubKey", | ret.push_back(Pair("scriptPubKey", | ||||
HexStr(scriptPubKey.begin(), scriptPubKey.end()))); | HexStr(scriptPubKey.begin(), scriptPubKey.end()))); | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO; | isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO; | ||||
ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false)); | ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false)); | ||||
ret.push_back( | ret.push_back( | ||||
Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true : false)); | Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true : false)); | ||||
UniValue detail = boost::apply_visitor(DescribeAddressVisitor(), dest); | UniValue detail = boost::apply_visitor(DescribeAddressVisitor(), dest); | ||||
ret.pushKVs(detail); | ret.pushKVs(detail); | ||||
if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) | if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) { | ||||
ret.push_back( | ret.push_back( | ||||
Pair("account", pwalletMain->mapAddressBook[dest].name)); | Pair("account", pwalletMain->mapAddressBook[dest].name)); | ||||
CKeyID keyID; | } | ||||
if (pwalletMain) { | if (pwalletMain) { | ||||
const auto &meta = pwalletMain->mapKeyMetadata; | const auto &meta = pwalletMain->mapKeyMetadata; | ||||
auto it = address.GetKeyID(keyID) ? meta.find(keyID) : meta.end(); | const CKeyID *keyID = boost::get<CKeyID>(&dest); | ||||
auto it = keyID ? meta.find(*keyID) : meta.end(); | |||||
if (it == meta.end()) { | if (it == meta.end()) { | ||||
it = meta.find(CScriptID(scriptPubKey)); | it = meta.find(CScriptID(scriptPubKey)); | ||||
} | } | ||||
if (it != meta.end()) { | if (it != meta.end()) { | ||||
ret.push_back(Pair("timestamp", it->second.nCreateTime)); | ret.push_back(Pair("timestamp", it->second.nCreateTime)); | ||||
if (!it->second.hdKeypath.empty()) { | if (!it->second.hdKeypath.empty()) { | ||||
ret.push_back(Pair("hdkeypath", it->second.hdKeypath)); | ret.push_back(Pair("hdkeypath", it->second.hdKeypath)); | ||||
ret.push_back(Pair("hdmasterkeyid", | ret.push_back(Pair("hdmasterkeyid", | ||||
Show All 28 Lines | if (keys.size() > 16) | ||||
"multisignature address creation > 16\nReduce the " | "multisignature address creation > 16\nReduce the " | ||||
"number"); | "number"); | ||||
std::vector<CPubKey> pubkeys; | std::vector<CPubKey> pubkeys; | ||||
pubkeys.resize(keys.size()); | pubkeys.resize(keys.size()); | ||||
for (unsigned int i = 0; i < keys.size(); i++) { | for (unsigned int i = 0; i < keys.size(); i++) { | ||||
const std::string &ks = keys[i].get_str(); | const std::string &ks = keys[i].get_str(); | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
// Case 1: Bitcoin address and we have full public key: | // Case 1: Bitcoin address and we have full public key: | ||||
CBitcoinAddress address(ks); | CTxDestination dest = DecodeDestination(ks); | ||||
if (pwalletMain && address.IsValid()) { | if (pwalletMain && IsValidDestination(dest)) { | ||||
CKeyID keyID; | const CKeyID *keyID = boost::get<CKeyID>(&dest); | ||||
if (!address.GetKeyID(keyID)) | if (!keyID) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
strprintf("%s does not refer to a key", ks)); | strprintf("%s does not refer to a key", ks)); | ||||
} | |||||
CPubKey vchPubKey; | CPubKey vchPubKey; | ||||
if (!pwalletMain->GetPubKey(keyID, vchPubKey)) | if (!pwalletMain->GetPubKey(*keyID, vchPubKey)) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
strprintf("no full public key for address %s", ks)); | strprintf("no full public key for address %s", ks)); | ||||
} | |||||
if (!vchPubKey.IsFullyValid()) | if (!vchPubKey.IsFullyValid()) | ||||
throw std::runtime_error(" Invalid public key: " + ks); | throw std::runtime_error(" Invalid public key: " + ks); | ||||
pubkeys[i] = vchPubKey; | pubkeys[i] = vchPubKey; | ||||
} | } | ||||
// Case 2: hex public key | // Case 2: hex public key | ||||
else | else | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | if (request.fHelp || request.params.size() < 2 || | ||||
"\"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\"," | "\"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\"," | ||||
"\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\""); | "\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\""); | ||||
throw std::runtime_error(msg); | throw std::runtime_error(msg); | ||||
} | } | ||||
// Construct using pay-to-script-hash: | // Construct using pay-to-script-hash: | ||||
CScript inner = createmultisig_redeemScript(request.params); | CScript inner = createmultisig_redeemScript(request.params); | ||||
CScriptID innerID(inner); | CScriptID innerID(inner); | ||||
CBitcoinAddress address(innerID); | |||||
UniValue result(UniValue::VOBJ); | UniValue result(UniValue::VOBJ); | ||||
result.push_back(Pair("address", address.ToString())); | result.push_back(Pair("address", EncodeDestination(innerID))); | ||||
result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end()))); | result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end()))); | ||||
return result; | return result; | ||||
} | } | ||||
static UniValue verifymessage(const Config &config, | static UniValue verifymessage(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 3) | if (request.fHelp || request.params.size() != 3) | ||||
Show All 26 Lines | if (request.fHelp || request.params.size() != 3) | ||||
"message\"")); | "message\"")); | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
std::string strAddress = request.params[0].get_str(); | std::string strAddress = request.params[0].get_str(); | ||||
std::string strSign = request.params[1].get_str(); | std::string strSign = request.params[1].get_str(); | ||||
std::string strMessage = request.params[2].get_str(); | std::string strMessage = request.params[2].get_str(); | ||||
CBitcoinAddress addr(strAddress); | CTxDestination destination = DecodeDestination(strAddress); | ||||
if (!addr.IsValid()) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address"); | if (!IsValidDestination(destination)) { | ||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address"); | |||||
} | |||||
CKeyID keyID; | const CKeyID *keyID = boost::get<CKeyID>(&destination); | ||||
if (!addr.GetKeyID(keyID)) | if (!keyID) { | ||||
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); | throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); | ||||
} | |||||
bool fInvalid = false; | bool fInvalid = false; | ||||
std::vector<uint8_t> vchSig = DecodeBase64(strSign.c_str(), &fInvalid); | std::vector<uint8_t> vchSig = DecodeBase64(strSign.c_str(), &fInvalid); | ||||
if (fInvalid) | if (fInvalid) | ||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | ||||
"Malformed base64 encoding"); | "Malformed base64 encoding"); | ||||
CHashWriter ss(SER_GETHASH, 0); | CHashWriter ss(SER_GETHASH, 0); | ||||
ss << strMessageMagic; | ss << strMessageMagic; | ||||
ss << strMessage; | ss << strMessage; | ||||
CPubKey pubkey; | CPubKey pubkey; | ||||
if (!pubkey.RecoverCompact(ss.GetHash(), vchSig)) return false; | if (!pubkey.RecoverCompact(ss.GetHash(), vchSig)) return false; | ||||
return (pubkey.GetID() == keyID); | return (pubkey.GetID() == *keyID); | ||||
} | } | ||||
static UniValue signmessagewithprivkey(const Config &config, | static UniValue signmessagewithprivkey(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 2) | if (request.fHelp || request.params.size() != 2) | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
"signmessagewithprivkey \"privkey\" \"message\"\n" | "signmessagewithprivkey \"privkey\" \"message\"\n" | ||||
"\nSign a message with the private key of an address\n" | "\nSign a message with the private key of an address\n" | ||||
▲ Show 20 Lines • Show All 151 Lines • Show Last 20 Lines |