JSON-RPC Interface

The headless daemon bitcoind has the JSON-RPC API enabled by default, the GUI bitcoin-qt has it disabled by default. This can be changed with the -server option. In the GUI it is possible to execute RPC methods in the Debug Console Dialog.


The RPC interface might change from one major version of Bitcoin Core to the next. This makes the RPC interface implicitly versioned on the major version. The version tuple can be retrieved by e.g. the getnetworkinfo RPC in version.

Usually deprecated features can be re-enabled during the grace-period of one major version via the -deprecatedrpc= command line option. The release notes of a new major release come with detailed instructions on what RPC features were deprecated and how to re-enable them temporarily.


The RPC interface allows other programs to control Bitcoin Core, including the ability to spend funds from your wallets, affect consensus verification, read private data, and otherwise perform operations that can cause loss of money, data, or privacy. This section suggests how you should use and configure Bitcoin Core to reduce the risk that its RPC interface will be abused.

RPC consistency guarantees

State that can be queried via RPCs is guaranteed to be at least up-to-date with the chain state immediately prior to the call's execution. However, the state returned by RPCs that reflect the mempool may not be up-to-date with the current mempool state.

Transaction Pool

The mempool state returned via an RPC is consistent with itself and with the chain state at the time of the call. Thus, the mempool state only encompasses transactions that are considered mine-able by the node at the time of the RPC.

The mempool state returned via an RPC reflects all effects of mempool and chain state related RPCs that returned prior to this call.


The wallet state returned via an RPC is consistent with itself and with the chain state at the time of the call.

Wallet RPCs will return the latest chain state consistent with prior non-wallet RPCs. The effects of all blocks (and transactions in blocks) at the time of the call is reflected in the state of all wallet transactions. For example, if a block contains transactions that conflicted with mempool transactions, the wallet would reflect the removal of these mempool transactions in the state.

However, the wallet may not be up-to-date with the current state of the mempool or the state of the mempool by an RPC that returned before this RPC. For example, a wallet transaction that was BIP-125-replaced in the mempool prior to this RPC may not yet be reflected as such in this RPC response.


There is a known issue in the JSON-RPC interface that can cause a node to crash if too many http connections are being opened at the same time because the system runs out of available file descriptors. To prevent this from happening you might want to increase the number of maximum allowed file descriptors in your system and try to prevent opening too many connections to your JSON-RPC interface at the same time if this is under your control. It is hard to give general advice since this depends on your system but if you make several hundred requests at once you are definitely at risk of encountering this issue. Bitcoin Core


Bitcoin Core is the original Bitcoin client and it builds the backbone of the network. It downloads and, by default, stores the entire history of Bitcoin transactions, which requires a few hundred gigabytes of disk space. Depending on the speed of your computer and network connection, the synchronization process can take anywhere from a few hours to a day or more.

To download Bitcoin Core, visit bitcoincore.org.


The following are some helpful notes on how to run Bitcoin Core on your native platform.


Unpack the files into a directory and run:


Unpack the files into a directory, and then run bitcoin-qt.exe.


Drag Bitcoin Core to your applications folder, and then run Bitcoin Core.

Need Help?


The following are developer notes on how to build Bitcoin Core on your native platform. They are not complete guides, but include notes on the necessary libraries, compile flags, etc.


The Bitcoin repo's root README contains relevant information on the development process and automated testing.




Distributed under the MIT software license. \mainpage notitle

\section intro_sec Introduction

This is the developer documentation of the reference client for an experimental new digital currency called Bitcoin, which enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate with no central authority: managing transactions and issuing money are carried out collectively by the network.

The software is a community-driven open source project, released under the MIT license.

See https://github.com/bitcoin/bitcoin and https://bitcoincore.org/ for further information about the project.

\section Navigation Use Modules, Namespaces, Classes, or Files at the top of the page to start navigating the code.

Unauthenticated REST Interface

The REST API can be enabled with the -rest option.

The interface runs on the same port as the JSON-RPC interface, by default port 8332 for mainnet, port 18332 for testnet, and port 18443 for regtest.

REST Interface consistency guarantees

The same guarantees as for the RPC Interface apply.


There is a known issue in the REST interface that can cause a node to crash if too many http connections are being opened at the same time because the system runs out of available file descriptors. To prevent this from happening you might want to increase the number of maximum allowed file descriptors in your system and try to prevent opening too many connections to your rest interface at the same time if this is under your control. It is hard to give general advice since this depends on your system but if you make several hundred requests at once you are definitely at risk of encountering this issue.

Supported API


GET /rest/tx/<TX-HASH>.<bin|hex|json>

Given a transaction hash: returns a transaction in binary, hex-encoded binary, or JSON formats.

By default, this endpoint will only search the mempool. To query for a confirmed transaction, enable the transaction index via "txindex=1" command line / configuration option.


GET /rest/block/<BLOCK-HASH>.<bin|hex|json> GET /rest/block/notxdetails/<BLOCK-HASH>.<bin|hex|json>

Given a block hash: returns a block, in binary, hex-encoded binary or JSON formats. Responds with 404 if the block doesn't exist.

The HTTP request and response are both handled entirely in-memory.

With the /notxdetails/ option JSON response will only contain the transaction hash instead of the complete transaction details. The option only affects the JSON response.


GET /rest/headers/<COUNT>/<BLOCK-HASH>.<bin|hex|json>

Given a block hash: returns amount of blockheaders in upward direction. Returns empty if the block doesn't exist or it isn't in the active chain.

Blockhash by height

GET /rest/blockhashbyheight/<HEIGHT>.<bin|hex|json>

Given a height: returns hash of block in best-block-chain at height provided.


GET /rest/chaininfo.json

Returns various state info regarding block chain processing. Only supports JSON as output format.

Query UTXO set

GET /rest/getutxos/<checkmempool>/<txid>-<n>/<txid>-<n>/.../<txid>-<n>.<bin|hex|json>

The getutxo command allows querying of the UTXO set given a set of outpoints. See BIP64 for input and output serialisation: https://github.com/bitcoin/bips/blob/master/bip-0064.mediawiki


