blockchain: Generic blockchain implementation.

[ blockchain, bsd3, library ] [ Propose Tags ]
Versions, 0.0.1, 0.0.2, 0.0.3
Dependencies aeson, base (>=4.7 && <5), byteable, bytestring, cryptonite, either, errors, hashable, memory, mtl, text, time, transformers, unordered‑containers [details]
License BSD-3-Clause
Copyright 2017 Tyler Olson
Author Tyler Olson
Category Blockchain
Home page
Uploaded by tgolson at Mon Jul 3 03:32:56 UTC 2017
Distributions NixOS:0.0.3
Downloads 761 total (14 in the last 30 days)
Rating (no votes yet) [estimated by rule of succession]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2017-07-03 [all 1 reports]
Hackage Matrix CI

Please see

[Skip to Readme]




Maintainer's Corner

For package maintainers and hackage trustees

Readme for blockchain-0.0.3

[back to package description]


Available on Hackage

Generic blockchain implementation in Haskell. Heavily inspired by Bitcoin blockchain, but does not fully comply to the Bitcoin blockchain spec. Should be suitable for creating arbitrary Bitcoin-like blockchains with in various configurations.


$ stack build


$ stack test                          -- run unit tests
$ ./scripts/test_mining <num-miners>  -- run test mining network
$ ./scripts/test_stats <file-path>    -- print blockchain stats

notable differences from Bitcoin blockchain

  • Merkle root computed with extra leaves at end of tree (compared to extra leaves duplicated in bitcoin)
  • Entities serialized as json
  • Blockchain config is encoded in blockchain
  • Blocks include a dedicated coinbase transaction field to simplify special case handling
  • Block headers include an additional field for coinbase transaction hash
  • A "transaction in" must declare its previous transaction hash as either a coinbase transaction or a normal transaction

design goals

  • Enforce invariants in types whenever possible (non-empty transactions, genesis block, coinbase transactions, etc.)
  • Make it simple to create blockchains with arbitrary configurations
  • Make construction of unverified blockchains easy, but provide assurance any validated blockchain instance conforms to expected rules
  • Blocks & transactions are never presumed to be a valid part of a blockchain unless present in a validated blockchain
  • Adding new blocks to a validated blockchain can assume validity prior parts of the blockchain
  • Inspecting unspent transaction outputs of a validated blockchain can assume validity of all transactions
  • Blockchain should be readily serializable


A blockchain is a config and a tree of blocks with each node having a potentially infinite set of branches. A Blockchain also includes a tag to note whether is has been verified to meet all the expected conditions -- Blockchain Validated or Blockchain Unvalidated.

data Blockchain a = Blockchain
    { _config :: BlockchainConfig
    , _node   :: BlockchainNode

data BlockchainNode = BlockchainNode
    { nodeBlock :: Block
    , nodeNodes :: [BlockchainNode]

Blockchain construction revolves around three basic functions. Note: the BlockchainNode constructor is exported, while the top level Blockchain constructor is not.

-- build an unvalidated blockchain from a config and node
construct :: BlockchainConfig -> BlockchainNode -> Blockchain Unvalidated

-- validate the blockchain
validate :: Blockchain Unvalidated -> Either ValidationException (Blockchain Validated)

-- add a block
addBlock :: Block -> Blockchain Validated -> Either BlockException (Blockchain Validated)

Finally, blocks are created by mining. This is a process of finding a Block with a certain shape so that it satisfies the expected difficulty, as defined in the blockchain config. Blocks are mined with the coinbase reward going to the provided public key. Note: this function may take a long time to finish executing. Most realistic use cases should run this in a separate thread that can be canceled.

mineBlock :: PublicKey -> [Transaction] -> Blockchain Validated -> IO (Either MineBlockException Block)


  • Test attempts to double spend address funds -- particularly within the same transaction
  • Implement createTransaction (currently only createSimpleTransaction)
  • Function that validates transactions -- outside of create transaction logic
  • Implement max transaction count per block
  • Cache block header hash on block (and maybe transactions) for more efficient operations
    • Maybe cache on the blockchain itself, and validate computes/checks hashes?
  • Run lint in CI