bitcoin-s/wallet
Torkel Rogstad 30e6d7030f Somewhat dirty standalone server and CLI binary (#558)
* PoC bitcoin-s-cli

* Add CLI, Server sbt projects, remove Ammonite

In this commit we set up sbt configuration for
CLI, Server (in-work-name) and corresponding
test projects.

We also remove Ammonite shell from sbt, as that
isn't really being used. bloop console offers
the same functionality way more ergonimic.

* Move BitcoinSAppConfig into new server project

Server project depends on node, chain wand wallet
so this is a good time for introducing this class
into main sources. We also introduce
BitcoinSTestAppConfig in testkit, to replace the
functionality in BitcoinSAppConfig related to
tests.

* Type chain in blockchainresult

* MVP server setup for node, chain and wallet

* Extremely dirty CLI for interacting with server

* initial attempt at mimicking Bitcoin Core API

* WalletStorage: add method for checking for seed existance

* Check for seed existance on wallet startup

* Fix bug where MnemonicNotFound was not an error

* Segregate confirmed and unconfirmed balance methods

* Add error handling, improve formatting of CLI output

* Tweak build

Bump Sttp version, downgrade to uPickle 2.11 compat,
skip publish in cli-test and server-test

* Add CLI, server and picklers to root project
2019-07-10 06:33:17 -05:00
..
src/main/scala/org/bitcoins/wallet Somewhat dirty standalone server and CLI binary (#558) 2019-07-10 06:33:17 -05:00
README.md Process outgoing transactions (#555) 2019-07-09 06:25:24 -05:00

wallet

This is meant to be a stand alone project that can be used as a cold storage wallet and hot wallet.

Features

  • utxo storage
  • key storage
  • key generation
  • coin selection
  • transaction building
  • fee calculation

Design choices

  • Private key material is just stored once, as the mnemonic code used to initialize the wallet
  • Addresses we hand out to users are stored with their BIP44/BIP49/BIP84 paths and script types, so that everything we need for spending the money sent to an address is derivable.
  • The wallet is a "dumb" wallet that acts mostly as a database of UTXOs, transactions and addresses, with associated operations on these. The wallet module does very little verification of incoming data about transactions, UTXOs and reorgs. We're aiming to write small, self contained modules, that can be composed together into more fully fledged systems. That means the chain and node modules does the actual verification of data we receive, and wallet just blindly acts on this. This results in a design where you can swap out node for a Bitcoin Core full node, use it with hardware wallets, or something else entirely. However, that also means that users of wallet that doesn't want to use the other modules we provide have to make sure that the data they are feeding the wallet is correct.

Database structure

We store information in the following tables:

  • TXOs - Contains both the information needed to spent it as well as information related to wallet state (confirmations, spent/unspent etc)
  • Addresses - must reference the account it belongs to
  • Accounts

Mnemonic encryption

The mnemonic seed to the Bitcoin-S wallet is written to disk, encrypted. The file name is $HOME/.bitcoin-s/$NETWORK/encrypted_bitcoin-s_seed.json. We store it in a JSON object that looks like this:

{
  "iv": "initializationVector",
  "cipherText": "encryptedCipherText",
  "salt": "saltUsedInEncryption"
}

The parts that's relevant to this part of the wallet is WalletStorage.scala (where we handle the actual reading from and writing to disk), EncryptedMnemonic.scala (where we convert an encrypted mnemonic to a cleartext mnemonic) and AesCrypt.scala (where do the actual encryption/decryption).

We use AES encryption for this, block cipher mode and PKCS5 padding. The wallet password is fed into the PBKDF2 key stretching function, using SHA512 as the HMAC function. This happens in PBKDF2.scala.