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 <core_io.h>6#include <hash.h>7#include <key_io.h>8#include <rpc/util.h>9#include <script/script.h>10#include <util/moneystr.h>11#include <wallet/coincontrol.h>12#include <wallet/receive.h>13#include <wallet/rpc/util.h>14#include <wallet/spend.h>15#include <wallet/wallet.h>17#include <univalue.h>20namespace wallet {21static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)22{23std::vector<CTxDestination> addresses;24if (by_label) {25// Get the set of addresses assigned to label26addresses = wallet.ListAddrBookAddresses(CWallet::AddrBookFilter{LabelFromValue(params[0])});27if (addresses.empty()) throw JSONRPCError(RPC_WALLET_ERROR, "Label not found in wallet");28} else {29// Get the address30CTxDestination dest = DecodeDestination(params[0].get_str());31if (!IsValidDestination(dest)) {32throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");33}34addresses.emplace_back(dest);35}37// Filter by own scripts only38std::set<CScript> output_scripts;39for (const auto& address : addresses) {40auto output_script{GetScriptForDestination(address)};41if (wallet.IsMine(output_script)) {42output_scripts.insert(output_script);43}44}46if (output_scripts.empty()) {47throw JSONRPCError(RPC_WALLET_ERROR, "Address not found in wallet");48}50// Minimum confirmations51int min_depth = 1;52if (!params[1].isNull())53min_depth = params[1].getInt<int>();55const bool include_immature_coinbase{params[2].isNull() ? false : params[2].get_bool()};57// Tally58CAmount amount = 0;59for (const auto& [_, wtx] : wallet.mapWallet) {60int depth{wallet.GetTxDepthInMainChain(wtx)};61if (depth < min_depth62// Coinbase with less than 1 confirmation is no longer in the main chain63|| (wtx.IsCoinBase() && (depth < 1))64|| (wallet.IsTxImmatureCoinBase(wtx) && !include_immature_coinbase))65{66continue;67}69for (const CTxOut& txout : wtx.GetTx()->vout) {70if (output_scripts.contains(txout.scriptPubKey)) {71amount += txout.nValue;72}73}74}76return amount;77}80RPCMethod getreceivedbyaddress()81{82return RPCMethod{83"getreceivedbyaddress",84"Returns the total amount received by the given address in transactions with at least minconf confirmations.\n",85{86{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address for transactions."},87{"minconf", RPCArg::Type::NUM, RPCArg::Default{1}, "Only include transactions confirmed at least this many times."},88{"include_immature_coinbase", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include immature coinbase transactions."},89},90RPCResult{91RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " received at this address."92},93RPCExamples{94"\nThe amount from transactions with at least 1 confirmation\n"95+ HelpExampleCli("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\"") +96"\nThe amount including unconfirmed transactions, zero confirmations\n"97+ HelpExampleCli("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0") +98"\nThe amount with at least 6 confirmations\n"99+ HelpExampleCli("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 6") +100"\nThe amount with at least 6 confirmations including immature coinbase outputs\n"101+ HelpExampleCli("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 6 true") +102"\nAs a JSON-RPC call\n"103+ HelpExampleRpc("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\", 6")104},105[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue106{107const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);108if (!pwallet) return UniValue::VNULL;110// Make sure the results are valid at least up to the most recent block111// the user could have gotten from another RPC command prior to now112pwallet->BlockUntilSyncedToCurrentChain();114LOCK(pwallet->cs_wallet);116return ValueFromAmount(GetReceived(*pwallet, request.params, /*by_label=*/false));117},118};119}122RPCMethod getreceivedbylabel()123{124return RPCMethod{125"getreceivedbylabel",126"Returns the total amount received by addresses with <label> in transactions with at least [minconf] confirmations.\n",127{128{"label", RPCArg::Type::STR, RPCArg::Optional::NO, "The selected label, may be the default label using \"\"."},129{"minconf", RPCArg::Type::NUM, RPCArg::Default{1}, "Only include transactions confirmed at least this many times."},130{"include_immature_coinbase", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include immature coinbase transactions."},131},132RPCResult{133RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " received for this label."134},135RPCExamples{136"\nAmount received by the default label with at least 1 confirmation\n"137+ HelpExampleCli("getreceivedbylabel", "\"\"") +138"\nAmount received at the tabby label including unconfirmed amounts with zero confirmations\n"139+ HelpExampleCli("getreceivedbylabel", "\"tabby\" 0") +140"\nThe amount with at least 6 confirmations\n"141+ HelpExampleCli("getreceivedbylabel", "\"tabby\" 6") +142"\nThe amount with at least 6 confirmations including immature coinbase outputs\n"143+ HelpExampleCli("getreceivedbylabel", "\"tabby\" 6 true") +144"\nAs a JSON-RPC call\n"145+ HelpExampleRpc("getreceivedbylabel", "\"tabby\", 6, true")146},147[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue148{149const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);150if (!pwallet) return UniValue::VNULL;152// Make sure the results are valid at least up to the most recent block153// the user could have gotten from another RPC command prior to now154pwallet->BlockUntilSyncedToCurrentChain();156LOCK(pwallet->cs_wallet);158return ValueFromAmount(GetReceived(*pwallet, request.params, /*by_label=*/true));159},160};161}164RPCMethod getbalance()165{166return RPCMethod{167"getbalance",168"Returns the total available balance.\n"169"The available balance is what the wallet considers currently spendable, and is\n"170"thus affected by options which limit spendability such as -spendzeroconfchange.\n",171{172{"dummy", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Remains for backward compatibility. Must be excluded or set to \"*\".",173RPCArgOptions{.placeholder = true}},174{"minconf", RPCArg::Type::NUM, RPCArg::Default{0}, "Only include transactions confirmed at least this many times."},175{"include_watchonly", RPCArg::Type::BOOL, RPCArg::Default{false}, "No longer used"},176{"avoid_reuse", RPCArg::Type::BOOL, RPCArg::Default{true}, "(only available if avoid_reuse wallet flag is set) Do not include balance in dirty outputs; addresses are considered dirty if they have previously been used in a transaction."},177},178RPCResult{179RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " received for this wallet."180},181RPCExamples{182"\nThe total amount in the wallet with 0 or more confirmations\n"183+ HelpExampleCli("getbalance", "") +184"\nThe total amount in the wallet with at least 6 confirmations\n"185+ HelpExampleCli("getbalance", "\"*\" 6") +186"\nAs a JSON-RPC call\n"187+ HelpExampleRpc("getbalance", "\"*\", 6")188},189[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue190{191const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);192if (!pwallet) return UniValue::VNULL;194// Make sure the results are valid at least up to the most recent block195// the user could have gotten from another RPC command prior to now196pwallet->BlockUntilSyncedToCurrentChain();198LOCK(pwallet->cs_wallet);200if (self.MaybeArg<std::string_view>("dummy").value_or("*") != "*") {201throw JSONRPCError(RPC_METHOD_DEPRECATED, "dummy first argument must be excluded or set to \"*\".");202}204const auto min_depth{self.Arg<int>("minconf")};206bool avoid_reuse = GetAvoidReuseFlag(*pwallet, request.params[3]);208const auto bal = GetBalance(*pwallet, min_depth, avoid_reuse);210return ValueFromAmount(bal.m_mine_trusted);211},212};213}215RPCMethod lockunspent()216{217return RPCMethod{218"lockunspent",219"Updates list of temporarily unspendable outputs.\n"220"Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"221"If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n"222"A locked transaction output will not be chosen by automatic coin selection, when spending bitcoins.\n"223"Manually selected coins are automatically unlocked.\n"224"Locks are stored in memory only, unless persistent=true, in which case they will be written to the\n"225"wallet database and loaded on node start. Unwritten (persistent=false) locks are always cleared\n"226"(by virtue of process exit) when a node stops or fails. Unlocking will clear both persistent and not.\n"227"Also see the listunspent call\n",228{229{"unlock", RPCArg::Type::BOOL, RPCArg::Optional::NO, "Whether to unlock (true) or lock (false) the specified transactions"},230{"transactions", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The transaction outputs and within each, the txid (string) vout (numeric).",231{232{"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",233{234{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},235{"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},236},237},238},239},240{"persistent", RPCArg::Type::BOOL, RPCArg::Default{false}, "Whether to write/erase this lock in the wallet database, or keep the change in memory only. Ignored for unlocking."},241},242RPCResult{243RPCResult::Type::BOOL, "", "Whether the command was successful or not"244},245RPCExamples{246"\nList the unspent transactions\n"247+ HelpExampleCli("listunspent", "") +248"\nLock an unspent transaction\n"249+ HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +250"\nList the locked transactions\n"