mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-04 10:12:28 +02:00
SegWit wallet support
This introduces two command line flags (-addresstype and -changetype) which control the type of addresses/outputs created by the GUI and RPCs. Certain RPCs allow overriding these (`getnewaddress` and `getrawchangeaddress`). Supported types are "legacy" (P2PKH and P2SH-multisig), "p2sh-segwit" (P2SH-P2WPKH and P2SH-P2WSH-multisig), and "bech32" (P2WPKH and P2WSH-multisig). A few utility functions are added to the wallet to construct different address type and to add the necessary entries to the wallet file to be compatible with earlier versions (see `CWallet::LearnRelatedScripts`, `GetDestinationForKey`, `GetAllDestinationsForKey`, `CWallet::AddAndGetDestinationForScript`).
This commit is contained in:
@@ -136,14 +136,15 @@ UniValue getnewaddress(const JSONRPCRequest& request)
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
if (request.fHelp || request.params.size() > 1)
|
||||
if (request.fHelp || request.params.size() > 2)
|
||||
throw std::runtime_error(
|
||||
"getnewaddress ( \"account\" )\n"
|
||||
"getnewaddress ( \"account\" \"address_type\" )\n"
|
||||
"\nReturns a new Bitcoin address for receiving payments.\n"
|
||||
"If 'account' is specified (DEPRECATED), it is added to the address book \n"
|
||||
"so payments received with the address will be credited to 'account'.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"account\" (string, optional) DEPRECATED. The account name for the address to be linked to. If not provided, the default account \"\" is used. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created if there is no account by the given name.\n"
|
||||
"2. \"address_type\" (string, optional) The address type to use. Options are \"legacy\", \"p2sh\", and \"bech32\". Default is set by -addresstype.\n"
|
||||
"\nResult:\n"
|
||||
"\"address\" (string) The new bitcoin address\n"
|
||||
"\nExamples:\n"
|
||||
@@ -158,6 +159,14 @@ UniValue getnewaddress(const JSONRPCRequest& request)
|
||||
if (!request.params[0].isNull())
|
||||
strAccount = AccountFromValue(request.params[0]);
|
||||
|
||||
OutputType output_type = g_address_type;
|
||||
if (!request.params[1].isNull()) {
|
||||
output_type = ParseOutputType(request.params[1].get_str(), g_address_type);
|
||||
if (output_type == OUTPUT_TYPE_NONE) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[1].get_str()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!pwallet->IsLocked()) {
|
||||
pwallet->TopUpKeyPool();
|
||||
}
|
||||
@@ -167,11 +176,12 @@ UniValue getnewaddress(const JSONRPCRequest& request)
|
||||
if (!pwallet->GetKeyFromPool(newKey)) {
|
||||
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
|
||||
}
|
||||
CKeyID keyID = newKey.GetID();
|
||||
pwallet->LearnRelatedScripts(newKey, output_type);
|
||||
CTxDestination dest = GetDestinationForKey(newKey, output_type);
|
||||
|
||||
pwallet->SetAddressBook(keyID, strAccount, "receive");
|
||||
pwallet->SetAddressBook(dest, strAccount, "receive");
|
||||
|
||||
return EncodeDestination(keyID);
|
||||
return EncodeDestination(dest);
|
||||
}
|
||||
|
||||
|
||||
@@ -226,11 +236,13 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request)
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
if (request.fHelp || request.params.size() > 0)
|
||||
if (request.fHelp || request.params.size() > 1)
|
||||
throw std::runtime_error(
|
||||
"getrawchangeaddress\n"
|
||||
"getrawchangeaddress ( \"address_type\" )\n"
|
||||
"\nReturns a new Bitcoin address, for receiving change.\n"
|
||||
"This is for use with raw transactions, NOT normal use.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"address_type\" (string, optional) The address type to use. Options are \"legacy\", \"p2sh\", and \"bech32\". Default is set by -changetype.\n"
|
||||
"\nResult:\n"
|
||||
"\"address\" (string) The address\n"
|
||||
"\nExamples:\n"
|
||||
@@ -244,6 +256,14 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request)
|
||||
pwallet->TopUpKeyPool();
|
||||
}
|
||||
|
||||
OutputType output_type = g_change_type;
|
||||
if (!request.params[0].isNull()) {
|
||||
output_type = ParseOutputType(request.params[0].get_str(), g_change_type);
|
||||
if (output_type == OUTPUT_TYPE_NONE) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[0].get_str()));
|
||||
}
|
||||
}
|
||||
|
||||
CReserveKey reservekey(pwallet);
|
||||
CPubKey vchPubKey;
|
||||
if (!reservekey.GetReservedKey(vchPubKey, true))
|
||||
@@ -251,9 +271,10 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request)
|
||||
|
||||
reservekey.KeepKey();
|
||||
|
||||
CKeyID keyID = vchPubKey.GetID();
|
||||
pwallet->LearnRelatedScripts(vchPubKey, output_type);
|
||||
CTxDestination dest = GetDestinationForKey(vchPubKey, output_type);
|
||||
|
||||
return EncodeDestination(keyID);
|
||||
return EncodeDestination(dest);
|
||||
}
|
||||
|
||||
|
||||
@@ -1184,11 +1205,12 @@ UniValue addmultisigaddress(const JSONRPCRequest& request)
|
||||
|
||||
// Construct using pay-to-script-hash:
|
||||
CScript inner = _createmultisig_redeemScript(pwallet, request.params);
|
||||
CScriptID innerID(inner);
|
||||
pwallet->AddCScript(inner);
|
||||
|
||||
pwallet->SetAddressBook(innerID, strAccount, "send");
|
||||
return EncodeDestination(innerID);
|
||||
CTxDestination dest = pwallet->AddAndGetDestinationForScript(inner, g_address_type);
|
||||
|
||||
pwallet->SetAddressBook(dest, strAccount, "send");
|
||||
return EncodeDestination(dest);
|
||||
}
|
||||
|
||||
class Witnessifier : public boost::static_visitor<bool>
|
||||
@@ -3446,8 +3468,8 @@ static const CRPCCommand commands[] =
|
||||
{ "wallet", "getaccount", &getaccount, {"address"} },
|
||||
{ "wallet", "getaddressesbyaccount", &getaddressesbyaccount, {"account"} },
|
||||
{ "wallet", "getbalance", &getbalance, {"account","minconf","include_watchonly"} },
|
||||
{ "wallet", "getnewaddress", &getnewaddress, {"account"} },
|
||||
{ "wallet", "getrawchangeaddress", &getrawchangeaddress, {} },
|
||||
{ "wallet", "getnewaddress", &getnewaddress, {"account","address_type"} },
|
||||
{ "wallet", "getrawchangeaddress", &getrawchangeaddress, {"address_type"} },
|
||||
{ "wallet", "getreceivedbyaccount", &getreceivedbyaccount, {"account","minconf"} },
|
||||
{ "wallet", "getreceivedbyaddress", &getreceivedbyaddress, {"address","minconf"} },
|
||||
{ "wallet", "gettransaction", &gettransaction, {"txid","include_watchonly"} },
|
||||
|
||||
Reference in New Issue
Block a user