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.
1// Copyright (c) 2016-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 <wallet/wallettool.h>7#include <common/args.h>8#include <util/check.h>9#include <util/fs.h>10#include <util/translation.h>11#include <wallet/dump.h>12#include <wallet/wallet.h>13#include <wallet/walletutil.h>15namespace wallet {16namespace WalletTool {18// The standard wallet deleter function blocks on the validation interface19// queue, which doesn't exist for the bitcoin-wallet. Define our own20// deleter here.21static void WalletToolReleaseWallet(CWallet* wallet)22{23wallet->WalletLogPrintf("Releasing wallet\n");24wallet->Close();25delete wallet;26}28static void WalletCreate(CWallet* wallet_instance, uint64_t wallet_creation_flags)29{30LOCK(wallet_instance->cs_wallet);32wallet_instance->InitWalletFlags(wallet_creation_flags);34Assert(wallet_instance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));35wallet_instance->SetupDescriptorScriptPubKeyMans();37tfm::format(std::cout, "Topping up keypool...\n");38wallet_instance->TopUpKeyPool();39}41static std::shared_ptr<CWallet> MakeWallet(const std::string& name, const fs::path& path, DatabaseOptions options)42{43DatabaseStatus status;44bilingual_str error;45std::vector<bilingual_str> warnings;46std::unique_ptr<WalletDatabase> database = MakeDatabase(path, options, status, error);47if (!database) {48tfm::format(std::cerr, "%s\n", error.original);49return nullptr;50}52// dummy chain interface53std::shared_ptr<CWallet> wallet_instance{new CWallet(/*chain=*/nullptr, name, std::move(database)), WalletToolReleaseWallet};54DBErrors load_wallet_ret;55try {56load_wallet_ret = wallet_instance->PopulateWalletFromDB(error, warnings);57} catch (const std::runtime_error&) {58tfm::format(std::cerr, "Error loading %s. Is wallet being used by another process?\n", name);59return nullptr;60}62if (!error.empty()) {63tfm::format(std::cerr, "%s", error.original);64}66for (const auto &warning : warnings) {67tfm::format(std::cerr, "%s", warning.original);68}70if (load_wallet_ret != DBErrors::LOAD_OK && load_wallet_ret != DBErrors::NONCRITICAL_ERROR && load_wallet_ret != DBErrors::NEED_RESCAN) {71return nullptr;72}74if (options.require_create) WalletCreate(wallet_instance.get(), options.create_flags);76return wallet_instance;77}79static void WalletShowInfo(CWallet* wallet_instance)80{81LOCK(wallet_instance->cs_wallet);83tfm::format(std::cout, "Wallet info\n===========\n");84tfm::format(std::cout, "Name: %s\n", wallet_instance->GetName());85tfm::format(std::cout, "Format: %s\n", wallet_instance->GetDatabase().Format());86tfm::format(std::cout, "Descriptors: %s\n", wallet_instance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS) ? "yes" : "no");87tfm::format(std::cout, "Encrypted: %s\n", wallet_instance->HasEncryptionKeys() ? "yes" : "no");88tfm::format(std::cout, "HD (hd seed available): %s\n", wallet_instance->IsHDEnabled() ? "yes" : "no");89tfm::format(std::cout, "Keypool Size: %u\n", wallet_instance->GetKeyPoolSize());90tfm::format(std::cout, "Transactions: %zu\n", wallet_instance->mapWallet.size());91tfm::format(std::cout, "Address Book: %zu\n", wallet_instance->m_address_book.size());92}94bool ExecuteWalletToolFunc(const ArgsManager& args, const std::string& command)95{96{97std::vector<std::string> details;98if (!args.CheckCommandOptions(command, &details)) {99tfm::format(std::cerr, "Error: Invalid arguments provided:\n%s\n", util::MakeUnorderedList(details));100return false;101}102}103if ((command == "create" || command == "createfromdump") && !args.IsArgSet("-wallet")) {104tfm::format(std::cerr, "Wallet name must be provided when creating a new wallet.\n");105return false;106}107const std::string name = args.GetArg("-wallet", "");108util::Result<fs::path> path_res = GetWalletPath(name);109if (!path_res) {110tfm::format(std::cerr, "%s\n", util::ErrorString(path_res).original);111return false;112}113const fs::path& path = *path_res;115if (command == "create") {116if (name.empty()) {117tfm::format(std::cerr, "Wallet name cannot be empty\n");118return false;119}120DatabaseOptions options;121ReadDatabaseArgs(args, options);122options.require_create = true;123options.create_flags |= WALLET_FLAG_DESCRIPTORS;124options.require_format = DatabaseFormat::SQLITE;126const std::shared_ptr<CWallet> wallet_instance = MakeWallet(name, path, options);127if (wallet_instance) {128WalletShowInfo(wallet_instance.get());129wallet_instance->Close();130}131} else if (command == "info") {132DatabaseOptions options;133ReadDatabaseArgs(args, options);134options.require_existing = true;135const std::shared_ptr<CWallet> wallet_instance = MakeWallet(name, path, options);136if (!wallet_instance) return false;137WalletShowInfo(wallet_instance.get());138wallet_instance->Close();139} else if (command == "dump") {140DatabaseOptions options;141ReadDatabaseArgs(args, options);142options.require_existing = true;143DatabaseStatus status;145if (IsBDBFile(BDBDataFile(path))) {146options.require_format = DatabaseFormat::BERKELEY_RO;147}149bilingual_str error;150std::unique_ptr<WalletDatabase> database = MakeDatabase(path, options, status, error);151if (!database) {152tfm::format(std::cerr, "%s\n", error.original);153return false;154}156bool ret = DumpWallet(args, *database, error);157if (!ret && !error.empty()) {158tfm::format(std::cerr, "%s\n", error.original);159return ret;160}161tfm::format(std::cout, "The dumpfile may contain private keys. To ensure the safety of your Bitcoin, do not share the dumpfile.\n");162return ret;163} else if (command == "createfromdump") {164bilingual_str error;165bool ret = CreateFromDump(args, name, path, error);166if (!ret && !error.empty()) {167tfm::format(std::cerr, "%s\n", error.original);168}169return ret;170} else {171tfm::format(std::cerr, "Invalid command: %s\n", command);172return false;173}175return true;176}177} // namespace WalletTool178} // namespace wallet