Link Search Menu Expand Document

Electrum

We set up Electrs to serve as a full Electrum server for use with hardware wallets.


Table of contents

  1. Bitcoin with hardware wallets
  2. Electrs
    1. Install dependencies
    2. Build from source code
    3. Configuration & indexing
    4. Autostart on boot
  3. Secure communication
    1. SSL encryption
    2. Remote access
  4. Connect Electrum wallet
    1. General
  5. Connect BitBoxApp
    1. General
    2. Tor
  6. Don’t trust, verify.
  7. Electrs upgrade

Bitcoin with hardware wallets

The best way to safekeep your bitcoin (meaning the best combination of security and usability) is to use a hardware wallet (like BitBox, Ledger or Trezor) in combination with your own Bitcoin node. This gives you security, privacy and eliminates the need to trust a third party to verify transactions.

With the RaspiNail setup, the Bitcoin Core wallet on the node can only be used from the command line as no graphical user interface is installed. As Bitcoin Core does not offer easy support for hardware wallets quite yet, only a “hot wallet” (exposed to the internet) is possible.

One possibility to use Bitcoin Core with more functionality is to use an Electrum Server as middleware. It imports data from Bitcoin Core and provides it to software wallets supporting the Electrum protocol. Wallets like the BitBoxApp or Electrum wallet that support hardware wallets can then be used with your own sovereign Bitcoin node.

The installation of your own Electrum server is optional and not essential for running a Lightning node. It is very much recommended, however, as it is an important step to claim back your on-chain sovereignty and enforce the Bitcoin consensus. In the article “We need Bitcoin full nodes. Economic ones.”, it is outlined why it is pointless to run an idle Bitcoin full node without using it to verify your own on-chain transactions.


🚨 Make sure that you have reduced the database cache of Bitcoin Core after full sync.


Electrs

An easy and performant way is to run Electrs, the Electrum Server in Rust. As there are no binaries available, we will compile the application directly from the source code.

Install dependencies

  • Install the Rust programming language. Latest stable version is 1.56.0, but you can check the current version named as “aarch64-unknown-linux-gnu” here: https://forge.rust-lang.org/infra/other-installation-methods.html

    🚨 This Rust installation is for Linux ARM64 systems only. Don’t install the following binaries on other platforms, it could damage your system.

    Logged in as admin:

    # download
    $ cd /tmp
    $ curl https://static.rust-lang.org/dist/rust-1.56.0-aarch64-unknown-linux-gnu.tar.gz -o rust.tar.gz
    $ curl https://static.rust-lang.org/dist/rust-1.56.0-aarch64-unknown-linux-gnu.tar.gz.asc -o rust.tar.gz.asc
    $ curl https://keybase.io/rust/pgp_keys.asc | gpg --import
    
    # verify
    $ gpg --verify rust.tar.gz.asc rust.tar.gz
    > gpg: Signature made Do 07 Nov 2019 13:25:50 GMT
    > gpg:                using RSA key C13466B7E169A085188632165CB4A9347B3B09DC
    > gpg: Good signature from "Rust Language (Tag and Release Signing Key) <rust-key@rust-lang.org>" [unknown]
    > gpg: WARNING: This key is not certified with a trusted signature!
    > gpg:          There is no indication that the signature belongs to the owner.
    > Primary key fingerprint: 108F 6620 5EAE B0AA A8DD  5E1C 85AB 96E6 FA1B E5FE
    >     Subkey fingerprint: C134 66B7 E169 A085 1886  3216 5CB4 A934 7B3B 09DC
    
    # install
    $ mkdir /home/admin/rust
    $ tar --strip-components 1 -C /home/admin/rust -xzvf rust.tar.gz
    $ cd /home/admin/rust
    $ sudo ./install.sh
    
  • Install build tools

    $ sudo apt update
    $ sudo apt install -y clang cmake
    

Build from source code

