Install
Get Software
Get source code
git clone https://github.com/bitcoin/bitcoin.git
or the binaries at
curl https://bitcoincore.org/bin
# select version
curl https://bitcoincore.org/bin/bitcoin-core-22.1/bitcoin-22.1-x86_64-linux-gnu.tar.gz
Install from source
Install build dependencies and build:
# cd bitcoin/
# cmake -B build
...
# cmake --build build
...
# ctest --test-dir build
...
# cmake --install build
...
Install binaries
# tar -xvzf bitcoin-22.1-x86_64-linux-gnu.tar.gz
...
# install -m 0755 -o root -g root -t /usr/local/bin bitcoin-22.1/bin/*
# install -m 0755 -o root -g root -t /usr/local/lib/ bitcoin-22.1/lib/*
# install -m 0755 -o root -g root -t /usr/local/include/ bitcoin-22.1/include/*
# install -m 0755 -o root -g root -t /usr/local/share/man/man1 bitcoin-22.1/share/man/man1/*
Create user
# groupadd --system bitcoin
# adduser --system -g bitcoin --home /opt/bitcoind bitcoin
Configuration
Config File
Create folder
Be sure to have at least 700GB (Aug 2025) disk space available !!
In my case I’m putting the blockchain on a dedicated 1TB LVM volume using XFS filesystem which is optimized for smaller files sizes.
# lvcreate -L 1T -n bitcoind vg1
# mkfs.xfs /dev/vg1/bitcoind
# mount /dev/vg1/bitcoind /opt/bitcoind
# chown -R bitcoin:bitcoin /opt/bitcoind
# su - bitcoin
$ mkdir ~/.bitcoin
Create File ~/.bitcoin/bitcoin.conf:
# Bitcoin Core Konfiguration
# Allgemeine Einstellungen
daemon=1 # Run in background
server=1 # Aktiviert die RPC-Schnittstelle
datadir=/opt/bitcoind/.bitcoin/data
txindex=1 # Aktiviert Transaktionsindex für beliebige Abfragen
blocknotify=/opt/bitcoind/blocknotify.sh %s # Skript für Blockbenachrichtigungen
# Netzwerk
listen=1 # Akzeptiert eingehende P2P-Verbindungen
maxconnections=50 # Maximale Anzahl an Peers
port=8333 # Standard-P2P-Port für Mainnet
# Nodes
# this will connect exclusively to trusted-node-ip
# if you dont want to run a full node.
#connect=trusted-node-ip:8333
# RPC-Schnittstelle
rpcuser=thor
rpcpassword=password
rpcallowip=127.0.0.1 # Lokaler Zugriff
rpcallowip=192.168.1.0/24 # other allowed local network
rpcport=8332 # Standard-RPC-Port
rpcbind=0.0.0.0 # Bindet RPC an alle Schnittstellen
rpcthreads=4 # Anzahl der Threads für RPC
# Sicherheit
rpcssl=1 # Aktiviert SSL für RPC
rpcsslcertificatechainfile=/opt/bitcoind/.bitcoin/server.cert
rpcsslprivatekeyfile=/opt/bitcoind/.bitcoin/server.key
# Wallet
wallet=/opt/bitcoind/.bitcoin/wallets/main_wallet
walletnotify=/opt/bitcoind/walletnotify.sh %s # Skript für Wallet-Benachrichtigungen
Create SSL Keys
# openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /opt/bitcoind/.bitcoin/server.key -out /opt/bitcoind/.bitcoin/server.cert
# chmod 600 /opt/bitcoind/.bitcoin/server.key
# chmod 644 /opt/bitcoind/.bitcoin/server.cert
# chown bitcoin:bitcoin /opt/bitcoind/.bitcoin/server.*
Blocknotify Script (example)
#!/bin/bash
BLOCK_HASH=$1
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
BLOCK_HEIGHT=$(bitcoin-cli getblockheader $BLOCK_HASH | jq -r '.height')
# E-Mail-Versand mit mail (mailutils muss installiert sein)
SUBJECT="Neuer Bitcoin-Block erkannt: Höhe $BLOCK_HEIGHT"
MESSAGE="Ein neuer Block wurde erkannt!\nBlockhash: $BLOCK_HASH\nHöhe: $BLOCK_HEIGHT\nZeitpunkt: $TIMESTAMP"
echo -e "$MESSAGE" | mail -s "$SUBJECT" admin@example.com
# Optional: Log in Datei schreiben
echo "$TIMESTAMP: Neuer Block $BLOCK_HEIGHT mit Hash $BLOCK_HASH" >> /var/log/bitcoin_blocks.log
Walletnotify Script (example)
#!/bin/bash
TXID=$1
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
TX_DETAILS=$(bitcoin-cli gettransaction $TXID)
AMOUNT=$(echo $TX_DETAILS | jq -r '.amount')
ADDRESS=$(echo $TX_DETAILS | jq -r '.details[0].address')
CONFIRMATIONS=$(echo $TX_DETAILS | jq -r '.confirmations')
# Nur eingehende Zahlungen verarbeiten (amount > 0)
if (( $(echo "$AMOUNT > 0" | bc -l) )); then
# HTTP-POST an einen Zahlungsprozessor (z. B. Webhook)
curl -X POST https://example.com/webhook \
-H "Content-Type: application/json" \
-d "{\"txid\":\"$TXID\",\"amount\":$AMOUNT,\"address\":\"$ADDRESS\",\"confirmations\":$CONFIRMATIONS,\"timestamp\":\"$TIMESTAMP\"}"
# Log in Datei schreiben
echo "$TIMESTAMP: Eingehende Zahlung von $AMOUNT BTC an $ADDRESS (txid: $TXID, confirmations: $CONFIRMATIONS)" >> /var/log/bitcoin_wallet.log
fi
Firewall
At least open the default P2P port
# iptables -A INPUT -p tcp --dport 8333 -j ACCEPT
# ip6tables -A INPUT -p tcp --dport 8333 -j ACCEPT
Start daemon
Create systemd unit file
/etc/systemd/system/bitcoind.service
[Unit]
Description=Bitcoin Core Daemon
After=network.target
[Service]
ExecStart=/usr/local/bin/bitcoind -daemon -conf=/opt/bitcoind/.bitcoin/bitcoin.conf -pid=/opt/bitcoind/.bitcoin/bitcoind.pid
ExecStop=/usr/local/bin/bitcoin-cli -conf=/opt/bitcoind/.bitcoin/bitcoin.conf stop
User=bitcoin
Group=bitcoin
Type=forking
PIDFile=/opt/bitcoind/.bitcoin/bitcoind.pid
Restart=always
RestartSec=30
TimeoutSec=300
RuntimeDirectory=bitcoind
WorkingDirectory=/opt/bitcoind/.bitcoin
PrivateTmp=true
ProtectSystem=full
NoNewPrivileges=true
# If systemd supports it include:
MemoryDenyWriteExecute=true
[Install]
WantedBy=multi-user.target
Start daemon
Reload systemd
systemctl daemon-reload
Start bitcoind
Be sure your system/volume has at least 700GB of free space!
Starting your full node will download the entire BTC blockchain which is
at around 600GB and 909844 blocks right now (Aug 2025).
Downloading the blockchain will last for hours if not days or weeks – depending on your bandwidth and available CPU power.
# systemctl start bitcoind
# systemctl enable bitcoind
Logging
The default log location is /opt/bitcoind/.bitcoin/data/debug.log
Check the log for errors!
# tail -f /opt/bitcoind/.bitcoin/data/debug.log
2025-08-13T11:26:30Z UpdateTip: new best=00000000000000000004089e9d9d4f0ea035101660fd9cac317f85f1e6a4d5de height=804792 version=0x2000e000 log2_work=94.380085 tx=884374807 date='2023-08-25T11:51:24Z' progress=0.854459 cache=302.8MiB(1958446txo)
2025-08-13T11:26:40Z UpdateTip: new best=00000000000000000002aecfbe1fb51a5c5194aa4dfd57894b23ac2c495312dd height=804793 version=0x2a34a000 log2_work=94.380099 tx=884380001 date='2023-08-25T11:55:43Z' progress=0.854460 cache=303.1MiB(1961770txo)
2025-08-13T11:26:59Z UpdateTip: new best=0000000000000000000417948e364c647805f4668b6385c2a002f697e13772a3 height=804794 version=0x20e00000 log2_work=94.380112 tx=884382128 date='2023-08-25T12:05:51Z' progress=0.854462 cache=303.3MiB(1962949txo)
2025-08-13T11:27:40Z UpdateTip: new best=00000000000000000002c98c332fd346160c70e8ea09e2c212391d0b46f458e6 height=804795 version=0x20014000 log2_work=94.380125 tx=884384892 date='2023-08-25T12:18:54Z' progress=0.854464 cache=304.3MiB(1971225txo)
2025-08-13T11:27:40Z New outbound peer connected: version: 70016, blocks=909845, peer=4748 (outbound-full-relay)
2025-08-13T11:27:41Z Synchronizing blockheaders, height: 909845 (~100.00%)
2025-08-13T11:27:41Z New outbound peer connected: version: 70016, blocks=909845, peer=4749 (outbound-full-relay)
2025-08-13T11:27:42Z New outbound peer connected: version: 70016, blocks=909845, peer=4750 (outbound-full-relay)
2025-08-13T11:28:19Z UpdateTip: new best=0000000000000000000052b63be93b66258c6482040031c270da86dd4c4d4bb1 height=804796 version=0x33822000 log2_work=94.380139 tx=884388104 date='2023-08-25T12:57:36Z' progress=0.854469 cache=305.3MiB(1979267txo)
2025-08-13T12:40:27Z Synchronizing blockheaders, height: 909853 (~100.00%)
If everything is fine in the logs your bitcoind starts up.
As you can see in the exanple output above, you will find messages about
- New blocks downloaded from the update peers
- New peers that get connected
- Or peers getting disconnected because of stalling download
- The current block height that is going to be synchronized / downloaded.
Rotate the logs!
Be sure to include copytruncate. Even there is a risk of loosing data, bitcoind dues not support signals like HUP and thus you need to restart bitcoind after rotating the logfile! Using copytruncate will avoid restarting the daemon.
# cat /etc/logrotate.d/bitcoind
/opt/bitcoind/.bitcoin/data/debug.log {
create 600 bitcoin bitcoin
daily
rotate 14
compress
delaycompress
missingok
notifempty
copytruncate
}
bitcoin-cli
Add the following 2 parameters to any of the following commands as defined in your bitcoin.conf
-rpcuser=thor
-rpcpassword=password
Create Wallet
With automatically generated Seed-Phrase
bitcoin-cli -named createwallet wallet_name=ThorWallet descriptors=true blank=false
Create an address for your wallet
Wallet addresses that have been created can’t be deleted anymore without deleting the whole wallet.
# bitcoin-cli getnewaddress
<ADDRESS>
Import watch-only Address
Import watch only address <ADDRESS> with a label Thor-Label and rescan blockchain set to False
Doing no rescan is quicker but you can’t find any old transactions only future transactions can be searched.
bitcoin-cli importaddress "<ADDRESS>" "Thor-Label" False
Show the result
# bitcoin-cli getaddressinfo <ADDRESS>
{
"address": "<ADDRESS>",
"scriptPubKey": "b914...cb87",
"ismine": false,
"solvable": false,
"iswatchonly": true,
"isscript": true,
"iswitness": false,
"ischange": false,
"timestamp": 1,
"labels": [
"Thor-Label"
]
}
List Addresses in your Wallet
List all addresses including ‘watch-only’ addresses and those that have no transactions
# bitcoin-cli -named listreceivedbyaddress minconf=0 include_empty=true
[
{
"address": "<ADDRESS>",
"amount": 0.00000000,
"confirmations": 0,
"label": "Thor-Label",
"txids": [
]
}
{
[...]
}
]
Maybe you want to pass output to ‘jq’
Example 1
bitcoin-cli -named listreceivedbyaddress minconf=0 include_empty=true | jq '.[].address'
"3GS...Bt"
"3MZ...uV"
"bc1...m74"
"bc1...d2j"
"bc1...5yx"
Example 2
$ bitcoin-cli -named listreceivedbyaddress minconf=0 include_empty=true include_watchonly=true | jq '.[] | {address: .address, amount: .amount}'
{
"address": "3GS...Bt",
"amount": 0
}
{
"address": "3MZ...uV",
"amount": 0
}
{
"address": "bc1...m74",
"amount": 0
}
{
"address": "bc1...d2j",
"amount": 0
}
{
"address": "bc1...5yx",
"amount": 0
}
To be continued…