$ curl localhost:18332/rest/getutxos/checkmempool/b2cdfd7b89def827ff8af7cd9bff7627ff72e5e8b0f71210f92ea7a4000c5d75-0.json 2>/dev/null | json_pp
   "chainHeight" : 325347,
   "chaintipHash" : "00000000fb01a7f3745a717f8caebee056c484e6e0bfe4a9591c235bb70506fb",
   "bitmap": "1",
   "utxos" : [
         "height" : 2147483647,
         "value" : 8.8687,
         "scriptPubKey" : {
            "asm" : "OP_DUP OP_HASH160 1c7cebb529b86a04c683dfa87be49de35bcf589e OP_EQUALVERIFY OP_CHECKSIG",
            "hex" : "76a9141c7cebb529b86a04c683dfa87be49de35bcf589e88ac",
            "reqSigs" : 1,
            "type" : "pubkeyhash",
            "addresses" : [

Memory pool

GET /rest/mempool/info.json

Returns various information about the TX mempool. Only supports JSON as output format.

GET /rest/mempool/contents.json

Returns transactions in the TX mempool. Only supports JSON as output format.


Running a web browser on the same node with a REST enabled bitcoind can be a risk. Accessing prepared XSS websites could read out tx/block data of your node by placing links like <script src=""> which might break the nodes privacy. The list of assets used in the bitcoin source and their attribution can now be found in contrib/debian/copyright. Benchmarking

Bitcoin Core has an internal benchmarking framework, with benchmarks for cryptographic algorithms (e.g. SHA1, SHA256, SHA512, RIPEMD160, Poly1305, ChaCha20), rolling bloom filter, coins selection, thread queue, wallet balance.


For benchmarks purposes you only need to compile bitcoin_bench. Beware of configuring without --enable-debug as this would impact benchmarking by unlatching log printers and lock analysis.

make -C src bitcoin_bench

After compiling bitcoin-core, the benchmarks can be run with:


The output will look similar to:

|             ns/byte |              byte/s | error % | benchmark
|               64.13 |       15,592,356.01 |    0.1% | `Base58CheckEncode`
|               24.56 |       40,722,672.68 |    0.2% | `Base58Decode`


src/bench/bench_bitcoin --help

To print options like scaling factor or per-benchmark filter.


More benchmarks are needed for, in no particular order:

Going Further

To monitor Bitcoin Core performance more in depth (like reindex or IBD): https://github.com/chaincodelabs/bitcoinperf

To generate Flame Graphs for Bitcoin Core: https://github.com/eklitzke/bitcoin/blob/flamegraphs/doc/flamegraphs.html BIPs that are implemented by Bitcoin Core (up-to-date up to v0.21.0):

bitcoin.conf Configuration File

The configuration file is used by bitcoind, bitcoin-qt and bitcoin-cli.

All command-line options (except for -?, -help, -version and -conf) may be specified in a configuration file, and all configuration file options (except for includeconf) may also be specified on the command line. Command-line options override values set in the configuration file and configuration file options override values set in the GUI.

Configuration File Format

The configuration file is a plain text file and consists of option=value entries, one per line. Leading and trailing whitespaces are removed.

In contrast to the command-line usage:

Blank lines

Blank lines are allowed and ignored by the parser.


A comment starts with a number sign (#) and extends to the end of the line. All comments are ignored by the parser.

Comments may appear in two ways:

Network specific options

Network specific options can be:

Network specific options take precedence over non-network specific options. If multiple values for the same option are found with the same precedence, the first one is generally chosen.

This means that given the following configuration, regtest.rpcport is set to 3000:



Configuration File Path

The configuration file is not automatically created; you can create it using your favorite text editor. By default, the configuration file name is bitcoin.conf and it is located in the Bitcoin data directory, but both the Bitcoin data directory and the configuration file path may be changed using the -datadir and -conf command-line options.

The includeconf=<file> option in the bitcoin.conf file can be used to include additional configuration files.

Default configuration file locations

Operating System Data Directory Example Path
Windows %APPDATA%\Bitcoin\ C:\Users\username\AppData\Roaming\Bitcoin\bitcoin.conf
Linux $HOME/.bitcoin/ /home/username/.bitcoin/bitcoin.conf
macOS $HOME/Library/Application Support/Bitcoin/ /Users/username/Library/Application Support/Bitcoin/bitcoin.conf

You can find an example bitcoin.conf file in share/examples/bitcoin.conf.

FreeBSD Build Guide

Updated for FreeBSD 12.2

This guide describes how to build bitcoind, command-line utilities, and GUI on FreeBSD.


The following dependencies are required:

Library Purpose Description
autoconf Build Automatically configure software source code
automake Build Generate makefile (requires autoconf)
libtool Build Shared library support
pkgconf Build Configure compiler and linker flags
git Clone Version control system
gmake Compile Generate executables
boost-libs Utility Library for threading, data structures, etc
libevent Networking OS independent asynchronous networking

The following dependencies are optional:

Library Purpose Description
db5 Berkeley DB Wallet storage (only needed when wallet enabled)
qt5 GUI GUI toolkit (only needed when GUI enabled)
libqrencode QR codes in GUI Generating QR codes (only needed when GUI enabled)
libzmq4 ZMQ notification Allows generating ZMQ notifications (requires ZMQ version >= 4.0.0)
sqlite3 SQLite DB Wallet storage (only needed when wallet enabled)
python3 Testing Python Interpreter (only needed when running the test suite)

See dependencies.html for a complete overview.


1. Install Required Dependencies

Install the required dependencies the usual way you install software on FreeBSD - either with pkg or via the Ports collection. The example commands below use pkg which is usually run as root or via sudo. If you want to use sudo, and you haven't set it up: use this guide to setup sudo access on FreeBSD.

pkg install autoconf automake boost-libs git gmake libevent libtool pkgconf

2. Clone Bitcoin Repo

Now that git and all the required dependencies are installed, let's clone the Bitcoin Core repository to a directory. All build scripts and commands will run from this directory.

git clone https://github.com/bitcoin/bitcoin.git

3. Install Optional Dependencies

Wallet Dependencies

It is not necessary to build wallet functionality to run bitcoind or the GUI. To enable legacy wallets, you must install db5. To enable descriptor wallets, sqlite3 is required. Skip db5 if you intend to exclusively use descriptor wallets

Legacy Wallet Support

db5 is required to enable support for legacy wallets. Skip if you don't intend to use legacy wallets

pkg install db5
Descriptor Wallet Support

sqlite3 is required to enable support for descriptor wallets. Skip if you don't intend to use descriptor wallets.

pkg install sqlite3

GUI Dependencies


Bitcoin Core includes a GUI built with the cross-platform Qt Framework. To compile the GUI, we need to install qt5. Skip if you don't intend to use the GUI.

pkg install qt5

The GUI can encode addresses in a QR Code. To build in QR support for the GUI, install libqrencode. Skip if not using the GUI or don't want QR code functionality.

pkg install libqrencode

Test Suite Dependencies

There is an included test suite that is useful for testing code changes when developing. To run the test suite (recommended), you will need to have Python 3 installed:

pkg install python3

Building Bitcoin Core

1. Configuration

There are many ways to configure Bitcoin Core, here are a few common examples:

Wallet (BDB + SQlite) Support, No GUI:

This explicitly enables legacy wallet support and disables the GUI. If sqlite3 is installed, then descriptor wallet support will be built.

./configure --with-gui=no --with-incompatible-bdb \
    BDB_LIBS="-ldb_cxx-5" \
    BDB_CFLAGS="-I/usr/local/include/db5" \
Wallet (only SQlite) and GUI Support:

This explicitly enables the GUI and disables legacy wallet support. If qt5 is not installed, this will throw an error. If sqlite3 is installed then descriptor wallet functionality will be built. If sqlite3 is not installed, then wallet functionality will be disabled.

./configure --without-bdb --with-gui=yes MAKE=gmake
No Wallet or GUI
./configure --without-wallet --with-gui=no MAKE=gmake

2. Compile

Important: Use gmake (the non-GNU make will exit with an error).

gmake # use -jX here for parallelism
gmake check # Run tests if Python 3 is available

NetBSD build guide

(updated for NetBSD 8.0)

This guide describes how to build bitcoind and command-line utilities on NetBSD.

This guide does not contain instructions for building the GUI.


You will need the following modules, which can be installed via pkgsrc or pkgin:


git clone https://github.com/bitcoin/bitcoin.git

See dependencies.html for a complete overview.

Building BerkeleyDB

BerkeleyDB is only necessary for the wallet functionality. To skip this, pass --disable-wallet to ./configure and skip to the next section.

It is recommended to use Berkeley DB 4.8. You cannot use the BerkeleyDB library from ports, for the same reason as boost above (g++/libstd++ incompatibility). If you have to build it yourself, you can use the installation script included in contrib/ like so:

./contrib/install_db4.sh `pwd`

from the root of the repository. Then set BDB_PREFIX for the next section:

export BDB_PREFIX="$PWD/db4"

Building Bitcoin Core

Important: Use gmake (the non-GNU make will exit with an error).

With wallet:

./configure --with-gui=no CPPFLAGS="-I/usr/pkg/include" \
    LDFLAGS="-L/usr/pkg/lib" \
    BOOST_CPPFLAGS="-I/usr/pkg/include" \
    BOOST_LDFLAGS="-L/usr/pkg/lib" \
    BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" \
    BDB_CFLAGS="-I${BDB_PREFIX}/include" \

Without wallet:

./configure --with-gui=no --disable-wallet \
    CPPFLAGS="-I/usr/pkg/include" \
    LDFLAGS="-L/usr/pkg/lib" \
    BOOST_CPPFLAGS="-I/usr/pkg/include" \
    BOOST_LDFLAGS="-L/usr/pkg/lib" \

Build and run the tests:

gmake # use -jX here for parallelism
gmake check

OpenBSD build guide

(updated for OpenBSD 6.7)

This guide describes how to build bitcoind, bitcoin-qt, and command-line utilities on OpenBSD.


Run the following as root to install the base dependencies for building:

pkg_add git gmake libevent libtool boost
pkg_add qt5 # (optional for enabling the GUI)
pkg_add autoconf # (select highest version, e.g. 2.69)
pkg_add automake # (select highest version, e.g. 1.16)
pkg_add python # (select highest version, e.g. 3.8)
pkg_add bash

git clone https://github.com/bitcoin/bitcoin.git

See dependencies.html for a complete overview.

Important: From OpenBSD 6.2 onwards a C++11-supporting clang compiler is part of the base image, and while building it is necessary to make sure that this compiler is used and not ancient g++ 4.2.1. This is done by appending CC=cc CC_FOR_BUILD=cc CXX=c++ to configuration commands. Mixing different compilers within the same executable will result in errors.

Building BerkeleyDB

BerkeleyDB is only necessary for the wallet functionality. To skip this, pass --disable-wallet to ./configure and skip to the next section.

It is recommended to use Berkeley DB 4.8. You cannot use the BerkeleyDB library from ports, for the same reason as boost above (g++/libstd++ incompatibility). If you have to build it yourself, you can use the installation script included in contrib/ like so:

./contrib/install_db4.sh `pwd` CC=cc CXX=c++

from the root of the repository. Then set BDB_PREFIX for the next section:

export BDB_PREFIX="$PWD/db4"

Building Bitcoin Core

Important: Use gmake (the non-GNU make will exit with an error).


# Replace this with the autoconf version that you installed. Include only
# the major and minor parts of the version: use "2.69" for "autoconf-2.69p2".

# Replace this with the automake version that you installed. Include only
# the major and minor parts of the version: use "1.16" for "automake-1.16.1".


Make sure BDB_PREFIX is set to the appropriate path from the above steps.

To configure with wallet:

./configure --with-gui=no CC=cc CXX=c++ \
    BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" \
    BDB_CFLAGS="-I${BDB_PREFIX}/include" \

To configure without wallet:

./configure --disable-wallet --with-gui=no CC=cc CC_FOR_BUILD=cc CXX=c++ MAKE=gmake

To configure with GUI:

./configure --with-gui=yes CC=cc CXX=c++ \
    BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" \
    BDB_CFLAGS="-I${BDB_PREFIX}/include" \

Build and run the tests:

gmake # use -jX here for parallelism
gmake check

Resource limits

If the build runs into out-of-memory errors, the instructions in this section might help.

The standard ulimit restrictions in OpenBSD are very strict:

data(kbytes)         1572864

This is, unfortunately, in some cases not enough to compile some .cpp files in the project, (see issue #6658). If your user is in the staff group the limit can be raised with:

ulimit -d 3000000

The change will only affect the current shell and processes spawned by it. To make the change system-wide, change datasize-cur and datasize-max in /etc/login.conf, and reboot.

macOS Build Instructions and Notes

The commands in this guide should be executed in a Terminal application. The built-in one is located in



Install the macOS command line tools:

xcode-select --install

When the popup appears, click Install.

Then install Homebrew.


brew install automake libtool boost miniupnpc pkg-config python qt libevent qrencode

If you run into issues, check Homebrew's troubleshooting page. See dependencies.html for a complete overview.

If you want to build the disk image with make deploy (.dmg / optional), you need RSVG:

brew install librsvg

The wallet support requires one or both of the dependencies (SQLite and Berkeley DB) in the sections below. To build Bitcoin Core without wallet, see Disable-wallet mode.


Usually, macOS installation already has a suitable SQLite installation. Also, the Homebrew package could be installed:

brew install sqlite

In that case the Homebrew package will prevail.

Berkeley DB

It is recommended to use Berkeley DB 4.8. If you have to build it yourself, you can use this script to install it like so:

./contrib/install_db4.sh .

from the root of the repository.

Also, the Homebrew package could be installed:

brew install berkeley-db4

Build Bitcoin Core

  1. Clone the Bitcoin Core source code:

    git clone https://github.com/bitcoin/bitcoin
    cd bitcoin
  2. Build Bitcoin Core:

    Configure and build the headless Bitcoin Core binaries as well as the GUI (if Qt is found).

    You can disable the GUI build by passing --without-gui to configure.

  3. It is recommended to build and run the unit tests:

    make check
  4. You can also create a .dmg that contains the .app bundle (optional):

    make deploy

Disable-wallet mode

When the intention is to run only a P2P node without a wallet, Bitcoin Core may be compiled in disable-wallet mode with:

./configure --disable-wallet

In this case there is no dependency on Berkeley DB and SQLite.

Mining is also possible in disable-wallet mode using the getblocktemplate RPC call.


Bitcoin Core is now available at ./src/bitcoind

Before running, you may create an empty configuration file:

mkdir -p "/Users/${USER}/Library/Application Support/Bitcoin"

touch "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf"

chmod 600 "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf"

The first time you run bitcoind, it will start downloading the blockchain. This process could take many hours, or even days on slower than average systems.

You can monitor the download process by looking at the debug.log file:

tail -f $HOME/Library/Application\ Support/Bitcoin/debug.log

Other commands:

./src/bitcoind -daemon      # Starts the bitcoin daemon.
./src/bitcoin-cli --help    # Outputs a list of command-line options.
./src/bitcoin-cli help      # Outputs a list of RPC commands when the daemon is running.


(For BSD specific instructions, see build-*bsd.html in this directory.)


Always use absolute paths to configure and compile Bitcoin Core and the dependencies. For example, when specifying the path of the dependency:

../dist/configure --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX

Here BDB_PREFIX must be an absolute path - it is defined using $(pwd) which ensures the usage of the absolute path.

To Build

make install # optional

This will build bitcoin-qt as well, if the dependencies are met.


These dependencies are required:

Library Purpose Description
libboost Utility Library for threading, data structures, etc
libevent Networking OS independent asynchronous networking

Optional dependencies:

Library Purpose Description
miniupnpc UPnP Support Firewall-jumping support
libdb4.8 Berkeley DB Optional, wallet storage (only needed when wallet enabled)
qt GUI GUI toolkit (only needed when GUI enabled)
libqrencode QR codes in GUI Optional for generating QR codes (only needed when GUI enabled)
univalue Utility JSON parsing and encoding (bundled version will be used unless --with-system-univalue passed to configure)
libzmq3 ZMQ notification Optional, allows generating ZMQ notifications (requires ZMQ version >= 4.0.0)
sqlite3 SQLite DB Optional, wallet storage (only needed when wallet enabled)

For the versions used, see dependencies.html

Memory Requirements

C++ compilers are memory-hungry. It is recommended to have at least 1.5 GB of memory available when compiling Bitcoin Core. On systems with less, gcc can be tuned to conserve memory with additional CXXFLAGS:

./configure CXXFLAGS="--param ggc-min-expand=1 --param ggc-min-heapsize=32768"

Alternatively, or in addition, debugging information can be skipped for compilation. The default compile flags are -g -O2, and can be changed with:

./configure CXXFLAGS="-O2"

Finally, clang (often less resource hungry) can be used instead of gcc, which is used by default:

./configure CXX=clang++ CC=clang

Linux Distribution Specific Instructions

Ubuntu & Debian

Dependency Build Instructions

Build requirements:

sudo apt-get install build-essential libtool autotools-dev automake pkg-config bsdmainutils python3

Now, you can either build from self-compiled depends or install the required dependencies:

sudo apt-get install libevent-dev libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev

BerkeleyDB is required for the wallet.

Ubuntu and Debian have their own libdb-dev and libdb++-dev packages, but these will install BerkeleyDB 5.1 or later. This will break binary wallet compatibility with the distributed executables, which are based on BerkeleyDB 4.8. If you do not care about wallet compatibility, pass --with-incompatible-bdb to configure.

Otherwise, you can build from self-compiled depends (see above).

SQLite is required for the wallet:

sudo apt install libsqlite3-dev

To build Bitcoin Core without wallet, see Disable-wallet mode

Optional (see --with-miniupnpc and --enable-upnp-default):

sudo apt-get install libminiupnpc-dev

ZMQ dependencies (provides ZMQ API):

sudo apt-get install libzmq3-dev

GUI dependencies:

If you want to build bitcoin-qt, make sure that the required packages for Qt development are installed. Qt 5 is necessary to build the GUI. To build without GUI pass --without-gui.

To build with Qt 5 you need the following:

sudo apt-get install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools

libqrencode (optional) can be installed with:

sudo apt-get install libqrencode-dev

Once these are installed, they will be found by configure and a bitcoin-qt executable will be built by default.


Dependency Build Instructions

Build requirements:

sudo dnf install gcc-c++ libtool make autoconf automake libevent-devel boost-devel libdb4-devel libdb4-cxx-devel python3

Optional (see --with-miniupnpc and --enable-upnp-default):

sudo dnf install miniupnpc-devel

ZMQ dependencies (provides ZMQ API):

sudo dnf install zeromq-devel

To build with Qt 5 you need the following:

sudo dnf install qt5-qttools-devel qt5-qtbase-devel

libqrencode (optional) can be installed with:

sudo dnf install qrencode-devel

SQLite can be installed with:

sudo dnf install sqlite-devel


The release is built with GCC and then "strip bitcoind" to strip the debug symbols, which reduces the executable size by about 90%.


miniupnpc may be used for UPnP port mapping. It can be downloaded from here. UPnP support is compiled in and turned off by default. See the configure options for upnp behavior desired:

--without-miniupnpc      No UPnP support miniupnp not required
--disable-upnp-default   (the default) UPnP support turned off by default at runtime
--enable-upnp-default    UPnP support turned on by default at runtime

Berkeley DB

It is recommended to use Berkeley DB 4.8. If you have to build it yourself, you can use the installation script included in contrib/ like so:

./contrib/install_db4.sh `pwd`

from the root of the repository.

Note: You only need Berkeley DB if the wallet is enabled (see Disable-wallet mode).


If you need to build Boost yourself:

sudo su
./bjam install


To help make your Bitcoin Core installation more secure by making certain attacks impossible to exploit even if a vulnerability is found, binaries are hardened by default. This can be disabled with:

Hardening Flags:

./configure --enable-hardening
./configure --disable-hardening

Hardening enables the following features:

Disable-wallet mode

When the intention is to run only a P2P node without a wallet, Bitcoin Core may be compiled in disable-wallet mode with:

./configure --disable-wallet

In this case there is no dependency on Berkeley DB 4.8 and SQLite.

Mining is also possible in disable-wallet mode using the getblocktemplate RPC call.

Additional Configure Flags

A list of additional configure flags can be displayed with:

./configure --help

Setup and Build Example: Arch Linux

This example lists the steps necessary to setup and build a command line only, non-wallet distribution of the latest changes on Arch Linux:

pacman -S git base-devel boost libevent python
git clone https://github.com/bitcoin/bitcoin.git
cd bitcoin/
./configure --disable-wallet --without-gui --without-miniupnpc
make check

Note: Enabling wallet support requires either compiling against a Berkeley DB newer than 4.8 (package db) using --with-incompatible-bdb, or building and depending on a local version of Berkeley DB 4.8. The readily available Arch Linux packages are currently built using --with-incompatible-bdb according to the PKGBUILD. As mentioned above, when maintaining portability of the wallet between the standard Bitcoin Core distributions and independently built node software is desired, Berkeley DB 4.8 must be used.

ARM Cross-compilation

These steps can be performed on, for example, an Ubuntu VM. The depends system will also work on other Linux distributions, however the commands for installing the toolchain will be different.

Make sure you install the build requirements mentioned above. Then, install the toolchain and curl:

sudo apt-get install g++-arm-linux-gnueabihf curl

To build executables for ARM:

cd depends
make HOST=arm-linux-gnueabihf NO_QT=1
cd ..
./configure --prefix=$PWD/depends/arm-linux-gnueabihf --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++

For further documentation on the depends system see README.html in the depends directory. WINDOWS BUILD NOTES

Below are some notes on how to build Bitcoin Core for Windows.

The options known to work for building Bitcoin Core on Windows are:

Other options which may work, but which have not been extensively tested are (please contribute instructions):

Installing Windows Subsystem for Linux

With Windows 10, Microsoft has released a new feature named the Windows Subsystem for Linux (WSL). This feature allows you to run a bash shell directly on Windows in an Ubuntu-based environment. Within this environment you can cross compile for Windows without the need for a separate Linux VM or server. Note that while WSL can be installed with other Linux variants, such as OpenSUSE, the following instructions have only been tested with Ubuntu.

This feature is not supported in versions of Windows prior to Windows 10 or on Windows Server SKUs. In addition, it is available only for 64-bit versions of Windows.

Full instructions to install WSL are available on the above link. To install WSL on Windows 10 with Fall Creators Update installed (version >= 16215.0) do the following:

  1. Enable the Windows Subsystem for Linux feature
  1. Install Ubuntu
  1. Complete Installation

After the bash shell is active, you can follow the instructions below, starting with the "Cross-compilation" section. Compiling the 64-bit version is recommended, but it is possible to compile the 32-bit version.

Cross-compilation for Ubuntu and Windows Subsystem for Linux

The steps below can be performed on Ubuntu (including in a VM) or WSL. The depends system will also work on other Linux distributions, however the commands for installing the toolchain will be different.

First, install the general dependencies:

sudo apt update
sudo apt upgrade
sudo apt install build-essential libtool autotools-dev automake pkg-config bsdmainutils curl git

A host toolchain (build-essential) is necessary because some dependency packages need to build host utilities that are used in the build process.

See dependencies.html for a complete overview.

If you want to build the windows installer with make deploy you need NSIS:

sudo apt install nsis

Acquire the source in the usual way:

git clone https://github.com/bitcoin/bitcoin.git
cd bitcoin

Building for 64-bit Windows

The first step is to install the mingw-w64 cross-compilation tool chain:

sudo apt install g++-mingw-w64-x86-64

Ubuntu Bionic 18.04 1:

sudo update-alternatives --config x86_64-w64-mingw32-g++ # Set the default mingw32 g++ compiler option to posix.

Once the toolchain is installed the build steps are common:

Note that for WSL the Bitcoin Core source path MUST be somewhere in the default mount file system, for example /usr/src/bitcoin, AND not under /mnt/d/. If this is not the case the dependency autoconf scripts will fail. This means you cannot use a directory that is located directly on the host Windows file system to perform the build.

Additional WSL Note: WSL support for launching Win32 applications results in Autoconf configure scripts being able to execute Windows Portable Executable files. This can cause unexpected behaviour during the build, such as Win32 error dialogs for missing libraries. The recommended approach is to temporarily disable WSL support for Win32 applications.

Build using:

PATH=$(echo "$PATH" | sed -e 's/:\/mnt.*//g') # strip out problematic Windows %PATH% imported var
sudo bash -c "echo 0 > /proc/sys/fs/binfmt_misc/status" # Disable WSL support for Win32 applications.
cd depends
make HOST=x86_64-w64-mingw32
cd ..
./autogen.sh # not required when building from tarball
CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site ./configure --prefix=/
sudo bash -c "echo 1 > /proc/sys/fs/binfmt_misc/status" # Enable WSL support for Win32 applications.

Depends system

For further documentation on the depends system see README.html in the depends directory.


After building using the Windows subsystem it can be useful to copy the compiled executables to a directory on the Windows drive in the same directory structure as they appear in the release .zip archive. This can be done in the following way. This will install to c:\workspace\bitcoin, for example:

make install DESTDIR=/mnt/c/workspace/bitcoin

You can also create an installer using:

make deploy


1: Starting from Ubuntu Xenial 16.04, both the 32 and 64 bit Mingw-w64 packages install two different compiler options to allow a choice between either posix or win32 threads. The default option is win32 threads which is the more efficient since it will result in binary code that links directly with the Windows kernel32.lib. Unfortunately, the headers required to support win32 threads conflict with some of the classes in the C++11 standard library, in particular std::mutex. It's not possible to build the Bitcoin Core code using the win32 version of the Mingw-w64 cross compilers (at least not without modifying headers in the Bitcoin Core source code). Dependencies

These are the dependencies currently used by Bitcoin Core. You can find instructions for installing them in the build-*.html file for your platform.

Dependency Version used Minimum required CVEs Shared Bundled Qt library
Berkeley DB 4.8.30 4.8.x No
Boost 1.71.0 1.58.0 No
Clang 5.0+ (C++17 support)
Expat 2.2.7 No Yes
fontconfig 2.12.1 No Yes
FreeType 2.7.1 No Yes (Android only)
GCC 7+ (C++17 support)
HarfBuzz-NG Yes
libevent 2.1.11-stable 2.0.21 No
libpng Yes
MiniUPnPc 2.0.20180203 No
Python (tests) 3.6
qrencode 3.4.4 No
Qt 5.9.8 5.5.1 No
SQLite 3.32.1 3.7.17
XCB Yes (Linux only)
xkbcommon Yes (Linux only)
ZeroMQ 4.3.1 4.0.0 No
zlib 1.2.11 No

Controlling dependencies

Some dependencies are not needed in all configurations. The following are some factors that affect the dependency list.

Options passed to ./configure


Support for Output Descriptors in Bitcoin Core

Since Bitcoin Core v0.17, there is support for Output Descriptors. This is a simple language which can be used to describe collections of output scripts. Supporting RPCs are:

This document describes the language. For the specifics on usage, see the RPC documentation for the functions mentioned above.


Output descriptors currently support:



Descriptors consist of several types of expressions. The top level expression is either a SCRIPT, or SCRIPT#CHECKSUM where CHECKSUM is an 8-character alphanumeric descriptor checksum.

SCRIPT expressions:

KEY expressions:

(Anywhere a ' suffix is permitted to denote hardened derivation, the suffix h can be used instead.)

ADDR expressions are any type of supported address:


Single-key scripts

Many single-key constructions are used in practice, generally including P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH. Many more combinations are imaginable, though they may not be optimal: P2SH-P2PK, P2SH-P2PKH, P2WSH-P2PK, P2WSH-P2PKH, P2SH-P2WSH-P2PK, P2SH-P2WSH-P2PKH.

To describe these, we model these as functions. The functions pk (P2PK), pkh (P2PKH) and wpkh (P2WPKH) take as input a KEY expression, and return the corresponding scriptPubKey. The functions sh (P2SH) and wsh (P2WSH) take as input a SCRIPT expression, and return the script describing P2SH and P2WSH outputs with the input as embedded script. The names of the functions do not contain "p2" for brevity.


Several pieces of software use multi-signature (multisig) scripts based on Bitcoin's OP_CHECKMULTISIG opcode. To support these, we introduce the multi(k,key_1,key_2,...,key_n) and sortedmulti(k,key_1,key_2,...,key_n) functions. They represent a k-of-n multisig policy, where any k out of the n provided KEY expressions must sign.

Key order is significant for multi(). A multi() expression describes a multisig script with keys in the specified order, and in a search for TXOs, it will not match outputs with multisig scriptPubKeys that have the same keys in a different order. Also, to prevent a combinatorial explosion of the search space, if more than one of the multi() key arguments is a BIP32 wildcard path ending in /* or *', the multi() expression only matches multisig scripts with the ith child key from each wildcard path in lockstep, rather than scripts with any combination of child keys from each wildcard path.

Key order does not matter for sortedmulti(). sortedmulti() behaves in the same way as multi() does but the keys are reordered in the resulting script such that they are lexicographically ordered as described in BIP67.

BIP32 derived keys and chains

Most modern wallet software and hardware uses keys that are derived using BIP32 ("HD keys"). We support these directly by permitting strings consisting of an extended public key (commonly referred to as an xpub) plus derivation path anywhere a public key is expected. The derivation path consists of a sequence of 0 or more integers (in the range 0..231-1) each optionally followed by ' or h, and separated by / characters. The string may optionally end with the literal /* or /*' (or /*h) to refer to all unhardened or hardened child keys in a configurable range (by default 0-1000, inclusive).

Whenever a public key is described using a hardened derivation step, the script cannot be computed without access to the corresponding private key.

Key origin identification

In order to describe scripts whose signing keys reside on another device, it may be necessary to identify the master key and derivation path an xpub was derived with.

For example, when following BIP44, it would be useful to describe a change chain directly as xpub.../44'/0'/0'/1/* where xpub... corresponds with the master key m. Unfortunately, since there are hardened derivation steps that follow the xpub, this descriptor does not let you compute scripts without access to the corresponding private keys. Instead, it should be written as xpub.../1/*, where xpub corresponds to m/44'/0'/0'.

When interacting with a hardware device, it may be necessary to include the entire path from the master down. BIP174 standardizes this by providing the master key fingerprint (first 32 bit of the Hash160 of the master pubkey), plus all derivation steps. To support constructing these, we permit providing this key origin information inside the descriptor language, even though it does not affect the actual scriptPubKeys it refers to.

Every public key can be prefixed by an 8-character hexadecimal fingerprint plus optional derivation steps (hardened and unhardened) surrounded by brackets, identifying the master and derivation path the key or xpub that follows was derived with.

Note that the fingerprint of the parent only serves as a fast way to detect parent and child nodes in software, and software must be willing to deal with collisions.

Including private keys

Often it is useful to communicate a description of scripts along with the necessary private keys. For this reason, anywhere a public key or xpub is supported, a private key in WIF format or xprv may be provided instead. This is useful when private keys are necessary for hardened derivation steps, or for dumping wallet descriptors including private key material.

Compatibility with old wallets

In order to easily represent the sets of scripts currently supported by existing Bitcoin Core wallets, a convenience function combo is provided, which takes as input a public key, and describes a set of P2PK, P2PKH, P2WPKH, and P2SH-P2WPH scripts for that key. In case the key is uncompressed, the set only includes P2PK and P2PKH scripts.


Descriptors can optionally be suffixed with a checksum to protect against typos or copy-paste errors.

These checksums consist of 8 alphanumeric characters. As long as errors are restricted to substituting characters in 0123456789()[],'/*abcdefgh@:$%{} for others in that set and changes in letter case, up to 4 errors will always be detected in descriptors up to 501 characters, and up to 3 errors in longer ones. For larger numbers of errors, or other types of errors, there is a roughly 1 in a trillion chance of not detecting the errors.

All RPCs in Bitcoin Core will include the checksum in their output. Only certain RPCs require checksums on input, including deriveaddress and importmulti. The checksum for a descriptor without one can be computed using the getdescriptorinfo RPC. Developer Notes

Table of Contents

Coding Style (General)

Various coding styles have been used during the history of the codebase, and the result is not very consistent. However, we're now trying to converge to a single style, which is specified below. When writing patches, favor the new style over attempting to mimic the surrounding style, except for move-only commits.

Do not submit patches solely to modify the style of existing code.

Coding Style (C++)

Block style example:

int g_count = 0;

namespace foo {
class Class
    std::string m_name;

    bool Function(const std::string& s, int n)
        // Comment summarising what this section of code does
        for (int i = 0; i < n; ++i) {
            int total_sum = 0;
            // When something fails, return early
            if (!Something()) return false;
            if (SomethingElse(i)) {
                total_sum += ComputeSomething(g_count);
            } else {
                DoSomething(m_name, total_sum);

        // Success return is usually at the end
        return true;
} // namespace foo

Coding Style (Python)

Refer to /test/functional/README.html#style-guidelines.

Coding Style (Doxygen-compatible comments)

Bitcoin Core uses Doxygen to generate its official documentation.

Use Doxygen-compatible comment blocks for functions, methods, and fields.

For example, to describe a function use:

 * ... Description ...
 * @param[in]  arg1 input description...
 * @param[in]  arg2 input description...
 * @param[out] arg3 output description...
 * @return Return cases...
 * @throws Error type and cases...
 * @pre  Pre-condition for function...
 * @post Post-condition for function...
bool function(int arg1, const char *arg2, std::string& arg3)

A complete list of @xxx commands can be found at http://www.doxygen.nl/manual/commands.html. As Doxygen recognizes the comments by the delimiters (/** and */ in this case), you don't need to provide any commands for a comment to be valid; just a description text is fine.

To describe a class, use the same construct above the class definition:

 * Alerts are for notifying old versions if they become too obsolete and
 * need to upgrade. The message is displayed in the status bar.
 * @see GetWarnings()
class CAlert

To describe a member or variable use:

//! Description before the member
int var;


int var; //!< Description after the member

Also OK:

/// ... Description ...
bool function2(int arg1, const char *arg2)

Not picked up by Doxygen:

// ... Description ...

Also not picked up by Doxygen:

 * ... Description ...

A full list of comment syntaxes picked up by Doxygen can be found at http://www.doxygen.nl/manual/docblocks.html, but the above styles are favored.


Generating Documentation

The documentation can be generated with make docs and cleaned up with make clean-docs. The resulting files are located in doc/doxygen/html; open index.html in that directory to view the homepage.

Before running make docs, you'll need to install these dependencies:

Linux: sudo apt install doxygen graphviz

MacOS: brew install doxygen graphviz

Development tips and tricks

Compiling for debugging

Run configure with --enable-debug to add additional compiler flags that produce better debugging builds.

Compiling for gprof profiling

Run configure with the --enable-gprof option, then make.


If the code is behaving strangely, take a look in the debug.log file in the data directory; error and debugging messages are written there.

The -debug=... command-line option controls debugging; running with just -debug or -debug=1 will turn on all categories (and give you a very large debug.log file).

The Qt code routes qDebug() output to debug.log under category "qt": run with -debug=qt to see it.

Testnet and Regtest modes

Run with the -testnet option to run with "play bitcoins" on the test network, if you are testing multi-machine code that needs to operate across the internet.

If you are testing something that can run on one machine, run with the -regtest option. In regression test mode, blocks can be created on-demand; see test/functional/ for tests that run in -regtest mode.


Bitcoin Core is a multi-threaded application, and deadlocks or other multi-threading bugs can be very difficult to track down. The --enable-debug configure option adds -DDEBUG_LOCKORDER to the compiler flags. This inserts run-time checks to keep track of which locks are held and adds warnings to the debug.log file if inconsistencies are detected.

Assertions and Checks

The util file src/util/check.h offers helpers to protect against coding and internal logic bugs. They must never be used to validate user, network or any other input.

Valgrind suppressions file

Valgrind is a programming tool for memory debugging, memory leak detection, and profiling. The repo contains a Valgrind suppressions file (valgrind.supp) which includes known Valgrind warnings in our dependencies that cannot be fixed in-tree. Example use:

$ valgrind --suppressions=contrib/valgrind.supp src/test/test_bitcoin
$ valgrind --suppressions=contrib/valgrind.supp --leak-check=full \
      --show-leak-kinds=all src/test/test_bitcoin --log_level=test_suite
$ valgrind -v --leak-check=full src/bitcoind -printtoconsole
$ ./test/functional/test_runner.py --valgrind

Compiling for test coverage

LCOV can be used to generate a test coverage report based upon make check execution. LCOV must be installed on your system (e.g. the lcov package on Debian/Ubuntu).

To enable LCOV report generation during test runs:

./configure --enable-lcov
make cov

# A coverage report will now be accessible at `./test_bitcoin.coverage/index.html`.

Performance profiling with perf

Profiling is a good way to get a precise idea of where time is being spent in code. One tool for doing profiling on Linux platforms is called perf, and has been integrated into the functional test framework. Perf can observe a running process and sample (at some frequency) where its execution is.

Perf installation is contingent on which kernel version you're running; see this thread for specific instructions.

Certain kernel parameters may need to be set for perf to be able to inspect the running process's stack.

$ sudo sysctl -w kernel.perf_event_paranoid=-1
$ sudo sysctl -w kernel.kptr_restrict=0

Make sure you understand the security trade-offs of setting these kernel parameters.

To profile a running bitcoind process for 60 seconds, you could use an invocation of perf record like this:

$ perf record \
    -g --call-graph dwarf --per-thread -F 140 \
    -p `pgrep bitcoind` -- sleep 60

You could then analyze the results by running:

perf report --stdio | c++filt | less

or using a graphical tool like Hotspot.

See the functional test documentation for how to invoke perf within tests.


Bitcoin Core can be compiled with various "sanitizers" enabled, which add instrumentation for issues regarding things like memory safety, thread race conditions, or undefined behavior. This is controlled with the --with-sanitizers configure flag, which should be a comma separated list of sanitizers to enable. The sanitizer list should correspond to supported -fsanitize= options in your compiler. These sanitizers have runtime overhead, so they are most useful when testing changes or producing debugging builds.

Some examples:

# Enable both the address sanitizer and the undefined behavior sanitizer
./configure --with-sanitizers=address,undefined

# Enable the thread sanitizer
./configure --with-sanitizers=thread

If you are compiling with GCC you will typically need to install corresponding "san" libraries to actually compile with these flags, e.g. libasan for the address sanitizer, libtsan for the thread sanitizer, and libubsan for the undefined sanitizer. If you are missing required libraries, the configure script will fail with a linker error when testing the sanitizer flags.

The test suite should pass cleanly with the thread and undefined sanitizers, but there are a number of known problems when using the address sanitizer. The address sanitizer is known to fail in sha256_sse4::Transform which makes it unusable unless you also use --disable-asm when running configure. We would like to fix sanitizer issues, so please send pull requests if you can fix any errors found by the address sanitizer (or any other sanitizer).

Not all sanitizer options can be enabled at the same time, e.g. trying to build with --with-sanitizers=address,thread will fail in the configure script as these sanitizers are mutually incompatible. Refer to your compiler manual to learn more about these options and which sanitizers are supported by your compiler.

Additional resources:

Locking/mutex usage notes

The code is multi-threaded and uses mutexes and the LOCK and TRY_LOCK macros to protect data structures.

Deadlocks due to inconsistent lock ordering (thread 1 locks cs_main and then cs_wallet, while thread 2 locks them in the opposite order: result, deadlock as each waits for the other to release its lock) are a problem. Compile with -DDEBUG_LOCKORDER (or use --enable-debug) to get lock order inconsistencies reported in the debug.log file.

Re-architecting the core code so there are better-defined interfaces between the various components is a goal, with any necessary locking done by the components (e.g. see the self-contained FillableSigningProvider class and its cs_KeyStore lock for example).


Ignoring IDE/editor files

In closed-source environments in which everyone uses the same IDE, it is common to add temporary files it produces to the project-wide .gitignore file.

However, in open source software such as Bitcoin Core, where everyone uses their own editors/IDE/tools, it is less common. Only you know what files your editor produces and this may change from version to version. The canonical way to do this is thus to create your local gitignore. Add this to ~/.gitconfig:

        excludesfile = /home/.../.gitignore_global

(alternatively, type the command git config --global core.excludesfile ~/.gitignore_global on a terminal)

Then put your favourite tool's temporary filenames in that file, e.g.

# NetBeans

Another option is to create a per-repository excludes file .git/info/exclude. These are not committed but apply only to one repository.

If a set of tools is used by the build system or scripts the repository (for example, lcov) it is perfectly acceptable to add its files to .gitignore and commit them.

Development guidelines

A few non-style-related recommendations for developers, as well as points to pay attention to for reviewers of Bitcoin Core code.

General Bitcoin Core


General C++

For general C++ guidelines, you may refer to the C++ Core Guidelines.

Common misconceptions are clarified in those sections:

C++ data structures

class A
    uint32_t m_count{0};
void Foo(Span<const int> data);

std::vector<int> vec{1,2,3};
enum class Tabs {

int GetInt(Tabs tab)
    switch (tab) {
    case Tabs::INFO: return 0;
    case Tabs::CONSOLE: return 1;
    case Tabs::GRAPH: return 2;
    case Tabs::PEERS: return 3;
    } // no default case, so the compiler can warn about missing cases

Rationale: The comment documents skipping default: label, and it complies with clang-format rules. The assertion prevents firing of -Wreturn-type warning on some compilers.

Strings and formatting


Although the shadowing warning (-Wshadow) is not enabled by default (it prevents issues arising from using a different variable with the same name), please name variables so that their names do not shadow variables defined in the source code.

When using nested cycles, do not name the inner cycle variable the same as in the upper cycle, etc.

Threads and synchronization

// txmempool.h
class CTxMemPool
    mutable RecursiveMutex cs;
    void UpdateTransactionsFromBlock(...) EXCLUSIVE_LOCKS_REQUIRED(::cs_main, cs);

// txmempool.cpp
void CTxMemPool::UpdateTransactionsFromBlock(...)
// validation.h
class ChainstateManager
    bool ProcessNewBlock(...) EXCLUSIVE_LOCKS_REQUIRED(!::cs_main);

// validation.cpp
bool ChainstateManager::ProcessNewBlock(...)
    TRY_LOCK(cs_vNodes, lockNodes);


TRY_LOCK(cs_vNodes, lockNodes);



#!/usr/bin/env bash



Source code organization

namespace mynamespace {
} // namespace mynamespace

namespace {
} // namespace



Several parts of the repository are subtrees of software maintained elsewhere.

Some of these are maintained by active developers of Bitcoin Core, in which case changes should probably go directly upstream without being PRed directly against the project. They will be merged back in the next subtree merge.

Others are external projects without a tight relationship with our project. Changes to these should also be sent upstream, but bugfixes may also be prudent to PR against Bitcoin Core so that they can be integrated quickly. Cosmetic changes should be purely taken upstream.

There is a tool in test/lint/git-subtree-check.sh (instructions) to check a subtree directory for consistency with its upstream repository.

Current subtrees include:

Upgrading LevelDB

Extra care must be taken when upgrading LevelDB. This section explains issues you must be aware of.

File Descriptor Counts

In most configurations, we use the default LevelDB value for max_open_files, which is 1000 at the time of this writing. If LevelDB actually uses this many file descriptors, it will cause problems with Bitcoin's select() loop, because it may cause new sockets to be created where the fd value is >= 1024. For this reason, on 64-bit Unix systems, we rely on an internal LevelDB optimization that uses mmap() + close() to open table files without actually retaining references to the table file descriptors. If you are upgrading LevelDB, you must sanity check the changes to make sure that this assumption remains valid.

In addition to reviewing the upstream changes in env_posix.cc, you can use lsof to check this. For example, on Linux this command will show open .ldb file counts:

$ lsof -p $(pidof bitcoind) |\
    awk 'BEGIN { fd=0; mem=0; } /ldb$/ { if ($4 == "mem") mem++; else fd++ } END { printf "mem = %s, fd = %s\n", mem, fd}'
mem = 119, fd = 0

The mem value shows how many files are mmap'ed, and the fd value shows you many file descriptors these files are using. You should check that fd is a small number (usually 0 on 64-bit hosts).

See the notes in the SetMaxOpenFiles() function in dbwrapper.cc for more details.

Consensus Compatibility

It is possible for LevelDB changes to inadvertently change consensus compatibility between nodes. This happened in Bitcoin 0.8 (when LevelDB was first introduced). When upgrading LevelDB, you should review the upstream changes to check for issues affecting consensus compatibility.

For example, if LevelDB had a bug that accidentally prevented a key from being returned in an edge case, and that bug was fixed upstream, the bug "fix" would be an incompatible consensus change. In this situation, the correct behavior would be to revert the upstream fix before applying the updates to Bitcoin's copy of LevelDB. In general, you should be wary of any upstream changes affecting what data is returned from LevelDB queries.

Scripted diffs

For reformatting and refactoring commits where the changes can be easily automated using a bash script, we use scripted-diff commits. The bash script is included in the commit message and our CI job checks that the result of the script is identical to the commit. This aids reviewers since they can verify that the script does exactly what it is supposed to do. It is also helpful for rebasing (since the same script can just be re-run on the new master commit).

To create a scripted-diff:

The scripted-diff is verified by the tool test/lint/commit-script-check.sh. The tool's default behavior, when supplied with a commit is to verify all scripted-diffs from the beginning of time up to said commit. Internally, the tool passes the first supplied argument to git rev-list --reverse to determine which commits to verify script-diffs for, ignoring commits that don't conform to the commit message format described above.

For development, it might be more convenient to verify all scripted-diffs in a range A..B, for example:

test/lint/commit-script-check.sh origin/master..HEAD

Suggestions and examples

If you need to replace in multiple files, prefer git ls-files to find or globbing, and git grep to grep, to avoid changing files that are not under version control.

For efficient replacement scripts, reduce the selection to the files that potentially need to be modified, so for example, instead of a blanket git ls-files src | xargs sed -i s/apple/orange/, use git grep -l apple src | xargs sed -i s/apple/orange/.

Also, it is good to keep the selection of files as specific as possible — for example, replace only in directories where you expect replacements — because it reduces the risk that a rebase of your commit by re-running the script will introduce accidental changes.

Some good examples of scripted-diff:

To find all previous uses of scripted diffs in the repository, do:

git log --grep="-BEGIN VERIFY SCRIPT-"

Release notes

Release notes should be written for any PR that:

Release notes should be added to a PR-specific release note file at /doc/release-notes-<PR number>.html to avoid conflicts between multiple PRs. All release-notes* files are merged into a single /doc/release-notes.html file prior to the release.

RPC interface guidelines

A few guidelines for introducing and reviewing new RPC interfaces:

Internal interface guidelines

Internal interfaces between parts of the codebase that are meant to be independent (node, wallet, GUI), are defined in src/interfaces/. The main interface classes defined there are interfaces::Chain, used by wallet to access the node's latest chain state, interfaces::Node, used by the GUI to control the node, and interfaces::Wallet, used by the GUI to control an individual wallet. There are also more specialized interface types like interfaces::Handler interfaces::ChainClient passed to and from various interface methods.

Interface classes are written in a particular style so node, wallet, and GUI code doesn't need to run in the same process, and so the class declarations work more easily with tools and libraries supporting interprocess communication:

Bitcoin Core attempts to minimize the level of trust in DNS seeds, but DNS seeds still pose a small amount of risk for the network. As such, DNS seeds must be run by entities which have some minimum level of trust within the Bitcoin community.

Other implementations of Bitcoin software may also use the same seeds and may be more exposed. In light of this exposure, this document establishes some basic expectations for operating dnsseeds.

  1. A DNS seed operating organization or person is expected to follow good host security practices, maintain control of applicable infrastructure, and not sell or transfer control of the DNS seed. Any hosting services contracted by the operator are equally expected to uphold these expectations.

  2. The DNS seed results must consist exclusively of fairly selected and functioning Bitcoin nodes from the public network to the best of the operator's understanding and capability.

  3. For the avoidance of doubt, the results may be randomized but must not single-out any group of hosts to receive different results unless due to an urgent technical necessity and disclosed.

  4. The results may not be served with a DNS TTL of less than one minute.

  5. Any logging of DNS queries should be only that which is necessary for the operation of the service or urgent health of the Bitcoin network and must not be retained longer than necessary nor disclosed to any third party.

  6. Information gathered as a result of the operators node-spidering (not from DNS queries) may be freely published or retained, but only if this data was not made more complete by biasing node connectivity (a violation of expectation (1)).

  7. Operators are encouraged, but not required, to publicly document the details of their operating practices.

  8. A reachable email contact address must be published for inquiries related to the DNS seed operation.

If these expectations cannot be satisfied the operator should discontinue providing services and contact the active Bitcoin Core development team as well as posting on bitcoin-dev.

Behavior outside of these expectations may be reasonable in some situations but should be discussed in public in advance.

See also

Bitcoin Core file system


Data directory location

The data directory is the default location where the Bitcoin Core files are stored.

  1. The default data directory paths for supported platforms are:
Platform Data directory path
Linux $HOME/.bitcoin/
macOS $HOME/Library/Application Support/Bitcoin/
Windows %APPDATA%\Bitcoin\ [1]
  1. A custom data directory path can be specified with the -datadir option.

  2. All content of the data directory, except for bitcoin.conf file, is chain-specific. This means the actual data directory paths for non-mainnet cases differ:

Chain option Data directory path
-chain=main (default) path_to_datadir/
-chain=test or -testnet path_to_datadir/testnet3/
-chain=signet or -signet path_to_datadir/signet/
-chain=regtest or -regtest path_to_datadir/regtest/

Data directory layout

Subdirectory File(s) Description
blocks/ Blocks directory; can be specified by -blocksdir option (except for blocks/index/)
blocks/index/ LevelDB database Block index; -blocksdir option does not affect this path
blocks/ blkNNNNN.dat[2] Actual Bitcoin blocks (in network format, dumped in raw on disk, 128 MiB per file)
blocks/ revNNNNN.dat[2] Block undo data (custom format)
chainstate/ LevelDB database Blockchain state (a compact representation of all currently unspent transaction outputs (UTXOs) and metadata about the transactions they are from)
indexes/txindex/ LevelDB database Transaction index; optional, used if -txindex=1
indexes/blockfilter/basic/db/ LevelDB database Blockfilter index LevelDB database for the basic filtertype; optional, used if -blockfilterindex=basic
indexes/blockfilter/basic/ fltrNNNNN.dat[2] Blockfilter index filters for the basic filtertype; optional, used if -blockfilterindex=basic
wallets/ Contains wallets; can be specified by -walletdir option; if wallets/ subdirectory does not exist, wallets reside in the data directory
./ anchors.dat Anchor IP address database, created on shutdown and deleted at startup. Anchors are last known outgoing block-relay-only peers that are tried to re-connect to on startup
./ banlist.dat Stores the IPs/subnets of banned nodes
./ bitcoin.conf User-defined configuration settings for bitcoind or bitcoin-qt. File is not written to by the software and must be created manually. Path can be specified by -conf option
./ bitcoind.pid Stores the process ID (PID) of bitcoind or bitcoin-qt while running; created at start and deleted on shutdown; can be specified by -pid option
./ debug.log Contains debug information and general logging generated by bitcoind or bitcoin-qt; can be specified by -debuglogfile option
./ fee_estimates.dat Stores statistics used to estimate minimum transaction fees and priorities required for confirmation
./ guisettings.ini.bak Backup of former GUI settings after -resetguisettings option is used
./ ip_asn.map IP addresses to Autonomous System Numbers (ASNs) mapping used for bucketing of the peers; path can be specified with the -asmap option
./ mempool.dat Dump of the mempool's transactions
./ onion_v3_private_key Cached Tor onion service private key for -listenonion option
./ peers.dat Peer IP address database (custom format)
./ settings.json Read-write settings set through GUI or RPC interfaces, augmenting manual settings from bitcoin.conf. File is created automatically if read-write settings storage is not disabled with -nosettings option. Path can be specified with -settings option
./ .cookie Session RPC authentication cookie; if used, created at start and deleted on shutdown; can be specified by -rpccookiefile option
./ .lock Data directory lock file

Multi-wallet environment

Wallets are Berkeley DB (BDB) or SQLite databases.

  1. Each user-defined wallet named "wallet_name" resides in the wallets/wallet_name/ subdirectory.

  2. The default (unnamed) wallet resides in wallets/ subdirectory; if the latter does not exist, the wallet resides in the data directory.

  3. A wallet database path can be specified with the -wallet option.

  4. wallet.dat files must not be shared across different node instances, as that can result in key-reuse and double-spends due the lack of synchronization between instances.

  5. Any copy or backup of the wallet should be done through a backupwallet call in order to update and lock the wallet, preventing any file corruption caused by updates during the copy.

Berkeley DB database based wallets

Subdirectory File(s) Description
database/ BDB logging files Part of BDB environment; created at start and deleted on shutdown; a user must keep it as safe as personal wallet wallet.dat
./ db.log BDB error file
./ wallet.dat Personal wallet (a BDB database) with keys and transactions
./ .walletlock BDB wallet lock file

SQLite database based wallets

Subdirectory File Description
./ wallet.dat Personal wallet (a SQLite database) with keys and transactions
./ wallet.dat-journal SQLite Rollback Journal file for wallet.dat. Usually created at start and deleted on shutdown. A user must keep it as safe as the wallet.dat file.

GUI settings

bitcoin-qt uses QSettings class; this implies platform-specific locations where application settings are stored.

Legacy subdirectories and files

These subdirectories and files are no longer used by the Bitcoin Core:

Path Description Repository notes
blktree/ Blockchain index; replaced by blocks/index/ in 0.8.0 PR #2231, 8fdc94cc
coins/ Unspent transaction output database; replaced by chainstate/ in 0.8.0 PR #2231, 8fdc94cc
blkindex.dat Blockchain index BDB database; replaced by {chainstate/, blocks/index/, blocks/revNNNNN.dat[2]} in 0.8.0 PR #1677
blk000?.dat Block data (custom format, 2 GiB per file); replaced by blocks/blkNNNNN.dat[2] in 0.8.0 PR #1677
addr.dat Peer IP address BDB database; replaced by peers.dat in 0.7.0 PR #1198, 928d3a01
onion_private_key Cached Tor onion service private key for -listenonion option. Was used for Tor v2 services; replaced by onion_v3_private_key in 0.21.0 PR #19954


1. The / (slash, U+002F) is used as the platform-independent path component separator in this document.

2. NNNNN matches [0-9]{5} regex.

Fuzzing Bitcoin Core using libFuzzer

Quickstart guide

To quickly get started fuzzing Bitcoin Core using libFuzzer:

$ git clone https://github.com/bitcoin/bitcoin
$ cd bitcoin/
$ ./autogen.sh
$ CC=clang CXX=clang++ ./configure --enable-fuzz --with-sanitizers=address,fuzzer,undefined
# macOS users: If you have problem with this step then make sure to read "macOS hints for
# libFuzzer" on https://github.com/bitcoin/bitcoin/blob/master/doc/fuzzing.html#macos-hints-for-libfuzzer
$ make
$ FUZZ=process_message src/test/fuzz/fuzz
# abort fuzzing using ctrl-c

Fuzzing harnesses, fuzzing output and fuzzing corpora

process_message is a fuzzing harness for the ProcessMessage(...) function (net_processing). The available fuzzing harnesses are found in src/test/fuzz/.

The fuzzer will output NEW every time it has created a test input that covers new areas of the code under test. For more information on how to interpret the fuzzer output, see the libFuzzer documentation.

If you specify a corpus directory then any new coverage increasing inputs will be saved there:

$ mkdir -p process_message-seeded-from-thin-air/
$ FUZZ=process_message src/test/fuzz/fuzz process_message-seeded-from-thin-air/
INFO: Seed: 840522292
INFO: Loaded 1 modules   (424174 inline 8-bit counters): 424174 [0x55e121ef9ab8, 0x55e121f613a6),
INFO: Loaded 1 PC tables (424174 PCs): 424174 [0x55e121f613a8,0x55e1225da288),
INFO:        0 files found in process_message-seeded-from-thin-air/
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2      INITED cov: 94 ft: 95 corp: 1/1b exec/s: 0 rss: 150Mb
#3      NEW    cov: 95 ft: 96 corp: 2/3b lim: 4 exec/s: 0 rss: 150Mb L: 2/2 MS: 1 InsertByte-
#4      NEW    cov: 96 ft: 98 corp: 3/7b lim: 4 exec/s: 0 rss: 150Mb L: 4/4 MS: 1 CrossOver-
#21     NEW    cov: 96 ft: 100 corp: 4/11b lim: 4 exec/s: 0 rss: 150Mb L: 4/4 MS: 2 ChangeBit-CrossOver-
#324    NEW    cov: 101 ft: 105 corp: 5/12b lim: 6 exec/s: 0 rss: 150Mb L: 6/6 MS: 5 CrossOver-ChangeBit-CopyPart-ChangeBit-ChangeBinInt-
#1239   REDUCE cov: 102 ft: 106 corp: 6/24b lim: 14 exec/s: 0 rss: 150Mb L: 13/13 MS: 5 ChangeBit-CrossOver-EraseBytes-ChangeBit-InsertRepeatedBytes-
#1272   REDUCE cov: 102 ft: 106 corp: 6/23b lim: 14 exec/s: 0 rss: 150Mb L: 12/12 MS: 3 ChangeBinInt-ChangeBit-EraseBytes-
        NEW_FUNC[1/677]: 0x55e11f456690 in std::_Function_base::~_Function_base() /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/std_function.h:255
        NEW_FUNC[2/677]: 0x55e11f465800 in CDataStream::CDataStream(std::vector<unsigned char, std::allocator<unsigned char> > const&, int, int) src/./streams.h:248
#2125   REDUCE cov: 4820 ft: 4867 corp: 7/29b lim: 21 exec/s: 0 rss: 155Mb L: 6/12 MS: 2 CopyPart-CMP- DE: "block"-
        NEW_FUNC[1/9]: 0x55e11f64d790 in std::_Rb_tree<uint256, std::pair<uint256 const, std::chrono::duration<long, std::ratio<1l, 1000000l> > >, std::_Select1st<std::pair<uint256 const, std::chrono::duration<long, std::ratio<1l, 1000000l> > > >, std::less<uint256>, std::allocator<std::pair<uint256 const, std::chrono::duration<long, std::ratio<1l, 1000000l> > > > >::~_Rb_tree() /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_tree.h:972
        NEW_FUNC[2/9]: 0x55e11f64d870 in std::_Rb_tree<uint256, std::pair<uint256 const, std::chrono::duration<long, std::ratio<1l, 1000000l> > >, std::_Select1st<std::pair<uint256 const, std::chrono::duration<long, std::ratio<1l, 1000000l> > > >, std::less<uint256>, std::allocator<std::pair<uint256 const, std::chrono::duration<long, std::ratio<1l, 1000000l> > > > >::_M_erase(std::_Rb_tree_node<std::pair<uint256 const, std::chrono::duration<long, std::ratio<1l, 1000000l> > > >*) /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_tree.h:1875
#2228   NEW    cov: 4898 ft: 4971 corp: 8/35b lim: 21 exec/s: 0 rss: 156Mb L: 6/12 MS: 3 EraseBytes-CopyPart-PersAutoDict- DE: "block"-
        NEW_FUNC[1/5]: 0x55e11f46df70 in std::enable_if<__and_<std::allocator_traits<zero_after_free_allocator<char> >::__construct_helper<char, unsigned char const&>::type>::value, void>::type std::allocator_traits<zero_after_free_allocator<char> >::_S_construct<char, unsigned char const&>(zero_after_free_allocator<char>&, char*, unsigned char const&) /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/alloc_traits.h:243
        NEW_FUNC[2/5]: 0x55e11f477390 in std::vector<unsigned char, std::allocator<unsigned char> >::data() /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_vector.h:1056
#2456   NEW    cov: 4933 ft: 5042 corp: 9/55b lim: 21 exec/s: 0 rss: 160Mb L: 20/20 MS: 3 ChangeByte-InsertRepeatedBytes-PersAutoDict- DE: "block"-
#2467   NEW    cov: 4933 ft: 5043 corp: 10/76b lim: 21 exec/s: 0 rss: 161Mb L: 21/21 MS: 1 InsertByte-
#4215   NEW    cov: 4941 ft: 5129 corp: 17/205b lim: 29 exec/s: 4215 rss: 350Mb L: 29/29 MS: 5 InsertByte-ChangeBit-CopyPart-InsertRepeatedBytes-CrossOver-
#4567   REDUCE cov: 4941 ft: 5129 corp: 17/204b lim: 29 exec/s: 4567 rss: 404Mb L: 24/29 MS: 2 ChangeByte-EraseBytes-
#6642   NEW    cov: 4941 ft: 5138 corp: 18/244b lim: 43 exec/s: 2214 rss: 450Mb L: 43/43 MS: 3 CopyPart-CMP-CrossOver- DE: "verack"-
# abort fuzzing using ctrl-c
$ ls process_message-seeded-from-thin-air/
349ac589fc66a09abc0b72bb4ae445a7a19e2cd8 4df479f1f421f2ea64b383cd4919a272604087a7
a640312c98dcc55d6744730c33e41c5168c55f09 b135de16e4709558c0797c15f86046d31c5d86d7
c000f7b41b05139de8b63f4cbf7d1ad4c6e2aa7f fc52cc00ec1eb1c08470e69f809ae4993fa70082
$ cat --show-nonprinting process_message-seeded-from-thin-air/349ac589fc66a09abc0b72bb4ae445a7a19e2cd8

In this case the fuzzer managed to create a block message which when passed to ProcessMessage(...) increased coverage.

The project's collection of seed corpora is found in the bitcoin-core/qa-assets repo.

To fuzz process_message using the bitcoin-core/qa-assets seed corpus:

$ git clone https://github.com/bitcoin-core/qa-assets
$ FUZZ=process_message src/test/fuzz/fuzz qa-assets/fuzz_seed_corpus/process_message/
INFO: Seed: 1346407872
INFO: Loaded 1 modules   (424174 inline 8-bit counters): 424174 [0x55d8a9004ab8, 0x55d8a906c3a6),
INFO: Loaded 1 PC tables (424174 PCs): 424174 [0x55d8a906c3a8,0x55d8a96e5288),
INFO:      991 files found in qa-assets/fuzz_seed_corpus/process_message/
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: seed corpus: files: 991 min: 1b max: 1858b total: 288291b rss: 150Mb
#993    INITED cov: 7063 ft: 8236 corp: 25/3821b exec/s: 0 rss: 181Mb

If you find coverage increasing inputs when fuzzing you are highly encouraged to submit them for inclusion in the bitcoin-core/qa-assets repo.

Every single pull request submitted against the Bitcoin Core repo is automatically tested against all inputs in the bitcoin-core/qa-assets repo. Contributing new coverage increasing inputs is an easy way to help make Bitcoin Core more robust.

macOS hints for libFuzzer

The default Clang/LLVM version supplied by Apple on macOS does not include fuzzing libraries, so macOS users will need to install a full version, for example using brew install llvm.

Should you run into problems with the address sanitizer, it is possible you may need to run ./configure with --disable-asm to avoid errors with certain assembly code from Bitcoin Core's code. See developer notes on sanitizers for more information.

You may also need to take care of giving the correct path for clang and clang++, like CC=/path/to/clang CXX=/path/to/clang++ if the non-systems clang does not come first in your path.

Full configure that was tested on macOS Catalina with brew installed llvm:

./configure --enable-fuzz --with-sanitizers=fuzzer,address,undefined CC=/usr/local/opt/llvm/bin/clang CXX=/usr/local/opt/llvm/bin/clang++ --disable-asm

Read the libFuzzer documentation for more information. This libFuzzer tutorial might also be of interest.

Fuzzing Bitcoin Core using american fuzzy lop (afl-fuzz)

Quickstart guide

To quickly get started fuzzing Bitcoin Core using afl-fuzz:

$ git clone https://github.com/bitcoin/bitcoin
$ cd bitcoin/
$ git clone https://github.com/google/afl
$ make -C afl/
$ make -C afl/llvm_mode/
$ ./autogen.sh
# It is possible to compile with afl-gcc and afl-g++ instead of afl-clang. However, running afl-fuzz
# may require more memory via the -m flag.
$ CC=$(pwd)/afl/afl-clang-fast CXX=$(pwd)/afl/afl-clang-fast++ ./configure --enable-fuzz
$ make
# For macOS you may need to ignore x86 compilation checks when running "make". If so,
# try compiling using: AFL_NO_X86=1 make
$ mkdir -p inputs/ outputs/
$ echo A > inputs/thin-air-input
$ FUZZ=bech32 afl/afl-fuzz -i inputs/ -o outputs/ -- src/test/fuzz/fuzz
# You may have to change a few kernel parameters to test optimally - afl-fuzz
# will print an error and suggestion if so.

Read the afl-fuzz documentation for more information.

Fuzzing Bitcoin Core using Honggfuzz

Quickstart guide

To quickly get started fuzzing Bitcoin Core using Honggfuzz:

$ git clone https://github.com/bitcoin/bitcoin
$ cd bitcoin/
$ ./autogen.sh
$ git clone https://github.com/google/honggfuzz
$ cd honggfuzz/
$ make
$ cd ..
$ CC=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang CXX=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang++ ./configure --enable-fuzz --with-sanitizers=address,undefined
$ make
$ mkdir -p inputs/
$ FUZZ=process_message honggfuzz/honggfuzz -i inputs/ -- src/test/fuzz/fuzz

Read the Honggfuzz documentation for more information. Gitian building

This file was moved to the Bitcoin Core documentation repository at https://github.com/bitcoin-core/docs. Sample init scripts and service configuration for bitcoind

Sample scripts and configuration files for syst.html, Upstart and OpenRC can be found in the contrib/init folder.

contrib/init/bitcoind.service:    syst.html service unit configuration
contrib/init/bitcoind.openrc:     OpenRC compatible SysV style init script
contrib/init/bitcoind.openrcconf: OpenRC conf.d file
contrib/init/bitcoind.conf:       Upstart service configuration file
contrib/init/bitcoind.init:       CentOS compatible SysV style init script

Service User

All three Linux startup configurations assume the existence of a "bitcoin" user and group. They must be created before attempting to use these scripts. The macOS configuration assumes bitcoind will be set up for the current user.


Running bitcoind as a daemon does not require any manual configuration. You may set the rpcauth setting in the bitcoin.conf configuration file to override the default behaviour of using a special cookie for authentication.

This password does not have to be remembered or typed as it is mostly used as a fixed token that bitcoind and client programs read from the configuration file, however it is recommended that a strong and secure password be used as this password is security critical to securing the wallet should the wallet be enabled.

If bitcoind is run with the "-server" flag (set by default), and no rpcpassword is set, it will use a special cookie file for authentication. The cookie is generated with random content when the daemon starts, and deleted when it exits. Read access to this file controls who can access it through RPC.

By default the cookie is stored in the data directory, but it's location can be overridden with the option '-rpccookiefile'.

This allows for running bitcoind without having to do any manual configuration.

conf, pid, and wallet accept relative paths which are interpreted as relative to the data directory. wallet only supports relative paths.

For an example configuration file that describes the configuration settings, see share/examples/bitcoin.conf.



All three configurations assume several paths that might need to be adjusted.

Binary: /usr/bin/bitcoind Configuration file: /etc/bitcoin/bitcoin.conf Data directory: /var/lib/bitcoind PID file: /var/run/bitcoind/bitcoind.pid (OpenRC and Upstart) or /run/bitcoind/bitcoind.pid (syst.html) Lock file: /var/lock/subsys/bitcoind (CentOS)

The PID directory (if applicable) and data directory should both be owned by the bitcoin user and group. It is advised for security reasons to make the configuration file and data directory only readable by the bitcoin user and group. Access to bitcoin-cli and other bitcoind rpc clients can then be controlled by group membership.

NOTE: When using the syst.html .service file, the creation of the aforementioned directories and the setting of their permissions is automatically handled by syst.html. Directories are given a permission of 710, giving the bitcoin group access to files under it if the files themselves give permission to the bitcoin group to do so (e.g. when -sysperms is specified). This does not allow for the listing of files under the directory.

NOTE: It is not currently possible to override datadir in /etc/bitcoin/bitcoin.conf with the current syst.html, OpenRC, and Upstart init files out-of-the-box. This is because the command line options specified in the init files take precedence over the configurations in /etc/bitcoin/bitcoin.conf. However, some init systems have their own configuration mechanisms that would allow for overriding the command line options specified in the init files (e.g. setting BITCOIND_DATADIR for OpenRC).


Binary: /usr/local/bin/bitcoind Configuration file: ~/Library/Application Support/Bitcoin/bitcoin.conf Data directory: ~/Library/Application Support/Bitcoin Lock file: ~/Library/Application Support/Bitcoin/.lock

Installing Service Configuration


Installing this .service file consists of just copying it to /usr/lib/syst.html/system directory, followed by the command systemctl daemon-reload in order to update running syst.html configuration.

To test, run systemctl start bitcoind and to enable for system startup run systemctl enable bitcoind

NOTE: When installing for syst.html in Debian/Ubuntu the .service file needs to be copied to the /lib/syst.html/system directory instead.


Rename bitcoind.openrc to bitcoind and drop it in /etc/init.d. Double check ownership and permissions and make it executable. Test it with /etc/init.d/bitcoind start and configure it to run on startup with rc-update add bitcoind

Upstart (for Debian/Ubuntu based distributions)

Upstart is the default init system for Debian/Ubuntu versions older than 15.04. If you are using version 15.04 or newer and haven't manually configured upstart you should follow the syst.html instructions instead.

Drop bitcoind.conf in /etc/init. Test by running service bitcoind start it will automatically start on reboot.

NOTE: This script is incompatible with CentOS 5 and Amazon Linux 2014 as they use old versions of Upstart and do not supply the start-stop-daemon utility.


Copy bitcoind.init to /etc/init.d/bitcoind. Test by running service bitcoind start.

Using this script, you can adjust the path and flags to the bitcoind program by setting the BITCOIND and FLAGS environment variables in the file /etc/sysconfig/bitcoind. You can also use the DAEMONOPTS environment variable here.


Copy org.bitcoin.bitcoind.plist into ~/Library/LaunchAgents. Load the launch agent by running launchctl load ~/Library/LaunchAgents/org.bitcoin.bitcoind.plist.

This Launch Agent will cause bitcoind to start whenever the user logs in.

NOTE: This approach is intended for those wanting to run bitcoind as the current user. You will need to modify org.bitcoin.bitcoind.plist if you intend to use it as a Launch Daemon with a dedicated bitcoin user.


Auto respawning is currently only configured for Upstart and syst.html. Reasonable defaults have been chosen but YMMV.

Multiprocess Bitcoin

On unix systems, the --enable-multiprocess build option can be passed to ./configure to build new bitcoin-node, bitcoin-wallet, and bitcoin-gui executables alongside existing bitcoind and bitcoin-qt executables.

bitcoin-node is a drop-in replacement for bitcoind, and bitcoin-gui is a drop-in replacement for bitcoin-qt, and there are no differences in use or external behavior between the new and old executables. But internally (after #10102), bitcoin-gui will spawn a bitcoin-node process to run P2P and RPC code, communicating with it across a socket pair, and bitcoin-node will spawn bitcoin-wallet to run wallet code, also communicating over a socket pair. This will let node, wallet, and GUI code run in separate address spaces for better isolation, and allow future improvements like being able to start and stop components independently on different machines and environments.

Next steps

Specific next steps after #10102 will be:


After #10102, the -debug=ipc command line option can be used to see requests and responses between processes.


The multiprocess feature requires Cap'n Proto and libmultiprocess as dependencies. A simple way to get starting using it without installing these dependencies manually is to use the depends system with the MULTIPROCESS=1 dependency option passed to make:

make -C depends NO_QT=1 MULTIPROCESS=1
./configure --prefix=$PWD/depends/x86_64-pc-linux-gnu
src/bitcoin-node -regtest -printtoconsole -debug=ipc
BITCOIND=bitcoin-node test/functional/test_runner.py

The configure script will pick up settings and library locations from the depends directory, so there is no need to pass --enable-multiprocess as a separate flag when using the depends system (it's controlled by the MULTIPROCESS=1 option).

Alternately, you can install Cap'n Proto and libmultiprocess packages on your system, and just run ./configure --enable-multiprocess without using the depends system. The configure script will be able to locate the installed packages via pkg-config. See Installation section of the libmultiprocess readme for install steps. See build-unix.html and build-osx.html for information about installing dependencies in general. Productivity Notes

Table of Contents


Cache compilations with ccache

The easiest way to faster compile times is to cache compiles. ccache is a way to do so, from its description at the time of writing:

ccache is a compiler cache. It speeds up recompilation by caching the result of previous compilations and detecting when the same compilation is being done again. Supported languages are C, C++, Objective-C and Objective-C++.

Install ccache through your distribution's package manager, and run ./configure with your normal flags to pick it up.

To use ccache for all your C/C++ projects, follow the symlinks method here to set it up.

To get the most out of ccache, put something like this in ~/.ccache/ccache.conf:

max_size = 50.0G  # or whatever cache size you prefer; default is 5G; 0 means unlimited
base_dir = /home/yourname  # or wherever you keep your source files

Note: base_dir is required for ccache to share cached compiles of the same file across different repositories / paths; it will only do this for paths under base_dir. So this option is required for effective use of ccache with git worktrees (described below).

You must not set base_dir to "/", or anywhere that contains system headers (according to the ccache docs).

Disable features with ./configure

After running ./autogen.sh, which generates the ./configure file, use ./configure --help to identify features that you can disable to save on compilation time. A few common flags:


If you do need the wallet enabled, it is common for devs to add --with-incompatible-bdb. This uses your system bdb version for the wallet, so you don't have to find a copy of bdb 4.8. Wallets from such a build will be incompatible with any release binary (and vice versa), so use with caution on mainnet.

Make use of your threads with make -j

If you have multiple threads on your machine, you can tell make to utilize all of them with:

make -j"$(($(nproc)+1))"

Only build what you need

When rebuilding during development, note that running make, without giving a target, will do a lot of work you probably don't need. It will build the GUI (unless you've disabled it) and all the tests (which take much longer to build than the app does).

Obviously, it is important to build and run the tests at appropriate times -- but when you just want a quick compile to check your work, consider picking one or a set of build targets relevant to what you're working on, e.g.:

make src/bitcoind src/bitcoin-cli
make src/qt/bitcoin-qt
make -C src bitcoin_bench

(You can and should combine this with -j, as above, for a parallel build.)

Multiple working directories with git worktrees

If you work with multiple branches or multiple copies of the repository, you should try git worktrees.

To create a new branch that lives under a new working directory without disrupting your current working directory (useful for creating pull requests):

git worktree add -b my-shiny-new-branch ../living-at-my-new-working-directory based-on-my-crufty-old-commit-ish

To simply check out a commit-ish under a new working directory without disrupting your current working directory (useful for reviewing pull requests):

git worktree add --checkout ../where-my-checkout-commit-ish-will-live my-checkout-commit-ish

Interactive "dummy rebases" for fixups and execs with git merge-base

When rebasing, we often want to do a "dummy rebase," whereby we are not rebasing over an updated master but rather over the last common commit with master. This might be useful for rearranging commits, rebase --autosquashing, or rebase --execing without introducing conflicts that arise from an updated master. In these situations, we can use git merge-base to identify the last common commit with master, and rebase off of that.

To squash in git commit --fixup commits without rebasing over an updated master, we can do the following:

git rebase -i --autosquash "$(git merge-base master HEAD)"

To execute make check on every commit since last diverged from master, but without rebasing over an updated master, we can do the following:

git rebase -i --exec "make check" "$(git merge-base master HEAD)"

This synergizes well with ccache as objects resulting from unchanged code will most likely hit the cache and won't need to be recompiled.

You can also set up upstream refspecs to refer to pull requests easier in the above git worktree commands.

Writing code

Format C/C++ diffs with clang-format-diff.py

See contrib/devtools/README.html.

Format Python diffs with yapf-diff.py

Usage is exactly the same as clang-format-diff.py. You can get it here.

Rebasing/Merging code

More conflict context with merge.conflictstyle diff3

For resolving merge/rebase conflicts, it can be useful to enable diff3 style using git config merge.conflictstyle diff3. Instead of


you will see


This may make it much clearer what caused the conflict. In this style, you can often just look at what changed between original and theirs, and mechanically apply that to yours (or the other way around).

Reviewing code

Reduce mental load with git diff options

When reviewing patches which change indentation in C++ files, use git diff -w and git show -w. This makes the diff algorithm ignore whitespace changes. This feature is also available on github.com, by adding ?w=1 at the end of any URL which shows a diff.

When reviewing patches that change symbol names in many places, use git diff --word-diff. This will instead of showing the patch as deleted/added lines, show deleted/added words.

When reviewing patches that move code around, try using git diff --patience commit~:old/file.cpp commit:new/file/name.cpp, and ignoring everything except the moved body of code which should show up as neither + or - lines. In case it was not a pure move, this may even work when combined with the -w or --word-diff options described above. --color-moved=dimmed-zebra will also dim the coloring of moved hunks in the diff on compatible terminals.

Reference PRs easily with refspecs

When looking at other's pull requests, it may make sense to add the following section to your .git/config file:

[remote "upstream-pull"]
        fetch = +refs/pull/*/head:refs/remotes/upstream-pull/*
        url = git@github.com:bitcoin/bitcoin.git

This will add an upstream-pull remote to your git repository, which can be fetched using git fetch --all or git fetch upstream-pull. It will download and store on disk quite a lot of data (all PRs, including merged and closed ones). Afterwards, you can use upstream-pull/NUMBER/head in arguments to git show, git checkout and anywhere a commit id would be acceptable to see the changes from pull request NUMBER.

Diff the diffs with git range-diff

It is very common for contributors to rebase their pull requests, or make changes to commits (perhaps in response to review) that are not at the head of their branch. This poses a problem for reviewers as when the contributor force pushes, the reviewer is no longer sure that his previous reviews of commits are still valid (as the commit hashes can now be different even though the diff is semantically the same). git range-diff (Git >= 2.19) can help solve this problem by diffing the diffs.

For example, to identify the differences between your previously reviewed diffs P1-5, and the new diffs P1-2,N3-4 as illustrated below:

       P1--P2--P3--P4--P5   <-- previously-reviewed-head
...--m   <-- master
       P1--P2--N3--N4--N5   <-- new-head (with P3 slightly modified)

You can do:

git range-diff master previously-reviewed-head new-head

Note that git range-diff also work for rebases:

       P1--P2--P3--P4--P5   <-- previously-reviewed-head
...--m--m1--m2--m3   <-- master
                   P1--P2--N3--N4  <-- new-head (with P3 modified, P4 & P5 squashed)

PREV=P5 N=4 && git range-diff `git merge-base --all HEAD $PREV`...$PREV HEAD~$N...HEAD

Where P5 is the commit you last reviewed and 4 is the number of commits in the new version.

git range-diff also accepts normal git diff options, see Reduce mental load with git diff options for useful git diff options.

You can also set up upstream refspecs to refer to pull requests easier in the above git range-diff commands.

PSBT Howto for Bitcoin Core

Since Bitcoin Core 0.17, an RPC interface exists for Partially Signed Bitcoin Transactions (PSBTs, as specified in BIP 174).

This document describes the overall workflow for producing signed transactions through the use of PSBT, and the specific RPC commands used in typical scenarios.

PSBT in general

PSBT is an interchange format for Bitcoin transactions that are not fully signed yet, together with relevant metadata to help entities work towards signing it. It is intended to simplify workflows where multiple parties need to cooperate to produce a transaction. Examples include hardware wallets, multisig setups, and CoinJoin transactions.

Overall workflow

Overall, the construction of a fully signed Bitcoin transaction goes through the following steps:

Generally, each of the above (excluding Creator and Extractor) will simply add more and more data to a particular PSBT, until all inputs are fully signed. In a naive workflow, they all have to operate sequentially, passing the PSBT from one to the next, until the Extractor can convert it to a real transaction. In order to permit parallel operation, Combiners can be employed which merge metadata from different PSBTs for the same unsigned transaction.

The names above in bold are the names of the roles defined in BIP174. They're useful in understanding the underlying steps, but in practice, software and hardware implementations will typically implement multiple roles simultaneously.

PSBT in Bitcoin Core



Multisig with multiple Bitcoin Core instances

Alice, Bob, and Carol want to create a 2-of-3 multisig address. They're all using Bitcoin Core. We assume their wallets only contain the multisig funds. In case they also have a personal wallet, this can be accomplished through the multiwallet feature - possibly resulting in a need to add -rpcwallet=name to the command line in case bitcoin-cli is used.


Later, when V BTC has been received on Amulti, and Bob and Carol want to move the coins in their entirety to address Asend, with no change. Alice does not need to be involved.

In case there are more signers, it may be advantageous to let them all sign in parallel, rather than passing the PSBT from one signer to the next one. In the above example this would translate to Carol handing a copy of P to each signer separately. They can then all invoke walletprocesspsbt "P", and end up with their individually-signed PSBT structures. They then all send those back to Carol (or anyone) who can combine them using combinepsbt. The last two steps (finalizepsbt and sendrawtransaction) remain unchanged.

Reduce Memory

There are a few parameters that can be dialed down to reduce the memory usage of bitcoind. This can be useful on embedded systems or small VPSes.

In-memory caches

The size of some in-memory caches can be reduced. As caches trade off memory usage for performance, reducing these will usually have a negative effect on performance.

Memory pool

Number of peers

Thread configuration

For each thread a thread stack needs to be allocated. By default on Linux, threads take up 8MiB for the thread stack on a 64-bit system, and 4MiB in a 32-bit system.

Linux specific

By default, since glibc 2.10, the C library will create up to two heap arenas per core. This is known to cause excessive memory usage in some scenarios. To avoid this make a script that sets MALLOC_ARENA_MAX before starting bitcoind:

#!/usr/bin/env bash

The behavior was introduced to increase CPU locality of allocated memory and performance with concurrent allocation, so this setting could in theory reduce performance. However, in Bitcoin Core very little parallel allocation happens, so the impact is expected to be small or absent. Reduce Traffic

Some node operators need to deal with bandwidth caps imposed by their ISPs.

By default, Bitcoin Core allows up to 125 connections to different peers, 10 of which are outbound. You can therefore, have at most 115 inbound connections. Of the 10 outbound peers, there can be 8 full-relay connections and 2 block-relay-only ones.

The default settings can result in relatively significant traffic consumption.

Ways to reduce traffic:

1. Use -maxuploadtarget=<MiB per day>

A major component of the traffic is caused by serving historic blocks to other nodes during the initial blocks download phase (syncing up a new node). This option can be specified in MiB per day and is turned off by default. This is not a hard limit; only a threshold to minimize the outbound traffic. When the limit is about to be reached, the uploaded data is cut by no longer serving historic blocks (blocks older than one week). Keep in mind that new nodes require other nodes that are willing to serve historic blocks.

Peers with the download permission will never be disconnected, although their traffic counts for calculating the target.

2. Disable "listening" (-listen=0)

Disabling listening will result in fewer nodes connected (remember the maximum of 10 outbound peers). Fewer nodes will result in less traffic usage as you are relaying blocks and transactions to fewer nodes.

3. Reduce maximum connections (-maxconnections=<num>)

Reducing the maximum connected nodes to a minimum could be desirable if traffic limits are tiny. Keep in mind that bitcoin's trustless model works best if you are connected to a handful of nodes.

4. Turn off transaction relay (-blocksonly)

Forwarding transactions to peers increases the P2P traffic. To only sync blocks with other peers, you can disable transaction relay.

Be reminded of the effects of this setting.

Branch updates

Before every release candidate

Before every major and minor release

Before every major release

Before branch-off

After branch-off (on master)

After branch-off (on the major release branch)

Before final release


First time / New builders

If you're using the automated script (found in contrib/gitian-build.py), then at this point you should run it with the "--setup" command. Otherwise ignore this.

Check out the source code in the following directory hierarchy.

cd /path/to/your/toplevel/build
git clone https://github.com/bitcoin-core/gitian.sigs.git
git clone https://github.com/bitcoin-core/bitcoin-detached-sigs.git
git clone https://github.com/devrandom/gitian-builder.git
git clone https://github.com/bitcoin/bitcoin.git

Write the release notes

Open a draft of the release notes for collaborative editing at https://github.com/bitcoin-core/bitcoin-devwiki/wiki.

For the period during which the notes are being edited on the wiki, the version on the branch should be wiped and replaced with a link to the wiki which should be used for all announcements until -final.

Write the release notes. git shortlog helps a lot, for example:

git shortlog --no-merges v(current version, e.g. 0.19.2)..v(new version, e.g. 0.20.0)

(or ping @wumpus on IRC, he has specific tooling to generate the list of merged pulls and sort them into categories based on labels).

Generate list of authors:

git log --format='- %aN' v(current version, e.g. 0.20.0)..v(new version, e.g. 0.20.1) | sort -fiu

Tag the version (or release candidate) in git:

git tag -s v(new version, e.g. 0.20.0)

Setup and perform Gitian builds

If you're using the automated script (found in contrib/gitian-build.py), then at this point you should run it with the "--build" command. Otherwise ignore this.

Setup Gitian descriptors:

pushd ./bitcoin
export SIGNER="(your Gitian key, ie bluematt, sipa, etc)"
export VERSION=(new version, e.g. 0.20.0)
git fetch
git checkout v${VERSION}

Ensure your gitian.sigs are up-to-date if you wish to gverify your builds against other Gitian signatures.

pushd ./gitian.sigs
git pull

Ensure gitian-builder is up-to-date:

pushd ./gitian-builder
git pull

Fetch and create inputs: (first time, or when dependency versions change)

pushd ./gitian-builder
mkdir -p inputs
wget -O inputs/osslsigncode-2.0.tar.gz https://github.com/mtrojnar/osslsigncode/archive/2.0.tar.gz
echo '5a60e0a4b3e0b4d655317b2f12a810211c50242138322b16e7e01c6fbb89d92f inputs/osslsigncode-2.0.tar.gz' | sha256sum -c

Create the macOS SDK tarball, see the macdeploy instructions for details, and copy it into the inputs directory.

Optional: Seed the Gitian sources cache and offline git repositories

NOTE: Gitian is sometimes unable to download files. If you have errors, try the step below.

By default, Gitian will fetch source files as needed. To cache them ahead of time, make sure you have checked out the tag you want to build in bitcoin, then:

pushd ./gitian-builder
make -C ../bitcoin/depends download SOURCES_PATH=`pwd`/cache/common

Only missing files will be fetched, so this is safe to re-run for each build.

NOTE: Offline builds must use the --url flag to ensure Gitian fetches only from local URLs. For example:

pushd ./gitian-builder
./bin/gbuild --url bitcoin=/path/to/bitcoin,signature=/path/to/sigs {rest of arguments}

The gbuild invocations below DO NOT DO THIS by default.

Build and sign Bitcoin Core for Linux, Windows, and macOS:

pushd ./gitian-builder
./bin/gbuild --num-make 2 --memory 3000 --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
./bin/gsign --signer "$SIGNER" --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../

./bin/gbuild --num-make 2 --memory 3000 --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml
./bin/gsign --signer "$SIGNER" --release ${VERSION}-win-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win.yml
mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz
mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../

./bin/gbuild --num-make 2 --memory 3000 --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml
./bin/gsign --signer "$SIGNER" --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml
mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz
mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../

Build output expected:

  1. source tarball (bitcoin-${VERSION}.tar.gz)
  2. linux 32-bit and 64-bit dist tarballs (bitcoin-${VERSION}-linux[32|64].tar.gz)
  3. windows 32-bit and 64-bit unsigned installers and dist zips (bitcoin-${VERSION}-win[32|64]-setup-unsigned.exe, bitcoin-${VERSION}-win[32|64].zip)
  4. macOS unsigned installer and dist tarball (bitcoin-${VERSION}-osx-unsigned.dmg, bitcoin-${VERSION}-osx64.tar.gz)
  5. Gitian signatures (in gitian.sigs/${VERSION}-<linux|{win,osx}-unsigned>/(your Gitian key)/)

Verify other gitian builders signatures to your own. (Optional)

Add other gitian builders keys to your gpg keyring, and/or refresh keys: See ../bitcoin/contrib/gitian-keys/README.html.

Verify the signatures

pushd ./gitian-builder
./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-linux ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-win.yml
./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml

Next steps:

Commit your signature to gitian.sigs:

pushd gitian.sigs
git add ${VERSION}-linux/"${SIGNER}"
git add ${VERSION}-win-unsigned/"${SIGNER}"
git add ${VERSION}-osx-unsigned/"${SIGNER}"
git commit -m "Add ${VERSION} unsigned sigs for ${SIGNER}"
git push  # Assuming you can push to the gitian.sigs tree

Codesigner only: Create Windows/macOS detached signatures:

Codesigner only: Sign the macOS binary:

transfer bitcoin-osx-unsigned.tar.gz to macOS for signing
tar xf bitcoin-osx-unsigned.tar.gz
./detached-sig-create.sh -s "Key ID"
Enter the keychain password and authorize the signature
Move signature-osx.tar.gz back to the gitian host

Codesigner only: Sign the windows binaries:

tar xf bitcoin-win-unsigned.tar.gz
./detached-sig-create.sh -key /path/to/codesign.key
Enter the passphrase for the key when prompted
signature-win.tar.gz will be created

Codesigner only: Commit the detached codesign payloads:

cd ~/bitcoin-detached-sigs
checkout the appropriate branch for this release series
rm -rf *
tar xf signature-osx.tar.gz
tar xf signature-win.tar.gz
git add -A
git commit -m "point to ${VERSION}"
git tag -s v${VERSION} HEAD
git push the current branch and new tag

Non-codesigners: wait for Windows/macOS detached signatures:

Create (and optionally verify) the signed macOS binary:

pushd ./gitian-builder
./bin/gbuild -i --commit signature=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml
./bin/gsign --signer "$SIGNER" --release ${VERSION}-osx-signed --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml
./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-signed ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml
mv build/out/bitcoin-osx-signed.dmg ../bitcoin-${VERSION}-osx.dmg

Create (and optionally verify) the signed Windows binaries:

pushd ./gitian-builder
./bin/gbuild -i --commit signature=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml
./bin/gsign --signer "$SIGNER" --release ${VERSION}-win-signed --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml
./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-signed ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml
mv build/out/bitcoin-*win64-setup.exe ../bitcoin-${VERSION}-win64-setup.exe

Commit your signature for the signed macOS/Windows binaries:

pushd gitian.sigs
git add ${VERSION}-osx-signed/"${SIGNER}"
git add ${VERSION}-win-signed/"${SIGNER}"
git commit -m "Add ${SIGNER} ${VERSION} signed binaries signatures"
git push  # Assuming you can push to the gitian.sigs tree

After 3 or more people have gitian-built and their results match:

sha256sum * > SHA256SUMS

The list of files should be:


The *-debug* files generated by the gitian build contain debug symbols for troubleshooting by developers. It is assumed that anyone that is interested in debugging can run gitian to generate the files for themselves. To avoid end-user confusion about which file to pick, as well as save storage space do not upload these to the bitcoin.org server, nor put them in the torrent.

gpg --digest-algo sha256 --clearsign SHA256SUMS # outputs SHA256SUMS.asc

(the digest algorithm is forced to sha256 to avoid confusion of the Hash: header that GPG adds with the SHA256 used for the files) Note: check that SHA256SUMS itself doesn't end up in SHA256SUMS, which is a spurious/nonsensical entry.

transmission-show -m <torrent file>

Insert the magnet URI into the announcement sent to mailing lists. This permits people without access to bitcoin.org to download the binary distribution. Also put it into the optional_magnetlink: slot in the YAML file for bitcoin.org (see below for bitcoin.org update instructions).

Additional information

How to calculate m_assumed_blockchain_size and m_assumed_chain_state_size

Both variables are used as a guideline for how much space the user needs on their drive in total, not just strictly for the blockchain. Note that all values should be taken from a fully synced node and have an overhead of 5-10% added on top of its base value.

To calculate m_assumed_blockchain_size:

To calculate m_assumed_chain_state_size:



The purpose of this library is to make the verification functionality that is critical to Bitcoin's consensus available to other applications, e.g. to language bindings.


The interface is defined in the C header bitcoinconsensus.h located in src/script/bitcoinconsensus.h.


bitcoinconsensus_version returns an unsigned int with the API version (currently 1).

Script Validation

bitcoinconsensus_verify_script returns an int with the status of the verification. It will be 1 if the input script correctly spends the previous output scriptPubKey.

Script Flags

Example Implementations


It is possible to run Bitcoin Core as a Tor onion service, and connect to such services.

The following directions assume you have a Tor proxy running on port 9050. Many distributions default to having a SOCKS proxy listening on port 9050, but others may not. In particular, the Tor Browser Bundle defaults to listening on port 9150. See Tor Project FAQ:TBBSocksPort for how to properly configure Tor.

How to see information about your Tor configuration via Bitcoin Core

There are several ways to see your local onion address in Bitcoin Core:

You may set the -debug=tor config logging option to have additional information in the debug log about your Tor configuration.

1. Run Bitcoin Core behind a Tor proxy

The first step is running Bitcoin Core behind a Tor proxy. This will already anonymize all outgoing connections, but more is possible.

-proxy=ip:port  Set the proxy server. If SOCKS5 is selected (default), this proxy
                server will be used to try to reach .onion addresses as well.

-onion=ip:port  Set the proxy server to use for Tor onion services. You do not
                need to set this if it's the same as -proxy. You can use -noonion
                to explicitly disable access to onion services.

-listen         When using -proxy, listening is disabled by default. If you want
                to run an onion service (see next section), you'll need to enable
                it explicitly.

-connect=X      When behind a Tor proxy, you can specify .onion addresses instead
-addnode=X      of IP addresses or hostnames in these parameters. It requires
-seednode=X     SOCKS5. In Tor mode, such addresses can also be exchanged with
                other P2P nodes.

-onlynet=onion  Make outgoing connections only to .onion addresses. Incoming
                connections are not affected by this option. This option can be
                specified multiple times to allow multiple network types, e.g.
                ipv4, ipv6, or onion.

In a typical situation, this suffices to run behind a Tor proxy:

./bitcoind -proxy=

2. Manually create a Bitcoin Core onion service

If you configure your Tor system accordingly, it is possible to make your node also reachable from the Tor network. Add these lines to your /etc/tor/torrc (or equivalent config file): Needed for Tor version and older versions of Tor only. For newer versions of Tor see Section 3.

HiddenServiceDir /var/lib/tor/bitcoin-service/
HiddenServicePort 8333

The directory can be different of course, but virtual port numbers should be equal to your bitcoind's P2P listen port (8333 by default), and target addresses and ports should be equal to binding address and port for inbound Tor connections ( by default).

-externalip=X   You can tell bitcoin about its publicly reachable addresses using
                this option, and this can be an onion address. Given the above
                configuration, you can find your onion address in
                /var/lib/tor/bitcoin-service/hostname. For connections
                coming from unroutable addresses (such as, where the
                Tor proxy typically runs), onion addresses are given
                preference for your node to advertise itself with.

                You can set multiple local addresses with -externalip. The
                one that will be rumoured to a particular peer is the most
                compatible one and also using heuristics, e.g. the address
                with the most incoming connections, etc.

-listen         You'll need to enable listening for incoming connections, as this
                is off by default behind a proxy.

-discover       When -externalip is specified, no attempt is made to discover local
                IPv4 or IPv6 addresses. If you want to run a dual stack, reachable
                from both Tor and IPv4 (or IPv6), you'll need to either pass your
                other addresses using -externalip, or explicitly enable -discover.
                Note that both addresses of a dual-stack system may be easily
                linkable using traffic analysis.

In a typical situation, where you're only reachable via Tor, this should suffice:

./bitcoind -proxy= -externalip=7zvj7a2.htmlgkdbg4f2dryd5rgtrn7upivr5eeij4cicjh65pooxeshid.onion -listen

(obviously, replace the .onion address with your own). It should be noted that you still listen on all devices and another node could establish a clearnet connection, when knowing your address. To mitigate this, additionally bind the address of your Tor proxy:

./bitcoind ... -bind=

If you don't care too much about hiding your node, and want to be reachable on IPv4 as well, use discover instead:

./bitcoind ... -discover

and open port 8333 on your firewall (or use -upnp).

If you only want to use Tor to reach .onion addresses, but not use it as a proxy for normal IPv4/IPv6 communication, use:

./bitcoind -onion= -externalip=7zvj7a2.htmlgkdbg4f2dryd5rgtrn7upivr5eeij4cicjh65pooxeshid.onion -discover

3. Automatically create a Bitcoin Core onion service

Starting with Tor version it is possible, through Tor's control socket API, to create and destroy 'ephemeral' onion services programmatically. Bitcoin Core has been updated to make use of this.

This means that if Tor is running (and proper authentication has been configured), Bitcoin Core automatically creates an onion service to listen on. This will positively affect the number of available .onion nodes.

This new feature is enabled by default if Bitcoin Core is listening (-listen), and requires a Tor connection to work. It can be explicitly disabled with -listenonion=0 and, if not disabled, configured using the -torcontrol and -torpassword settings. To show verbose debugging information, pass -debug=tor.

Connecting to Tor's control socket API requires one of two authentication methods to be configured. It also requires the control socket to be enabled, e.g. put ControlPort 9051 in torrc config file. For cookie authentication the user running bitcoind must have read access to the CookieAuthFile specified in Tor configuration. In some cases this is preconfigured and the creation of an onion service is automatic. If permission problems are seen with -debug=tor they can be resolved by adding both the user running Tor and the user running bitcoind to the same group and setting permissions appropriately. On Debian-based systems the user running bitcoind can be added to the debian-tor group, which has the appropriate permissions. Before starting bitcoind you will need to re-login to allow debian-tor group to be applied. Otherwise you will see the following notice: "tor: Authentication cookie /run/tor/control.authcookie could not be opened (check permissions)" on debug.log.

An alternative authentication method is the use of the -torpassword=password option. The password is the clear text form that was used when generating the hashed password for the HashedControlPassword option in the tor configuration file. The hashed password can be obtained with the command tor --hash-password password (read the tor manual for more details).

4. Privacy recommendations

The Bitcoin-Core project has been designed to support multiple localisations. This makes adding new phrases, and completely new languages easily achievable. For managing all application translations, Bitcoin-Core makes use of the Transifex online translation management tool.

Helping to translate (using Transifex)

Transifex is setup to monitor the GitHub repo for updates, and when code containing new translations is found, Transifex will process any changes. It may take several hours after a pull-request has been merged, to appear in the Transifex web interface.

Multiple language support is critical in assisting Bitcoin’s global adoption, and growth. One of Bitcoin’s greatest strengths is cross-border money transfers, any help making that easier is greatly appreciated.

See the Transifex Bitcoin project to assist in translations. You should also join the translation mailing list for announcements - see details below.

Writing code with translations

We use automated scripts to help extract translations in both Qt, and non-Qt source files. It is rarely necessary to manually edit the files in src/qt/locale/. The translation source files must adhere to the following format: bitcoin_xx_YY.ts or bitcoin_xx.ts

src/qt/locale/bitcoin_en.ts is treated in a special way. It is used as the source for all other translations. Whenever a string in the source code is changed, this file must be updated to reflect those changes. A custom script is used to extract strings from the non-Qt parts. This script makes use of gettext, so make sure that utility is installed (ie, apt-get install gettext on Ubuntu/Debian). Once this has been updated, lupdate (included in the Qt SDK) is used to update bitcoin_en.ts.

To automatically regenerate the bitcoin_en.ts file, run the following commands:

cd src/
make translate

contrib/bitcoin-qt.pro takes care of generating .qm (binary compiled) files from .ts (source files) files. It’s mostly automated, and you shouldn’t need to worry about it.

Example Qt translation

QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));

Creating a pull-request

For general PRs, you shouldn’t include any updates to the translation source files. They will be updated periodically, primarily around pre-releases, allowing time for any new phrases to be translated before public releases. This is also important in avoiding translation related merge conflicts.

When an updated source file is merged into the GitHub repo, Transifex will automatically detect it (although it can take several hours). Once processed, the new strings will show up as "Remaining" in the Transifex web interface and are ready for translators.

To create the pull-request, use the following commands:

git add src/qt/bitcoinstrings.cpp src/qt/locale/bitcoin_en.ts
git commit

Creating a Transifex account

Visit the Transifex Signup page to create an account. Take note of your username and password, as they will be required to configure the command-line tool.

You can find the Bitcoin translation project at https://www.transifex.com/bitcoin/bitcoin/.

Installing the Transifex client command-line tool

The client is used to fetch updated translations. If you are having problems, or need more details, see https://docs.transifex.com/client/installing-the-client

pip install transifex-client

Setup your Transifex client config as follows. Please ignore the token field.

nano ~/.transifexrc

hostname = https://www.transifex.com
password = PASSWORD
token =
username = USERNAME

The Transifex Bitcoin project config file is included as part of the repo. It can be found at .tx/config, however you shouldn’t need to change anything.

Synchronising translations

To assist in updating translations, a helper script is available in the maintainer-tools repo.

  1. python3 ../bitcoin-maintainer-tools/update-translations.py
  2. git add new translations from src/qt/locale/
  3. Update src/qt/bitcoin_locale.qrc manually or via
git ls-files src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/        <file alias="\2">locale\/\1.qm<\/file>/'
  1. Update src/Makefile.qt_locale.include manually or via
git ls-files src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/  qt\/locale\/\1.ts \\/'

Do not directly download translations one by one from the Transifex website, as we do a few post-processing steps before committing the translations.

Handling Plurals (in source files)

When new plurals are added to the source file, it's important to do the following steps:

  1. Open bitcoin_en.ts in Qt Linguist (included in the Qt SDK)
  2. Search for %n, which will take you to the parts in the translation that use plurals
  3. Look for empty English Translation (Singular) and English Translation (Plural) fields
  4. Add the appropriate strings for the singular and plural form of the base string
  5. Mark the item as done (via the green arrow symbol in the toolbar)
  6. Repeat from step 2, until all singular and plural forms are in the source file
  7. Save the source file

Translating a new language

To create a new language template, you will need to edit the languages manifest file src/qt/bitcoin_locale.qrc and add a new entry. Below is an example of the English language entry.

<qresource prefix="/translations">
    <file alias="en">locale/bitcoin_en.qm</file>

Note: that the language translation file must end in .qm (the compiled extension), and not .ts.

Questions and general assistance

The Bitcoin-Core translation maintainers include tcatm, seone, Diapolo, wumpus and luke-jr. You can find them, and others, in the Freenode IRC chatroom - irc.freenode.net #bitcoin-core-dev.

If you are a translator, you should also subscribe to the mailing list, https://groups.google.com/forum/#!forum/bitcoin-translators. Announcements will be posted during application pre-releases to notify translators to check for updates. Translation Strings Policy

This document provides guidelines for internationalization of the Bitcoin Core software.

How to translate?

To mark a message as translatable

No internationalization is used for e.g. developer scripts outside src.

Strings to be translated

On a high level, these strings are to be translated:

GUI strings

Do not translate technical or extremely rare errors. Anything else that appears to the user in the GUI is to be translated. This includes labels, menu items, button texts, tooltips and window titles. This includes messages passed to the GUI through the UI interface through InitMessage, ThreadSafeMessageBox or ShowProgress.

General recommendations

Avoid unnecessary translation strings

Try not to burden translators with translating messages that are e.g. slight variations of other messages. In the GUI, avoid the use of text where an icon or symbol will do. Make sure that placeholder texts in forms do not end up in the list of strings to be translated (use <string notr="true">).

Make translated strings understandable

Try to write translation strings in an understandable way, for both the user and the translator. Avoid overly technical or detailed messages.

Do not translate internal errors

Do not translate internal errors, log messages, or messages that appear on the RPC interface. If an error is to be shown to the user, use a translatable generic message, then log the detailed message to the log. E.g., "A fatal internal error occurred, see debug.log for details". This helps troubleshooting; if the error is the same for everyone, the likelihood is increased that it can be found using a search engine.

Avoid fragments

Avoid dividing up a message into fragments. Translators see every string separately, so they may misunderstand the context if the messages are not self-contained.

Avoid HTML in translation strings

There have been difficulties with the use of HTML in translation strings; translators should not be able to accidentally affect the formatting of messages. This may sometimes be at conflict with the recommendation in the previous section.


Plurals can be complex in some languages. A quote from the gettext documentation:

In Polish we use e.g. plik (file) this way:
1 plik,
2,3,4 pliki,
5-21 pliko'w,
22-24 pliki,
25-31 pliko'w
and so on

In Qt code, use tr's third argument for optional plurality. For example:

tr("%n hour(s)","",secs/HOUR_IN_SECONDS);
tr("%n day(s)","",secs/DAY_IN_SECONDS);
tr("%n week(s)","",secs/WEEK_IN_SECONDS);

This adds <numerusform>s to the respective .ts file, which can be translated separately depending on the language. In English, this is simply:

<message numerus="yes">
    <source>%n active connection(s) to Bitcoin network</source>
        <numerusform>%n active connection to Bitcoin network</numerusform>
        <numerusform>%n active connections to Bitcoin network</numerusform>

Where possible, try to avoid embedding numbers into the flow of the string at all. E.g.,

WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)


WARNING: check your network connection, less blocks (%d) were received in the last %n hours than expected (%d).

The second example reduces the number of pluralized words that translators have to handle from three to one, at no cost to comprehensibility of the sentence.

String freezes

During a string freeze (often before a major release), no translation strings are to be added, modified or removed.

This can be checked by executing make translate in the src directory, then verifying that bitcoin_en.ts remains unchanged.

Block and Transaction Broadcasting with ZeroMQ

ZeroMQ is a lightweight wrapper around TCP connections, inter-process communication, and shared-memory, providing various message-oriented semantics such as publish/subscribe, request/reply, and push/pull.

The Bitcoin Core daemon can be configured to act as a trusted "border router", implementing the bitcoin wire protocol and relay, making consensus decisions, maintaining the local blockchain database, broadcasting locally generated transactions into the network, and providing a queryable RPC interface to interact on a polled basis for requesting blockchain related data. However, there exists only a limited service to notify external software of events like the arrival of new blocks or transactions.

The ZeroMQ facility implements a notification interface through a set of specific notifiers. Currently there are notifiers that publish blocks and transactions. This read-only facility requires only the connection of a corresponding ZeroMQ subscriber port in receiving software; it is not authenticated nor is there any two-way protocol involvement. Therefore, subscribers should validate the received data since it may be out of date, incomplete or even invalid.

ZeroMQ sockets are self-connecting and self-healing; that is, connections made between two endpoints will be automatically restored after an outage, and either end may be freely started or stopped in any order.

Because ZeroMQ is message oriented, subscribers receive transactions and blocks all-at-once and do not need to implement any sort of buffering or reassembly.


The ZeroMQ feature in Bitcoin Core requires the ZeroMQ API >= 4.0.0 libzmq. For version information, see dependencies.html. Typically, it is packaged by distributions as something like libzmq3-dev. The C++ wrapper for ZeroMQ is not needed.

In order to run the example Python client scripts in the contrib/zmq/ directory, one must also install PyZMQ (generally with pip install pyzmq), though this is not necessary for daemon operation.


By default, the ZeroMQ feature is automatically compiled in if the necessary prerequisites are found. To disable, use --disable-zmq during the configure step of building bitcoind:

$ ./configure --disable-zmq (other options)

To actually enable operation, one must set the appropriate options on the command line or in the configuration file.


Currently, the following notifications are supported:


The socket type is PUB and the address must be a valid ZeroMQ socket address. The same address can be used in more than one notification. The same notification can be specified more than once.

The option to set the PUB socket's outbound message high water mark (SNDHWM) may be set individually for each notification:


The high water mark value must be an integer greater than or equal to 0.

For instance:

$ bitcoind -zmqpubhashtx=tcp:// \
           -zmqpubhashtx=tcp:// \
           -zmqpubrawtx=ipc:///tmp/bitcoind.tx.raw \

Each PUB notification has a topic and body, where the header corresponds to the notification type. For instance, for the notification -zmqpubhashtx the topic is hashtx (no null terminator) and the body is the transaction hash (32 bytes) for all but sequence topic. For sequence, the body is structured as the following based on the type of message:

<32-byte hash>C :                 Blockhash connected
<32-byte hash>D :                 Blockhash disconnected
<32-byte hash>R<8-byte LE uint> : Transactionhash removed from mempool for non-block inclusion reason
<32-byte hash>A<8-byte LE uint> : Transactionhash added mempool

Where the 8-byte uints correspond to the mempool sequence number.

These options can also be provided in bitcoin.conf.

ZeroMQ endpoint specifiers for TCP (and others) are documented in the ZeroMQ API.

Client side, then, the ZeroMQ subscriber socket must have the ZMQ_SUBSCRIBE option set to one or either of these prefixes (for instance, just hash); without doing so will result in no messages arriving. Please see contrib/zmq/zmq_sub.py for a working example.

The ZMQ_PUB socket's ZMQ_TCP_KEEPALIVE option is enabled. This means that the underlying SO_KEEPALIVE option is enabled when using a TCP transport. The effective TCP keepalive values are managed through the underlying operating system configuration and must be configured prior to connection establishment.

For example, when running on GNU/Linux, one might use the following to lower the keepalive setting to 10 minutes:

sudo sysctl -w net.ipv4.tcp_keepalive_time=600

Setting the keepalive values appropriately for your operating environment may improve connectivity in situations where long-lived connections are silently dropped by network middle boxes.


From the perspective of bitcoind, the ZeroMQ socket is write-only; PUB sockets don't even have a read function. Thus, there is no state introduced into bitcoind directly. Furthermore, no information is broadcast that wasn't already received from the public P2P network.

No authentication or authorization is done on connecting clients; it is assumed that the ZeroMQ port is exposed only to trusted entities, using other means such as firewalling.

Note that for *block topics, when the block chain tip changes, a reorganisation may occur and just the tip will be notified. It is up to the subscriber to retrieve the chain from the last known block to the new tip. Also note that no notification will occur if the tip was in the active chain--as would be the case after calling invalidateblock RPC. In contrast, the sequence topic publishes all block connections and disconnections.

There are several possibilities that ZMQ notification can get lost during transmission depending on the communication type you are using. Bitcoind appends an up-counting sequence number to each notification which allows listeners to detect lost notifications.

The sequence topic refers specifically to the mempool sequence number, which is also published along with all mempool events. This is a different sequence value than in ZMQ itself in order to allow a total ordering of mempool events to be constructed.