Skip to content

Instantly share code, notes, and snippets.

@k9ert
Last active December 28, 2020 16:11
Show Gist options
  • Save k9ert/f1f89df641edd4fa5f433e9cb99ae50e to your computer and use it in GitHub Desktop.
Save k9ert/f1f89df641edd4fa5f433e9cb99ae50e to your computer and use it in GitHub Desktop.
rc3

What's specter - the tutorial-notes for the talk at the rc3

We'll have some slides and will also have a look on the specter-shields (the hardware-side of Specter) but will soon do hands-on.

Content:

General

We assume that you'll work on some Debian based Linux system. It might also work on other Linux Distros and also for most stuff (all but cypress-snapshots) MacOS and maybe even partially on Windows, but i couldn't verify that.

  • Debian based Linux machine
  • python + virtualenv (>=3.6,<3.9)
  • bitcoind
  • nodejs

Debian preparation

Make sure you have at least 5-6 GB free disk space.

df -h

Let's install some prerequisites

sudo apt install python3 python3-pip git gnupg build-essential
# hopefully >=3.6,<3.9
python3 --version
sudo apt install libusb-1.0-0-dev libudev-dev python3-dev

bitcoind binary

Here is one way to do it. Make sure you have a recent version (> 0.20.0).

wget https://bitcoincore.org/bin/bitcoin-core-0.20.1/bitcoin-0.20.1-x86_64-linux-gnu.tar.gz
wget https://bitcoincore.org/bin/bitcoin-core-0.20.1/SHA256SUMS.asc
sha256sum --ignore-missing --check SHA256SUMS.asc
# should result in 
# bitcoin-0.20.1-x86_64-linux-gnu.tar.gz: OK
# check gpg-signature as well
gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 01EA5486DE18A882D4C2684590C8019E36C2E964
gpg --verify SHA256SUMS.asc
# unpacking and installing ...
tar -xzf https://bitcoincore.org/bin/bitcoin-core-0.20.1/bitcoin-0.20.1-x86_64-linux-gnu.tar.gz
sudo install -m 0755 -o root -g root -t /usr/local/bin bitcoin-0.20.1/bin/*

NodeJs

WARNING: We don't do any verification of checksums here!

wget https://nodejs.org/dist/v15.3.0/node-v15.3.0-linux-x64.tar.xz
sudo tar -xJf node-v15.3.0-linux-x64.tar.xz -C /opt
sudo ln -s /opt/node-v15.3.0-linux-x64 /opt/node
export PATH=$PATH:/opt/node/bin # maybe make that permanent

get a node up and running in 10 minutes

# Downloading and extracting the blocks/chainstate
wget https://prunednode.today/snapshot201226.zip
wget https://prunednode.today/snapshot201226.signed.txt
#wget http://k9ert.de/s2f/snapshot201226.zip
gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 6F16E354F83393D6E52EC25F36ED357AB24B915F 
# imports key from Stepan
curl https://stepansnigirev.com/stepan-gpg.asc | gpg --import
gpg --verify snapshot201226.signed.txt
sha256sum --ignore-missing --check snapshot201226.signed.txt
mkdir -p ~/.bitcoin
unzip snapshot201226.zip -d ~/.bitcoin

# Adjusting for getting remote-access
echo rpcpassword=aVerySecretPassword >> ~/.bitcoin/bitcoin.conf
echo rpcuser=bitcoin >> ~/.bitcoin/bitcoin.conf
echo rpcport=8332 >> ~/.bitcoin/bitcoin.conf
echo rpchost=localhost >> ~/.bitcoin/bitcoin.conf
bitcoind # In order to catch up from 26.12. to now, it'll need about about 3 minutes to catch up
# Let's leave this terminal open

Let's check whether it's properly running

This proves that our node is running fine.

➜  ~ bitcoin-cli getblockchaininfo
{
  "chain": "main",
  "blocks": 663332,
  "headers": 663332,
  "bestblockhash": "000000000000000000025cc7e5b183f67d7121e2eb63c62568e3095fefe3ae16",
  "difficulty": 18599593048299.49,
  "mediantime": 1609147520,
  "verificationprogress": 0.99999850781368,
  "initialblockdownload": false,
  "chainwork": "000000000000000000000000000000000000000017625d7e39890e4d02c4979d",
  "size_on_disk": 923568475,
  "pruned": true,
  "pruneheight": 662763,
  "automatic_pruning": true,
  "prune_target_size": 1048576000,
  "softforks": {
    "bip34": {
      "type": "buried",
      "active": true,
      "height": 227931
    },
    "bip66": {
      "type": "buried",
      "active": true,
      "height": 363725
    },
    "bip65": {
      "type": "buried",
      "active": true,
      "height": 388381
    },
    "csv": {
      "type": "buried",
      "active": true,
      "height": 419328
    },
    "segwit": {
      "type": "buried",
      "active": true,
      "height": 481824
    }
  },
  "warnings": ""
}
➜  ~ 

Installation

There are a lot of ways to install/run specter. Mainly, you can download an electron-app for your platform or you can install a pip-package. As the pip-package is quite close to what a hacker want to have, we'll do that (before checking out the source-code.

You have to decide whether you want to use a virtualenv. If you don't know what that is, you probably don't want to use it. If you want one, you would probably do something like this:

mkdir specter-desktop
cd specter-desktop
virtualenv --python=python3 .env
source .env/bin/activate

Install specter:

pip3 install cryptoadvance.specter --upgrade

However, let's use the newest prerelease and install it in a secure way:

wget https://github.com/cryptoadvance/specter-desktop/releases/download/v0.11.0-pre4/cryptoadvance.specter-0.11.0rc4.tar.gz
wget https://github.com/cryptoadvance/specter-desktop/releases/download/v0.11.0-pre4/SHA256SUMS-pip.txt
sha256sum --check SHA256SUMS-pip.txt 
# Sorry, no gpg-checks for pre-releases
# Now, let's extract the requirements-file and install all requirements with require-hashes
tar -xvzf cryptoadvance.specter-0.11.0rc3.tar.gz cryptoadvance.specter-0.11.0rc3/requirements.txt
pip3 install cryptoadvance.specter-0.11.0rc3/requirements.txt --require-hashes --upgrade
# The package cryptoadvance.specter itself cannot be included into requirements.txt
# But we have checked the checksum before so it's safe to install without checking it's hash
pip3 install cryptoadvance.specter-0.11.0rc3.tar.gz

Let's get it running

In python, packages have some "main-handlers". In our case, specter has some sort of cli with currently two commands:

(.env) ➜  specter-desktop python3 -m cryptoadvance.specter       
Initializing HWI...
Usage: __main__.py [OPTIONS] COMMAND [ARGS]...

Options:
  --debug  Show debug information on errors.
  --help   Show this message and exit.

Commands:
  bitcoind  This will start a bitcoind regtest and mines a block every...
  server
(.env) ➜  specter-desktop python3 -m cryptoadvance.specter server --help     
Initializing HWI...
Usage: __main__.py server [OPTIONS]

Options:
  --daemon                    Deprecated, don't use that and prepare to see it
                              removed

  --stop                      Deprecated, don't use that and prepare to see it
                              removed

  --restart                   Deprecated, don't use that and prepare to see it
                              removed

  --force                     Deprecated, don't use that and prepare to see it
                              removed

  --port TEXT                 The TCP-Port to bin specter to
  --host TEXT                 if you do --host 0.0.0.0 then specter will be
                              available in your local lan

  --cert TEXT                 --cert and --key are for using a self-signed-
                              cert/ssl-encryption

  --key TEXT                  --cert and --key are for using a self-signed-
                              cert/ssl-encryption

  --ssl / --no-ssl            By default will run unencrypted. Use -ssl to
                              create a self-signed certificate or you can also
                              specify it via --cert and --key.

  --debug / --no-debug
  --tor
  --hwibridge                 Start the hwi-bridge to use your HWWs with a
                              remote specter

  --specter-data-folder TEXT  Enables overriding the specter-data-folder. This
                              is usually ~/.specter

  --config TEXT               A class from the config.py which sets reasonable
                              Defaults

  --help                      Show this message and exit.
(.env) ➜  specter-desktop python3 -m cryptoadvance.specter bitcoind --help
Initializing HWI...
Usage: __main__.py bitcoind [OPTIONS]

  This will start a bitcoind regtest and mines a block every mining-period.
  If a bitcoind is already running on port 18443, it won't start another
  one. If you CTRL-C this, the bitcoind will still continue to run. You have
  to shut it down.

Options:
  --debug / --no-debug            Turns on debug-logging
  --quiet / --no-quiet            as less output as possible
  --nodocker                      use without docker (non-default)
  --docker-tag TEXT               Use a specific docker-tag
  --data-dir TEXT                 specify a (maybe not yet existing) datadir.
                                  Works only in --nodocker
                                  (Default:/tmp/bitcoind_plain_datadir)

  --mining / --no-mining          Turns on mining (default). In tests it's
                                  useful to turn it off.

  --mining-period TEXT            Every mining-period (in seconds), a block
                                  gets mined (default 15sec)

  --reset                         Will kill the bitcoind. Datadir will get
                                  lost.

  --create-conn-json              Will create a small json-file btcd-conn.json
                                  with connection details.

  --cleanuphard / --no-cleanuphard
                                  Will send a SIGKILL instead of SIGTERM
                                  (default) when CTRL-C. Mostly to speedup
                                  tests.

  --config TEXT                   A class from the config.py which sets
                                  reasonable Defaults

  --help                          Show this message and exit.
(.env) ➜  specter-desktop

So first, we'll need the server-command to spin up the server:

python3 -m cryptoadvance.specter server

You should now be able to access it at here.

Configure Bitcoind

Usually this is not needed as there is some autoconfiguration which checks the ~/.bitcoin/bitcoin.conf folder for access. Nevertheless you can configure it via clicking on the upper right gear (here).

Quick and dirty penny-test

We don't assume that you'll have a hardware-wallet available. If you have one, you could potentially use that one for your penny-test. I'd recommend to use a different passphrase. However, let's first do it with a bitcoind-hot-wallet.

Creating the wallet

  • "Add new Device" --> Bitcoin Core (hot wallet)
  • You can either import or accept the random words (or regenrate) --> next # NOTE DOWN THESE WORDS!!!
  • Give it a name "pennytest" --> Add Device
  • Create a wallet out of that device --> Create single key wallet
  • Give it a name "pennytest" --> Create Wallet
  • Save the backup-pdf (WARNING: This does not contain your secret words) --> continue
  • We're done ...

Send some coins back and forth

  • ... and we have an address presented for us. Send some sats with cheap fees (1-6 sats/byte) ...
  • switch to the transactions-tab, your tx should appear there
  • We can now spend it again back to our wallet. We don't have to wait for an confirmation
  • switch to send-tab and scan your address
  • click "send max" and adjust your fees
  • --> "create unsigned transaction" + sign it + send it
  • done

Troubleshooting

while testing that, when sendinmg coins i stumbled in this issue. You can fix it yourself by adding the first_tx_blockheight and in line 836 of wallet.py.

# if you use a virtualenv, change to that before this!
# Whether you have bitcoind installed or not, currently this needs the docker-package
pip3 install docker
# Starting a regtest
python3 -m cryptoadvance.specter bitcoind --nodocker
# open a new terminal and let this running.

You'd get about this output:

(.env) ➜  specter-desktop python3 -m cryptoadvance.specter bitcoind --nodocker
Initializing HWI...
    --> starting plain bitcoind
    -->            url: http://bitcoin:secret@localhost:18443/wallet/
    --> user, password: bitcoin, secret
    -->     host, port: localhost, 18443
    -->    bitcoin-cli: bitcoin-cli -regtest -rpcuser=bitcoin -rpcpassword=secret getblockchaininfo 
    --> Now, mining a block every 15.000000 seconds, avoid it via --no-mining
    --> height: 907 | 012345

Now go back to specter and click somewhere. It will complain about a missing bitcoind-connection and your pennytest-wallet disappeared. Let's configure the regtest-node:

  • click "configure node", the needed values are also above
  • user: bitcoin
  • password: secret
  • host: localhost
  • port: 18443

For regtest, you need to "export" new keys from your device to specter. That process is not working for Bitcoin-Core-Hotwallets so instead, we're creating the device anew. Based on that new device, you can create the wallet. But now, how can you get your hands on some funds? Answer: Stop and restart the regtest-node. It will automatically detect existing wallets and fund them.

But let's continue on a checked out version of specter.

Let's clone the sourcecode.

git clone https://github.com/cryptoadvance/specter-desktop.git
cd specter-desktop

Especially if you waork with sourcecode, you have to use a virtualenv. So let's get one. Much more on that in the Development-documentation.

virtualenv --python=python3 .env
. ./.env/bin/activate
# install the requirements
pip3 install -r requirements.txt --require-hashes 
# start the server
python3 -m cryptoadvance.specter server

At this point, we can start developing. Get a IDE (e.g. VisualStudio which i'm using) and maybe look into the good-first-issues.

Also a good idea is to run the tests:

pytest

Here is more about running the pytests.

A very interesting detail about testing in specter-desktop are the cypress-ui-tests. Run like them like this:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment