Inside Bitcoin
Opening the selected file…
Inside Bitcoin
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.
251}252throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Descriptor does not have a corresponding address");253}255addresses.push_back(EncodeDestination(dest));256}257}259// This should not be possible, but an assert seems overkill:260if (addresses.empty()) {261throw JSONRPCError(RPC_MISC_ERROR, "Unexpected empty result");262}264return addresses;265}267static RPCMethod deriveaddresses()268{269const std::string EXAMPLE_DESCRIPTOR = "wpkh([d34db33f/84h/0h/0h]xpub6DJ2dNUysrn5Vt36jH2KLBT2i1auw1tTSSomg8PhqNiUtx8QX2SvC9nrHu81fT41fvDUnhMjEzQgXnQjKEu3oaqMSzhSrHMxyyoEAmUHQbY/0/*)#cjjspncu";271return RPCMethod{272"deriveaddresses",273"Derives one or more addresses corresponding to an output descriptor.\n"274"Examples of output descriptors are:\n"275" pkh(<pubkey>) P2PKH outputs for the given pubkey\n"276" wpkh(<pubkey>) Native segwit P2PKH outputs for the given pubkey\n"277" sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig outputs for the given threshold and pubkeys\n"278" raw(<hex script>) Outputs whose output script equals the specified hex-encoded bytes\n"279" tr(<pubkey>,multi_a(<n>,<pubkey>,<pubkey>,...)) P2TR-multisig outputs for the given threshold and pubkeys\n"280"\nIn the above, <pubkey> either refers to a fixed public key in hexadecimal notation, or to an xpub/xprv optionally followed by one\n"281"or more path elements separated by \"/\", where \"h\" represents a hardened child key.\n"282"For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n",283{284{"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor."},285{"range", RPCArg::Type::RANGE, RPCArg::Optional::OMITTED, "If a ranged descriptor is used, this specifies the end or the range (in [begin,end] notation) to derive."},286},287{288RPCResult{"for single derivation descriptors",289RPCResult::Type::ARR, "", "",290{291{RPCResult::Type::STR, "address", "the derived addresses"},292}293},294RPCResult{"for multipath descriptors",295RPCResult::Type::ARR, "", "The derived addresses for each of the multipath expansions of the descriptor, in multipath specifier order",296{297{298RPCResult::Type::ARR, "", "The derived addresses for a multipath descriptor expansion",299{300{RPCResult::Type::STR, "address", "the derived address"},301},302},303},304},305},306RPCExamples{307"First three native segwit receive addresses\n" +308HelpExampleCli("deriveaddresses", "\"" + EXAMPLE_DESCRIPTOR + "\" \"[0,2]\"") +309HelpExampleRpc("deriveaddresses", "\"" + EXAMPLE_DESCRIPTOR + "\", \"[0,2]\"")310},311[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue312{313auto desc_str{self.Arg<std::string_view>("descriptor")};315int64_t range_begin = 0;316int64_t range_end = 0;318const UniValue* range = self.MaybeArg<UniValue>("range");319if (range) {320std::tie(range_begin, range_end) = ParseDescriptorRange(*range);321}323FlatSigningProvider key_provider;324std::string error;325auto descs = Parse(desc_str, key_provider, error, /* require_checksum = */ true);326if (descs.empty()) {327throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error);328}329auto& desc = descs.at(0);330if (!desc->IsRange() && range) {331throw JSONRPCError(RPC_INVALID_PARAMETER, "Range should not be specified for an un-ranged descriptor");332}334if (desc->IsRange() && !range) {335throw JSONRPCError(RPC_INVALID_PARAMETER, "Range must be specified for a ranged descriptor");336}338UniValue addresses = DeriveAddresses(desc.get(), range_begin, range_end, key_provider);340if (descs.size() == 1) {341return addresses;342}344UniValue ret(UniValue::VARR);345ret.push_back(addresses);346for (size_t i = 1; i < descs.size(); ++i) {347ret.push_back(DeriveAddresses(descs.at(i).get(), range_begin, range_end, key_provider));348}349return ret;350},351};352}354void RegisterOutputScriptRPCCommands(CRPCTable& t)355{356static const CRPCCommand commands[]{357{"util", &validateaddress},358{"util", &createmultisig},359{"util", &deriveaddresses},360{"util", &getdescriptorinfo},361};362for (const auto& c : commands) {363t.appendCommand(c.name, &c);364}365}