Bootstrapping Haskell for Bitcoin development
August 20, 2014, in bitcoin

It’s time to get our hands dirty. Let’s begin bootstrapping our Haskell development environment. Before we proceed it’s probably fair to note that it’s very early days for Bitcoin development using Haskell and like users of most languages one should expect the Bitcoin libraries to be changing rapidly.

Never the less the authors of Haskoin have done a remarkable job implementing a Bitcoin library in Haskell from scratch — this includes most (if not all) the low-level elliptic curve cryptography functionality. They are distributing the library with a public domain license but their aim is to build a commercial wallet service on top of the library. Please consider signing up for their service to show them your support.

Now I will show you how to create a sandboxed environment for your Bitcoin projects. This will reduce the risk of dependency conflicts (a.k.a. dependency hell) by installing a sandboxed version of all the dependencies independent of other projects. Later we will see how we can share a sandbox between different Bitcoin projects. We will also likely require the bleeding edge development version of Haskoin pulled from GitHub and in due time I’ll show you how to link the development version to your sandboxed project.

In Haskell packages and dependencies are published to Hackage and managed by Cabal and since version 1.18 it has included support for sandboxed environments.

$ mkdir test-haskoin    
$ cd test-haskoin
$ cabal sandbox init    [1]
$ cabal update          [2]

[1] Initializes the sandbox and stores files in .cabal-sandbox
[2] Download the package index from Hackage

Edit (2014-08-24): xenog one of the developers behind Haskoin reached out to notify me about the removal of icu as a dependency for the library. I have greyed out the following and now irrelevant section of the post.

Under normal circumstances we would be able to add Haskoin as a dependency in our .cabal file but since Haskoin depends on the C icu library which is sometimes installed outside the default C library locations (like /usr/local/opt) we either need to include the library location in the .cabal file or install the library manually with the extra command line parameters --extra-include-dirs and --extra-lib-dirs.

On an OS X it is easiest to install the library using brew but please refer to the icu download page for installation instructions for your operating system of choice.

$ brew install icu4c
$ cabal install --extra-include-dirs=/usr/local/opt/icu4c/include \
                --extra-lib-dirs=/usr/local/opt/icu4c/lib text-icu

Next we cabalize our test-haskell project.

$ cabal init

This takes us to a project wizard. Answering the questions is relatively straight forward. The resulting project file — test-haskell.cabal — describes the project and its dependencies.

Add Haskoin as a dependency to the .cabal file.

build-depends:       base >=4.6 && <4.7, haskoin ==0.1.0.*

Uncomment the following line by removing the two dashes.

-- main-is:         Main.hs

Make sure that Main.hs exists with this content.

module Main where

main :: IO ()
main = putStrLn "If this prints we're all done :)"

The last step is to install the dependencies, compile the project and hopefully see our achievement printed to stdout.

$ cabal configure
$ cabal install --dependencies-only
$ cabal build
$ cabal run

Actually, running cabal run will usually be enough as it will trigger the install and build events automatically.

In my next post in this series we will experiment with our sandboxed, cabalized Haskoin environment.