Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2011-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <bitcoin-build-config.h> // IWYU pragma: keep7#include <core_io.h>8#include <key_io.h>9#include <rpc/util.h>10#include <script/script.h>11#include <script/solver.h>12#include <util/bip32.h>13#include <util/translation.h>14#include <wallet/receive.h>15#include <wallet/rpc/util.h>16#include <wallet/wallet.h>18#include <univalue.h>20namespace wallet {21RPCMethod getnewaddress()22{23return RPCMethod{24"getnewaddress",25"Returns a new Bitcoin address for receiving payments.\n"26"If 'label' is specified, it is added to the address book \n"27"so payments received with the address will be associated with 'label'.\n",28{29{"label", RPCArg::Type::STR, RPCArg::Default{""}, "The label name for the address to be linked to. It can also be set to the empty string \"\" to represent the default label. The label does not need to exist, it will be created if there is no label by the given name."},30{"address_type", RPCArg::Type::STR, RPCArg::DefaultHint{"set by -addresstype"}, "The address type to use. Options are " + FormatAllOutputTypes() + "."},31},32RPCResult{33RPCResult::Type::STR, "address", "The new bitcoin address"34},35RPCExamples{36HelpExampleCli("getnewaddress", "")37+ HelpExampleRpc("getnewaddress", "")38},39[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue40{41std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);42if (!pwallet) return UniValue::VNULL;44LOCK(pwallet->cs_wallet);46if (!pwallet->CanGetAddresses()) {47throw JSONRPCError(RPC_WALLET_ERROR, "Error: This wallet has no available keys");48}50// Parse the label first so we don't generate a key if there's an error51const std::string label{LabelFromValue(request.params[0])};53OutputType output_type = pwallet->m_default_address_type;54if (!request.params[1].isNull()) {55std::optional<OutputType> parsed = ParseOutputType(request.params[1].get_str());56if (!parsed) {57throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[1].get_str()));58}59output_type = parsed.value();60}62auto op_dest = pwallet->GetNewDestination(output_type, label);63if (!op_dest) {64throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, util::ErrorString(op_dest).original);65}67return EncodeDestination(*op_dest);68},69};70}72RPCMethod getrawchangeaddress()73{74return RPCMethod{75"getrawchangeaddress",76"Returns a new Bitcoin address, for receiving change.\n"77"This is for use with raw transactions, NOT normal use.\n",78{79{"address_type", RPCArg::Type::STR, RPCArg::DefaultHint{"set by -changetype"}, "The address type to use. Options are " + FormatAllOutputTypes() + "."},80},81RPCResult{82RPCResult::Type::STR, "address", "The address"83},84RPCExamples{85HelpExampleCli("getrawchangeaddress", "")86+ HelpExampleRpc("getrawchangeaddress", "")87},88[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue89{90std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);91if (!pwallet) return UniValue::VNULL;93LOCK(pwallet->cs_wallet);95if (!pwallet->CanGetAddresses(true)) {96throw JSONRPCError(RPC_WALLET_ERROR, "Error: This wallet has no available keys");97}99OutputType output_type = pwallet->m_default_change_type.value_or(pwallet->m_default_address_type);100if (!request.params[0].isNull()) {101std::optional<OutputType> parsed = ParseOutputType(request.params[0].get_str());102if (!parsed) {103throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[0].get_str()));104}105output_type = parsed.value();106}108auto op_dest = pwallet->GetNewChangeDestination(output_type);109if (!op_dest) {110throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, util::ErrorString(op_dest).original);111}112return EncodeDestination(*op_dest);113},114};115}118RPCMethod setlabel()119{120return RPCMethod{121"setlabel",122"Sets the label associated with the given address.\n",123{124{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to be associated with a label."},125{"label", RPCArg::Type::STR, RPCArg::Optional::NO, "The label to assign to the address."},126},127RPCResult{RPCResult::Type::NONE, "", ""},128RPCExamples{129HelpExampleCli("setlabel", "\"" + EXAMPLE_ADDRESS[0] + "\" \"tabby\"")130+ HelpExampleRpc("setlabel", "\"" + EXAMPLE_ADDRESS[0] + "\", \"tabby\"")131},132[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue133{134std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);135if (!pwallet) return UniValue::VNULL;137LOCK(pwallet->cs_wallet);139CTxDestination dest = DecodeDestination(request.params[0].get_str());140if (!IsValidDestination(dest)) {141throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");142}144const std::string label{LabelFromValue(request.params[1])};146if (pwallet->IsMine(dest)) {147pwallet->SetAddressBook(dest, label, AddressPurpose::RECEIVE);148} else {149pwallet->SetAddressBook(dest, label, AddressPurpose::SEND);150}152return UniValue::VNULL;153},154};155}157RPCMethod listaddressgroupings()158{159return RPCMethod{160"listaddressgroupings",161"Lists groups of addresses which have had their common ownership\n"162"made public by common use as inputs or as the resulting change\n"163"in past transactions\n",164{},165RPCResult{166RPCResult::Type::ARR, "", "",167{168{RPCResult::Type::ARR, "", "",169{170{RPCResult::Type::ARR_FIXED, "", "",171{172{RPCResult::Type::STR, "address", "The bitcoin address"},173{RPCResult::Type::STR_AMOUNT, "amount", "The amount in " + CURRENCY_UNIT},174{RPCResult::Type::STR, "label", /*optional=*/true, "The label"},175}},176}},177}178},179RPCExamples{180HelpExampleCli("listaddressgroupings", "")181+ HelpExampleRpc("listaddressgroupings", "")182},183[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue184{185const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);186if (!pwallet) return UniValue::VNULL;188// Make sure the results are valid at least up to the most recent block189// the user could have gotten from another RPC command prior to now190pwallet->BlockUntilSyncedToCurrentChain();192LOCK(pwallet->cs_wallet);194UniValue jsonGroupings(UniValue::VARR);195std::map<CTxDestination, CAmount> balances = GetAddressBalances(*pwallet);196for (const std::set<CTxDestination>& grouping : GetAddressGroupings(*pwallet)) {197UniValue jsonGrouping(UniValue::VARR);198for (const CTxDestination& address : grouping)199{200UniValue addressInfo(UniValue::VARR);201addressInfo.push_back(EncodeDestination(address));202addressInfo.push_back(ValueFromAmount(balances[address]));203{204const auto* address_book_entry = pwallet->FindAddressBookEntry(address);205if (address_book_entry) {206addressInfo.push_back(address_book_entry->GetLabel());207}208}209jsonGrouping.push_back(std::move(addressInfo));210}211jsonGroupings.push_back(std::move(jsonGrouping));212}213return jsonGroupings;214},215};216}218RPCMethod keypoolrefill()219{220return RPCMethod{"keypoolrefill",221"Refills each descriptor keypool in the wallet up to the specified number of new keys.\n"222"By default, descriptor wallets have 4 active ranged descriptors (" + FormatAllOutputTypes() + "), each with " + util::ToString(DEFAULT_KEYPOOL_SIZE) + " entries.\n" +223HELP_REQUIRING_PASSPHRASE,224{225{"newsize", RPCArg::Type::NUM, RPCArg::DefaultHint{strprintf("%u, or as set by -keypool", DEFAULT_KEYPOOL_SIZE)}, "The new keypool size"},226},227RPCResult{RPCResult::Type::NONE, "", ""},228RPCExamples{229HelpExampleCli("keypoolrefill", "")230+ HelpExampleRpc("keypoolrefill", "")231},232[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue233{234std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);235if (!pwallet) return UniValue::VNULL;237LOCK(pwallet->cs_wallet);239// 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool240unsigned int kpSize = 0;241if (!request.params[0].isNull()) {242if (request.params[0].getInt<int>() < 0)243throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size.");244kpSize = (unsigned int)request.params[0].getInt<int>();245}247EnsureWalletIsUnlocked(*pwallet);248pwallet->TopUpKeyPool(kpSize);250if (pwallet->GetKeyPoolSize() < kpSize) {