Now we download the latest release of the Electrs source code, compile it to an executable binary and install it. The whole process takes about 30 minutes.

  # download
  $ cd /home/admin/rust
  $ electrsgit=$(curl -s https://api.github.com/repos/romanz/electrs/tags | jq -r '.[0].name')
  $ git clone --branch ${electrsgit} https://github.com/romanz/electrs.git
  $ cd electrs

  # compile
  $ cargo build --locked --release

  # install
  $ sudo cp ./target/release/electrs /usr/local/bin/

Configuration & indexing

  • Create the Electrs data directory on the external drive and link it to the “bitcoin” user home.

    sudo su - bitcoin
    mkdir /mnt/ext/electrs
    ln -s /mnt/ext/electrs /home/bitcoin/.electrs
    
  • Create config file:
    🚨 Change the password, otherwise Electrs is not able to talk to Bitcoin Core.

    $ nano /mnt/ext/electrs/electrs.conf
    
    # RaspiNail: electrs configuration
    # /mnt/ext/electrs/electrs.conf
    
    # RPC user / password
    auth = "raspinail:PASSWORD_[B]"
    
    # Bitcoin Core settings
    network = "bitcoin"
    daemon_dir= "/mnt/ext/bitcoin"
    daemon_rpc_addr = "127.0.0.1:8332"
    
    # Use p2p method for indexing Electrs database
    daemon_p2p_addr = "127.0.0.1:8333"
    
    # Electrs settings
    electrum_rpc_addr = "127.0.0.1:50001"
    db_dir = "/mnt/ext/electrs/db"
    index_lookup_limit = 1000
    
    # Logging
    verbose = 2
    log_filters = "INFO"
    timestamp = true
    rust_backtrace = true
    
  • Let’s start Electrs manually first, to check if it’s running as expected. It will immediately start with the initial indexing of the Bitcoin blocks. That should take around 6 hours with a modern SSD. The timestamps in sample output below are following this process with an older non-SSD drive.

    $ electrs --conf /mnt/ext/electrs/electrs.conf
    
    bitcoin@raspinail:~$ electrs --conf /mnt/ext/electrs/electrs.conf
    Starting electrs 0.9.1 on aarch64 linux with Config { network: Bitcoin, db_path: "/mnt/ext/electrs/db/bitcoin", daemon_dir: "/mnt/ext/bitcoin", daemon_auth: UserPass("raspinail", "<sensitive>"), daemon_rpc_addr: 127.0.0.1:8332, daemon_p2p_addr: 127.0.0.1:8333, electrum_rpc_addr: 127.0.0.1:50001, monitoring_addr: 127.0.0.1:4224, wait_duration: 10s, jsonrpc_timeout: 15s, index_batch_size: 10, index_lookup_limit: Some(1000), reindex_last_blocks: 0, auto_reindex: true, ignore_mempool: false, sync_once: false, disable_electrum_rpc: false, server_banner: "Welcome to electrs 0.9.1 (Electrum Rust Server)!", args: [] }
    [2021-10-27T10:32:27.517Z INFO  electrs::metrics::metrics_impl] serving Prometheus metrics on 127.0.0.1:4224
    [2021-10-27T10:32:27.593Z INFO  electrs::db] "/mnt/ext/electrs/db/bitcoin": 0 SST files, 0 GB, 0 Grows
    [2021-10-27T10:32:27.613Z INFO  electrs::server] serving Electrum RPC on 127.0.0.1:50001
    [2021-10-27T10:32:27.647Z INFO  electrs::index] indexing 2000 blocks: [1..2000]
    [2021-10-27T10:32:28.468Z INFO  electrs::chain] chain updated: tip=00000000dfd5d65c9d8561b4b8f60a63018fe3933ecb131fb37f905f87da951a, height=2000
    [2021-10-27T10:32:28.492Z INFO  electrs::index] indexing 2000 blocks: [2001..4000]
    [2021-10-27T10:32:29.263Z INFO  electrs::chain] chain updated: tip=00000000922e2aa9e84a474350a3555f49f06061fd49df50a9352f156692a842, height=4000
    ...
    [2021-10-27T18:50:44.037Z INFO  electrs::index] indexing 1228 blocks: [705751..706978]
    [2021-10-27T18:52:30.605Z INFO  electrs::chain] chain updated: tip=00000000000000000007f6f9c0f1978a64b090fbcaf71b94b37048a04e29dfaa, height=706978
    [2021-10-27T18:52:46.144Z INFO  electrs::db] starting config compaction
    [2021-10-27T18:52:46.158Z INFO  electrs::db] starting headers compaction
    [2021-10-27T18:52:50.335Z INFO  electrs::db] starting txid compaction
    [2021-10-27T19:17:40.807Z INFO  electrs::db] starting funding compaction
    [2021-10-27T20:17:00.417Z INFO  electrs::db] starting spending compaction
    [2021-10-27T21:18:44.228Z INFO  electrs::db] finished full compaction
    
  • Wait until the initial sync is completed and the database is compacted. The space used on disk will grow to over 125 GB before reducing to about 60 GB at the time of this writing.

    2020-07-12T08:32:08.581+01:00 - TRACE - indexed "/mnt/ext/bitcoin/blocks/blk02148.dat": 1471934 rows
    2020-07-12T08:32:26.334+01:00 - DEBUG - no more blocks to index
    2020-07-12T08:32:27.771+01:00 - DEBUG - no more blocks to index
    2020-07-12T08:32:27.822+01:00 - DEBUG - no more blocks to index
    2020-07-12T08:32:28.990+01:00 - DEBUG - no more blocks to index
    2020-07-12T08:32:28.990+01:00 - TRACE - indexed "/mnt/ext/bitcoin/blocks/blk02149.dat": 73105 rows
    2020-07-12T08:32:29.410+01:00 - DEBUG - last indexed block: best=00000000000000000007bcaf73926092f8765725795fba82fd8c9f0bd5df27fd height=638792 @ 2020-07-11T16:21:02Z
    2020-07-12T08:32:31.864+01:00 - INFO - starting full compaction
    2020-07-12T22:00:13.361+01:00 - INFO - finished full compaction
    2020-07-12T22:00:13.377+01:00 - INFO - enabling auto-compactions
    2020-07-12T22:00:16.577+01:00 - TRACE - latest indexed blockhash: 00000000000000000007bcaf73926092f8765725795fba82fd8c9f0bd5df27fd
    2020-07-12T22:01:58.360+01:00 - DEBUG - applying 638793 new headers from height 0
    2020-07-12T22:01:59.154+01:00 - INFO - enabling auto-compactions
    2020-07-12T22:06:38.385+01:00 - DEBUG - relayfee: 0.00001 BTC
    2020-07-12T22:06:38.410+01:00 - DEBUG - downloading new block headers (638793 already indexed) from 0000000000000000000581d1a3b9fadd27bfaae4797fc6e195617bc689615e86
    2020-07-12T22:06:38.827+01:00 - TRACE - downloaded 119 block headers
    2020-07-12T22:06:38.828+01:00 - INFO - best=0000000000000000000581d1a3b9fadd27bfaae4797fc6e195617bc689615e86 height=638911 @ 2020-07-12T11:58:10Z (119 left to index)
    2020-07-12T23:00:53.250+01:00 - DEBUG - applying 119 new headers from height 638793
    2020-07-12T23:00:53.251+01:00 - WARN - reconnecting to bitcoind: disconnected from daemon while receiving
    2020-07-12T23:03:07.478+01:00 - INFO - Electrum RPC server running on 127.0.0.1:50001 (protocol 1.4)
    
  • Stop Electrs with Ctrl-C and exit the “bitcoin” user session.

    [2021-10-28T11:19:17.728Z INFO  electrs::signals] notified via SIG2
    [2021-10-28T11:19:17.731Z INFO  electrs::db] closing DB at /mnt/ext/electrs/db/bitcoin
    [2021-10-28T11:19:17.896Z INFO  electrs::server] electrs stopped: RPC server interrupted
          
      Caused by:
          exiting due to signal
    
    $ exit
    

Autostart on boot

Electrs needs to start automatically on system boot.

  • As user “admin”, create the Electrs systemd unit and copy/paste the following configuration. Save and exit.

    $ sudo nano /etc/systemd/system/electrs.service
    
    # RaspiNail: systemd unit for electrs
    # /etc/systemd/system/electrs.service
    
    [Unit]
    Description=Electrs daemon
    Wants=bitcoind.service
    After=bitcoind.service
    
    [Service]
    
    # Service execution
    ###################
    
    ExecStart=/usr/local/bin/electrs --conf /mnt/ext/electrs/electrs.conf
    
    
    # Process management
    ####################
    
    Type=simple
    Restart=always
    TimeoutSec=120
    RestartSec=30
    KillMode=process
    
    
    # Directory creation and permissions
    ####################################
    
    User=bitcoin
    Group=bitcoin
    
    # /run/electrs
    RuntimeDirectory=electrs
    RuntimeDirectoryMode=0710
    
    
    # Hardening measures
    ####################
    
    # Provide a private /tmp and /var/tmp.
    PrivateTmp=true
    
    # Mount /usr, /boot/ and /etc read-only for the process.
    ProtectSystem=full
    
    # Disallow the process and all of its children to gain
    # new privileges through execve().
    NoNewPrivileges=true
    
    # Use a new /dev namespace only populated with API pseudo devices
    # such as /dev/null, /dev/zero and /dev/random.
    PrivateDevices=true
    
    # Deny the creation of writable and executable memory mappings.
    MemoryDenyWriteExecute=true
    
    [Install]
    WantedBy=multi-user.target
    
  • Enable and start Electrs.

    $ sudo systemctl enable electrs
    $ sudo systemctl start electrs
    
  • Check the systemd journal to see Electrs’ log output. Exit with Ctrl-C.

    $ sudo journalctl -f -u electrs
    

Secure communication

We should only communicate with Electrs over an encrypted channel. This is what SSL/TLS (Transport Layer Security) is for. Electrs does not handle TLS communication itself, so we use NGINX as a reverse proxy for that.

SSL encryption

This means that NGINX provides secure communication to the outside and routes it back without encryption to Electrs internally.

  • Install NGINX

    💡 Hint: NGINX is pronounced “Engine X”

    $ sudo apt install -y nginx
    
  • Create a self-signed TLS certificate (valid for 10 years)

    $ sudo openssl req -x509 -nodes -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt -subj "/CN=localhost" -days 3650
    
  • To completely disable the NGINX webserver and configure the TCP reverse proxy for Electrs, remove the default configuration and paste the following into the nginx.conf file.

    $ sudo mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
    $ sudo nano /etc/nginx/nginx.conf
    
    user www-data;
    worker_processes 1;
    pid /run/nginx.pid;
    include /etc/nginx/modules-enabled/*.conf;
    
    events {
      worker_connections 768;
    }
    
    stream {
      ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
      ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
      ssl_session_cache shared:SSL:1m;
      ssl_session_timeout 4h;
      ssl_protocols TLSv1.2 TLSv1.3;
      ssl_prefer_server_ciphers on;
    
      upstream electrs {
        server 127.0.0.1:50001;
      }
      server {
        listen 50002 ssl;
        proxy_pass electrs;
      }
    }
    
    
  • Test the NGINX configuration and restart the service.

    $ sudo nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    
    $ sudo systemctl restart nginx
    

Remote access

To use your Electrum server when you’re on the go, you can easily create a Tor hidden service. This way, you can connect the BitBoxApp or Electrum wallet also remotely, or even share the connection details with friends and family. Note that the remote device needs to have Tor installed.

  • Add the following three lines in the section for “location-hidden services” in the torrc file.

    $ sudo nano /etc/tor/torrc
    
    ############### This section is just for location-hidden services ###
    
    HiddenServiceDir /var/lib/tor/hidden_service_electrs/
    HiddenServiceVersion 3
    HiddenServicePort 50002 127.0.0.1:50002
    
  • Restart Tor and get your connection address.

    $ sudo systemctl restart tor
    $ sudo cat /var/lib/tor/hidden_service_electrs/hostname
    > gwdllz5g7vky2q4gr45zGuvopjzf33czreca3a3exosftx72ekppkuqd.onion
    

Connect Electrum wallet

Electrum wallet is a well-established, feature-rich software wallet that supports most hardware wallets.

General

On your regular computer, we will configure Electrum wallet to connect ONLY to your own RaspiNail node, by using clearnet IP connection on your LAN network or by private TOR connection from a remote location:

  • Create a shortcut on your desktop called “Electrum LAN”, right click on “Properties” and write this on the “target” field. Change the executable path to your actual Electrum version:
    "C:\Program Files (x86)\Electrum\electrum-4.1.5.exe" --oneserver --server raspinail.local:50002:s --proxy none
    

    or you could use the node LAN IP to connect to it (eg 192.168.0.20):

    "C:\Program Files (x86)\Electrum\electrum-4.1.5.exe" --oneserver --server 192.168.0.20:50002:s --proxy none
    
  • Create another shortcut on your desktop called “Electrum TOR”, right click on “Properties” and write this on the “target” field. Change the “xxxxxxxxxxxx.onion” string to your actual Onion TOR address:
    "C:\Program Files (x86)\Electrum\electrum-4.1.5.exe" --oneserver --server xxxxxxxxxxxx.onion:50002:s --proxy socks5:127.0.0.1:9050
    

    To use the TOR connection, you need Tor installed locally on your computer. You have to execute this program before opening the wallet, in order to allow it to connect through TOR proxy:

    C:\Users\regiregi22\Desktop\Tor Browser\Browser\TorBrowser\Tor\tor.exe
    
  • Check the connnection in the tab “Console”.
    A green LED in the bottom right indicates an active connection over clearnet.  
    A blue LED in the bottom right indicates an active connection over TOR.
    

Connect BitBoxApp

BitBoxApp is a beginner-friendly companion app to the BitBox02 hardware wallet by Shift Cryptosecurity.

General

On your regular computer, configure the BitBoxApp to use your RaspiNail node:

  • In the sidebar, select Settings > Connect your own full node
  • In the field “Enter the endpoint” enter the hostname or ip address and the port, e.g. RaspiNail.local:50002
  • Click on “Download remote certificate”
  • Click “Check”, you should be prompted with the message “Successfully establised a connection”
  • Click “Add” to add your server to the list on the top
  • Remove the Shift servers to only connect to your own server

Tor

If you have Tor installed on your computer, you can access your RaspiNail remotely over Tor.

  • In the sidebar, select Settings > Enable tor proxy
  • Enable it and confirm the proxy address (usually the default 127.0.0.1:9050)
  • When adding your RaspiNail full node as described above, use your Tor address (e.g. gwdllz5g7vky2q4gr45zGuvopjzf33czreca3a3exosftx72ekppkuqd.onion:50002)

BitBoxApp


Don’t trust, verify.

Congratulations, you have now one of the best Bitcoin desktop wallet, capable of securing your bitcoin with support of a hardware wallet, running with your own trustless Bitcoin full node!


Electrs upgrade

Updating a new release should be straight-forward, but make sure to check out the release notes first.

  • With user “admin”, check what version you have vs that available as lastest release.

    $ cd /home/admin/rust
    $ currentelectrs=$(head -n 1 electrs/RELEASE-NOTES.md | awk '{print "v"$2}')
    $ echo "Current = ${currentelectrs}"
    $ electrsgit=$(curl -s https://api.github.com/repos/romanz/electrs/tags | jq -r '.[0].name')
    $ echo "Available = ${electrsgit}"
    
  • If the available version is newer, then you can proceed with the following

    $ # backup the current one
    $ mv electrs electrs-v${currentelectrs};
    
    $ # clone the most recent tagged version
    $ git clone --branch ${electrsgit} https://github.com/romanz/electrs.git
    
    $ # Build it
    $ cd electrs
    $ cargo build --locked --release
    
    $ # Stop the service, copy the binary over, and start the service back up
    $ sudo systemctl stop electrs
    $ sudo cp ./target/release/electrs /usr/local/bin/
    $ sudo systemctl start electrs
    

Next: Block Explorer »