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+ HelpExampleCli("listlockunspent", "") +252"\nUnlock the transaction again\n"253+ HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +254"\nLock the transaction persistently in the wallet database\n"255+ HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\" true") +256"\nAs a JSON-RPC call\n"257+ HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")258},259[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue260{261std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);262if (!pwallet) return UniValue::VNULL;264// Make sure the results are valid at least up to the most recent block265// the user could have gotten from another RPC command prior to now266pwallet->BlockUntilSyncedToCurrentChain();268LOCK(pwallet->cs_wallet);270bool fUnlock = request.params[0].get_bool();272const bool persistent{request.params[2].isNull() ? false : request.params[2].get_bool()};274if (request.params[1].isNull()) {275if (fUnlock) {276if (!pwallet->UnlockAllCoins())277throw JSONRPCError(RPC_WALLET_ERROR, "Unlocking coins failed");278}279return true;280}282const UniValue& output_params = request.params[1].get_array();284// Create and validate the COutPoints first.286std::vector<COutPoint> outputs;287outputs.reserve(output_params.size());289for (unsigned int idx = 0; idx < output_params.size(); idx++) {290const UniValue& o = output_params[idx].get_obj();292RPCTypeCheckObj(o,293{294{"txid", UniValueType(UniValue::VSTR)},295{"vout", UniValueType(UniValue::VNUM)},296});298const Txid txid = Txid::FromUint256(ParseHashO(o, "txid"));299const int nOutput = o.find_value("vout").getInt<int>();300if (nOutput < 0) {301throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout cannot be negative");302}304const COutPoint outpt(txid, nOutput);306const auto it = pwallet->mapWallet.find(outpt.hash);307if (it == pwallet->mapWallet.end()) {308throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, unknown transaction");309}311const CWalletTx& trans = it->second;313if (outpt.n >= trans.GetTx()->vout.size()) {314throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout index out of bounds");315}317if (pwallet->IsSpent(outpt)) {318throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected unspent output");319}321const bool is_locked = pwallet->IsLockedCoin(outpt);323if (fUnlock && !is_locked) {324throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected locked output");325}327if (!fUnlock && is_locked && !persistent) {328throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, output already locked");329}331outputs.push_back(outpt);332}334// Atomically set (un)locked status for the outputs.335for (const COutPoint& outpt : outputs) {336if (fUnlock) {337if (!pwallet->UnlockCoin(outpt)) throw JSONRPCError(RPC_WALLET_ERROR, "Unlocking coin failed");338} else {339if (!pwallet->LockCoin(outpt, persistent)) throw JSONRPCError(RPC_WALLET_ERROR, "Locking coin failed");340}341}343return true;344},345};346}348RPCMethod listlockunspent()349{350return RPCMethod{351"listlockunspent",352"Returns list of temporarily unspendable outputs.\n"353"See the lockunspent call to lock and unlock transactions for spending.\n",354{},355RPCResult{356RPCResult::Type::ARR, "", "",357{358{RPCResult::Type::OBJ, "", "",359{360{RPCResult::Type::STR_HEX, "txid", "The transaction id locked"},361{RPCResult::Type::NUM, "vout", "The vout value"},362}},363}364},365RPCExamples{366"\nList the unspent transactions\n"367+ HelpExampleCli("listunspent", "") +368"\nLock an unspent transaction\n"369+ HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +370"\nList the locked transactions\n"371+ HelpExampleCli("listlockunspent", "") +372"\nUnlock the transaction again\n"373+ HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +374"\nAs a JSON-RPC call\n"375+ HelpExampleRpc("listlockunspent", "")376},377[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue378{379const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);380if (!pwallet) return UniValue::VNULL;382LOCK(pwallet->cs_wallet);384std::vector<COutPoint> vOutpts;385pwallet->ListLockedCoins(vOutpts);387UniValue ret(UniValue::VARR);389for (const COutPoint& outpt : vOutpts) {390UniValue o(UniValue::VOBJ);392o.pushKV("txid", outpt.hash.GetHex());393o.pushKV("vout", outpt.n);394ret.push_back(std::move(o));395}397return ret;398},399};400}402RPCMethod getbalances()403{404return RPCMethod{405"getbalances",406"Returns an object with all balances in " + CURRENCY_UNIT + ".\n",407{},408RPCResult{409RPCResult::Type::OBJ, "", "",410{411{RPCResult::Type::OBJ, "mine", "balances from outputs that the wallet can sign",412{413{RPCResult::Type::STR_AMOUNT, "trusted", "trusted balance (outputs created by the wallet or confirmed outputs)"},414{RPCResult::Type::STR_AMOUNT, "untrusted_pending", "untrusted pending balance (outputs created by others that are in the mempool)"},415{RPCResult::Type::STR_AMOUNT, "immature", "balance from immature coinbase outputs"},416{RPCResult::Type::STR_AMOUNT, "nonmempool", "sum of coins that are spent by transactions not in the mempool (usually an over-estimate due to not accounting for change or spends that conflict with each other)"},417{RPCResult::Type::STR_AMOUNT, "used", /*optional=*/true, "(only present if avoid_reuse is set) balance from coins sent to addresses that were previously spent from (potentially privacy violating)"},418}},419RESULT_LAST_PROCESSED_BLOCK,420}421},422RPCExamples{423HelpExampleCli("getbalances", "") +424HelpExampleRpc("getbalances", "")},425[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue426{427const std::shared_ptr<const CWallet> rpc_wallet = GetWalletForJSONRPCRequest(request);428if (!rpc_wallet) return UniValue::VNULL;429const CWallet& wallet = *rpc_wallet;431// Make sure the results are valid at least up to the most recent block432// the user could have gotten from another RPC command prior to now433wallet.BlockUntilSyncedToCurrentChain();435LOCK(wallet.cs_wallet);437const auto bal = GetBalance(wallet, /*min_depth=*/0, /*avoid_reuse=*/true, /*include_nonmempool=*/true);439UniValue balances{UniValue::VOBJ};440{441UniValue balances_mine{UniValue::VOBJ};442balances_mine.pushKV("trusted", ValueFromAmount(bal.m_mine_trusted));443balances_mine.pushKV("untrusted_pending", ValueFromAmount(bal.m_mine_untrusted_pending));444balances_mine.pushKV("immature", ValueFromAmount(bal.m_mine_immature));445balances_mine.pushKV("nonmempool", ValueFromAmount(bal.m_mine_nonmempool));446if (wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE)) {447balances_mine.pushKV("used", ValueFromAmount(bal.m_mine_used));448}449balances.pushKV("mine", std::move(balances_mine));450}451AppendLastProcessedBlock(balances, wallet);452return balances;453},454};455}457RPCMethod listunspent()458{459return RPCMethod{460"listunspent",461"Returns array of unspent transaction outputs\n"462"with between minconf and maxconf (inclusive) confirmations.\n"463"Optionally filter to only include txouts paid to specified addresses.\n",464{465{"minconf", RPCArg::Type::NUM, RPCArg::Default{1}, "The minimum confirmations to filter"},466{"maxconf", RPCArg::Type::NUM, RPCArg::Default{9999999}, "The maximum confirmations to filter"},467{"addresses", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The bitcoin addresses to filter",468{469{"address", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "bitcoin address"},470},471},472{"include_unsafe", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include outputs that are not safe to spend\n"473"See description of \"safe\" attribute below."},474{"query_options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "",475{476{"minimumAmount", RPCArg::Type::AMOUNT, RPCArg::Default{FormatMoney(0)}, "Minimum value of each UTXO in " + CURRENCY_UNIT + ""},477{"maximumAmount", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"unlimited"}, "Maximum value of each UTXO in " + CURRENCY_UNIT + ""},478{"maximumCount", RPCArg::Type::NUM, RPCArg::DefaultHint{"unlimited"}, "Maximum number of UTXOs"},479{"minimumSumAmount", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"unlimited"}, "Minimum sum value of all UTXOs in " + CURRENCY_UNIT + ""},480{"include_immature_coinbase", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include immature coinbase UTXOs"}481},482RPCArgOptions{.oneline_description="query_options"}},483},484RPCResult{485RPCResult::Type::ARR, "", "",486{487{RPCResult::Type::OBJ, "", "",488{489{RPCResult::Type::STR_HEX, "txid", "the transaction id"},490{RPCResult::Type::NUM, "vout", "the vout value"},491{RPCResult::Type::STR, "address", /*optional=*/true, "the bitcoin address"},492{RPCResult::Type::STR, "label", /*optional=*/true, "The associated label, or \"\" for the default label"},493{RPCResult::Type::STR_HEX, "scriptPubKey", "the output script"},494{RPCResult::Type::STR_AMOUNT, "amount", "the transaction output amount in " + CURRENCY_UNIT},495{RPCResult::Type::NUM, "confirmations", "The number of confirmations"},496{RPCResult::Type::NUM, "ancestorcount", /*optional=*/true, "The number of in-mempool ancestor transactions, including this one (if transaction is in the mempool)"},497{RPCResult::Type::NUM, "ancestorsize", /*optional=*/true, "The virtual transaction size of in-mempool ancestors, including this one (if transaction is in the mempool)"},498{RPCResult::Type::NUM, "ancestorfees", /*optional=*/true, "The total fees of in-mempool ancestors (including this one) with fee deltas used for mining priority in " + CURRENCY_ATOM + " (if transaction is in the mempool)"},499{RPCResult::Type::STR_HEX, "redeemScript", /*optional=*/true, "The redeem script if the output script is P2SH"},500{RPCResult::Type::STR, "witnessScript", /*optional=*/true, "witness script if the output script is P2WSH or P2SH-P2WSH"},