diff --git a/blockchain.cabal b/blockchain.cabal
--- a/blockchain.cabal
+++ b/blockchain.cabal
@@ -3,7 +3,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           blockchain
-version:        0.0.1
+version:        0.0.2
 synopsis:       Generic blockchain implementation.
 description:    Please see README.md
 category:       Blockchain
@@ -41,20 +41,21 @@
     , unordered-containers
   exposed-modules:
       Data.Blockchain.Core.Blockchain
-      Data.Blockchain.Core.Builder.Transaction
+      Data.Blockchain.Core.Builder
       Data.Blockchain.Core.Crypto
+      Data.Blockchain.Core.Types
+      Data.Blockchain.Mining
+  other-modules:
       Data.Blockchain.Core.Crypto.ECDSA
       Data.Blockchain.Core.Crypto.Hash
       Data.Blockchain.Core.Crypto.HashTree
-      Data.Blockchain.Core.Types
       Data.Blockchain.Core.Types.Block
       Data.Blockchain.Core.Types.BlockchainConfig
       Data.Blockchain.Core.Types.Difficulty
+      Data.Blockchain.Core.Types.Hex
       Data.Blockchain.Core.Types.Transaction
-      Data.Blockchain.Core.Util.Hex
       Data.Blockchain.Mining.Block
       Data.Blockchain.Mining.Blockchain
-  other-modules:
       Paths_blockchain
   default-language: Haskell2010
 
@@ -94,8 +95,8 @@
       Data.Blockchain.Core.Crypto.HashTreeSpec
       Data.Blockchain.Core.Types.BlockchainConfigSpec
       Data.Blockchain.Core.Types.DifficultySpec
+      Data.Blockchain.Core.Types.HexSpec
       Data.Blockchain.Core.Types.TransactionSpec
-      Data.Blockchain.Core.Util.HexSpec
       Data.Blockchain.Mining.BlockSpec
       Integration.Mining
       Integration.Stats
diff --git a/lib/Data/Blockchain/Core/Blockchain.hs b/lib/Data/Blockchain/Core/Blockchain.hs
--- a/lib/Data/Blockchain/Core/Blockchain.hs
+++ b/lib/Data/Blockchain/Core/Blockchain.hs
@@ -1,5 +1,4 @@
 module Data.Blockchain.Core.Blockchain
-    -- Types
     ( Validated
     , Unvalidated
     , Blockchain
@@ -8,14 +7,14 @@
     , BlockchainNode(..)
     , ValidationException(..)
     , BlockException(..)
-    -- Construction
+    -- * Construction
     , construct
     , validate
     , addBlock
-    -- Validation
+    -- * Validation
     , validateTransaction
     , validateTransactions
-    -- Chain inspection
+    -- * Chain inspection
     , blockHeaderHashDifficulty
     , addressValues
     , unspentTransactionOutputs
@@ -23,30 +22,34 @@
     , flatten
     ) where
 
-import           Control.Monad                 (unless)
-import qualified Data.Aeson                    as Aeson
-import qualified Data.Aeson.Types              as Aeson
-import qualified Data.Char                     as Char
-import qualified Data.Either                   as Either
-import qualified Data.Either.Combinators       as Either
-import qualified Data.Foldable                 as Foldable
-import qualified Data.HashMap.Strict           as H
-import qualified Data.List                     as List
-import qualified Data.List.NonEmpty            as NonEmpty
-import           Data.Monoid                   ((<>))
-import qualified Data.Ord                      as Ord
-import qualified Data.Word                     as Word
-import qualified GHC.Generics                  as Generic
+import           Control.Monad               (unless)
+import qualified Data.Aeson                  as Aeson
+import qualified Data.Aeson.Types            as Aeson
+import qualified Data.Char                   as Char
+import qualified Data.Either                 as Either
+import qualified Data.Either.Combinators     as Either
+import qualified Data.Foldable               as Foldable
+import qualified Data.HashMap.Strict         as H
+import qualified Data.List                   as List
+import qualified Data.List.NonEmpty          as NonEmpty
+import           Data.Monoid                 ((<>))
+import qualified Data.Ord                    as Ord
+import qualified Data.Word                   as Word
+import qualified GHC.Generics                as Generic
 
-import qualified Data.Blockchain.Core.Crypto   as Crypto
+import qualified Data.Blockchain.Core.Crypto as Crypto
 import           Data.Blockchain.Core.Types
-import qualified Data.Blockchain.Core.Util.Hex as Hex
 
 -- Types ----------------------------------------------------------------------------------------------------
 
 data Validated
 data Unvalidated
 
+-- | Core blockchain data type. Uses a validation tag to declare if it is known to abide by expected blockchain rules.
+-- Will be either @'Blockchain' 'Validated'@ or @'Blockchain' 'Unvalidated'@.
+--
+-- Note: both @'Blockchain' 'Validated'@ and @'Blockchain' 'Unvalidated'@ can be serialized to json,
+-- while only @'Blockchain' 'Unvalidated'@ can be deserialized from json.
 data Blockchain a = Blockchain
     { _config :: BlockchainConfig
     , _node   :: BlockchainNode
@@ -105,10 +108,12 @@
 
 -- Construction ---------------------------------------------------------------------------------------------
 
+-- | Constructs an unvalidated blockchain from a config and a node.
+-- Allows arbitrary blockchains to be constructed. However, blockchains are generally not useful until validated.
 construct :: BlockchainConfig -> BlockchainNode -> Blockchain Unvalidated
 construct = Blockchain
 
-
+-- | Validates a blockchain. Returns a 'ValidationException' if provided blockchain does not meet expected rules.
 validate :: Blockchain Unvalidated -> Either ValidationException (Blockchain Validated)
 validate (Blockchain config (BlockchainNode genesisBlock nodes)) = do
     let (Block header _coinbase txs) = genesisBlock
@@ -124,7 +129,7 @@
   where
     getBlocks (BlockchainNode block ns) = block : (ns >>= getBlocks)
 
-
+-- | Adds a block to a validated blockchain. Returns a 'BlockException' if block is not able to be inserted into the blockchain.
 addBlock :: Block -> Blockchain Validated -> Either BlockException (Blockchain Validated)
 addBlock newBlock (Blockchain config node) = Blockchain config <$> addBlockToNode mempty node
   where
@@ -191,7 +196,7 @@
 -- Exported util
 -- TODO: find better place for this function
 
-blockHeaderHashDifficulty :: Hex.Hex256 -> BlockHeader -> Difficulty
+blockHeaderHashDifficulty :: Hex256 -> BlockHeader -> Difficulty
 blockHeaderHashDifficulty diff1 header = fromIntegral $ diff1 `div` Crypto.hashToHex (Crypto.hash header)
 
 
diff --git a/lib/Data/Blockchain/Core/Builder.hs b/lib/Data/Blockchain/Core/Builder.hs
new file mode 100644
--- /dev/null
+++ b/lib/Data/Blockchain/Core/Builder.hs
@@ -0,0 +1,61 @@
+module Data.Blockchain.Core.Builder
+    ( CreateTransactionException(..)
+    , createSimpleTransaction
+    ) where
+
+import           Control.Monad                   (unless, when)
+import           Control.Monad.Trans.Class       (lift)
+
+import qualified Control.Error.Util              as Error
+import qualified Control.Monad.Except            as Except
+import qualified Data.HashMap.Strict             as H
+import qualified Data.List.NonEmpty              as NonEmpty
+import qualified Data.Word                       as Word
+
+import qualified Data.Blockchain.Core.Blockchain as Blockchain
+import qualified Data.Blockchain.Core.Crypto     as Crypto
+import qualified Data.Blockchain.Core.Types      as Blockchain
+
+data CreateTransactionException
+    = SourceAddressEmpty
+    | SourceAddressInsufficientFunds
+    | InvalidPrivateKey
+  deriving (Eq, Show)
+
+-- TODO
+-- createTransaction
+--     :: [Crypto.KeyPair] -> [(Crypto.PublicKey, Int)] -> Int -> Blockchain.Blockchain Blockchain.Validated
+--     -> Either CreateTransactionException Blockchain.Transaction
+-- createTransaction _srcs _targets _fee _blockchain = undefined
+
+-- | Create a transaction from a single public key address.
+createSimpleTransaction
+    :: Crypto.KeyPair   -- ^ KeyPair for source address. PrivateKey will be used to sign transaction.
+    -> Crypto.PublicKey -- ^ Target address
+    -> Word.Word        -- ^ Transaction value
+    -> Word.Word        -- ^ Fee
+    -> Blockchain.Blockchain Blockchain.Validated -- ^ Validated blockchain
+    -> IO (Either CreateTransactionException Blockchain.Transaction)
+createSimpleTransaction (Crypto.KeyPair srcPubKey srcPrivKey) targetPubKey value fee blockchain = Except.runExceptT $ do
+    let unspentTransactionOutputs = Blockchain.unspentTransactionOutputs blockchain
+
+    txOutPairs <- Error.failWith SourceAddressEmpty $ H.lookup srcPubKey unspentTransactionOutputs
+
+    let txOuts     = snd <$> txOutPairs
+        totalValue = sum $ Blockchain.value <$> txOuts
+
+    when (totalValue < (value + fee)) $ Except.throwError SourceAddressInsufficientFunds
+
+    txIns <- sequence $ flip fmap txOutPairs $ \(txOutRef, txOut) -> do
+        sig <- lift $ Blockchain.signTransaction srcPrivKey txOut
+        unless (Blockchain.verifyTransactionSignature sig txOut) $ Except.throwError InvalidPrivateKey
+
+        return (Blockchain.TransactionIn txOutRef sig)
+
+    let refund           = totalValue - (value + fee)
+        txOut            = Blockchain.TransactionOut value targetPubKey
+        maybeRefundTxOut = if refund > 0 then Just (Blockchain.TransactionOut refund srcPubKey)
+                                         else Nothing
+        txOuts'          = maybe (pure txOut) (: pure txOut) maybeRefundTxOut
+
+    return $ Blockchain.Transaction (NonEmpty.fromList txIns) (NonEmpty.fromList txOuts')
diff --git a/lib/Data/Blockchain/Core/Builder/Transaction.hs b/lib/Data/Blockchain/Core/Builder/Transaction.hs
deleted file mode 100644
--- a/lib/Data/Blockchain/Core/Builder/Transaction.hs
+++ /dev/null
@@ -1,58 +0,0 @@
-module Data.Blockchain.Core.Builder.Transaction
-    ( CreateTransactionException(..)
-    -- , createTransaction
-    , createSimpleTransaction
-    ) where
-
-import           Control.Monad                   (unless, when)
-import           Control.Monad.Trans.Class       (lift)
-
-import qualified Control.Error.Util              as Error
-import qualified Control.Monad.Except            as Except
-import qualified Data.HashMap.Strict             as H
-import qualified Data.List.NonEmpty              as NonEmpty
-import qualified Data.Word                       as Word
-
-import qualified Data.Blockchain.Core.Blockchain as Blockchain
-import qualified Data.Blockchain.Core.Crypto     as Crypto
-import qualified Data.Blockchain.Core.Types      as Blockchain
-
-data CreateTransactionException
-    = SourceAddressEmpty
-    | SourceAddressInsufficientFunds
-    | InvalidPrivateKey
-  deriving (Eq, Show)
-
--- TODO
--- createTransaction
---     :: [Crypto.KeyPair] -> [(Crypto.PublicKey, Int)] -> Int -> Blockchain.Blockchain Blockchain.Validated
---     -> Either CreateTransactionException Blockchain.Transaction
--- createTransaction _srcs _targets _fee _blockchain = undefined
-
-createSimpleTransaction
-    :: Crypto.KeyPair -> Crypto.PublicKey
-    -> Word.Word -> Word.Word -> Blockchain.Blockchain Blockchain.Validated
-    -> IO (Either CreateTransactionException Blockchain.Transaction)
-createSimpleTransaction (Crypto.KeyPair srcPubKey srcPrivKey) targetPubKey value fee blockchain = Except.runExceptT $ do
-    let unspentTransactionOutputs = Blockchain.unspentTransactionOutputs blockchain
-
-    txOutPairs <- Error.failWith SourceAddressEmpty $ H.lookup srcPubKey unspentTransactionOutputs
-
-    let txOuts     = snd <$> txOutPairs
-        totalValue = sum $ Blockchain.value <$> txOuts
-
-    when (totalValue < (value + fee)) $ Except.throwError SourceAddressInsufficientFunds
-
-    txIns <- sequence $ flip fmap txOutPairs $ \(txOutRef, txOut) -> do
-        sig <- lift $ Blockchain.signTransaction srcPrivKey txOut
-        unless (Blockchain.verifyTransactionSignature sig txOut) $ Except.throwError InvalidPrivateKey
-
-        return (Blockchain.TransactionIn txOutRef sig)
-
-    let refund           = totalValue - (value + fee)
-        txOut            = Blockchain.TransactionOut value targetPubKey
-        maybeRefundTxOut = if refund > 0 then Just (Blockchain.TransactionOut refund srcPubKey)
-                                         else Nothing
-        txOuts'          = maybe (pure txOut) (: pure txOut) maybeRefundTxOut
-
-    return $ Blockchain.Transaction (NonEmpty.fromList txIns) (NonEmpty.fromList txOuts')
diff --git a/lib/Data/Blockchain/Core/Crypto.hs b/lib/Data/Blockchain/Core/Crypto.hs
--- a/lib/Data/Blockchain/Core/Crypto.hs
+++ b/lib/Data/Blockchain/Core/Crypto.hs
@@ -1,7 +1,9 @@
 module Data.Blockchain.Core.Crypto
-    ( module X
+    ( module Data.Blockchain.Core.Crypto.ECDSA
+    , module Data.Blockchain.Core.Crypto.Hash
+    , module Data.Blockchain.Core.Crypto.HashTree
     ) where
 
-import           Data.Blockchain.Core.Crypto.ECDSA    as X
-import           Data.Blockchain.Core.Crypto.Hash     as X
-import           Data.Blockchain.Core.Crypto.HashTree as X
+import           Data.Blockchain.Core.Crypto.ECDSA
+import           Data.Blockchain.Core.Crypto.Hash
+import           Data.Blockchain.Core.Crypto.HashTree
diff --git a/lib/Data/Blockchain/Core/Crypto/ECDSA.hs b/lib/Data/Blockchain/Core/Crypto/ECDSA.hs
--- a/lib/Data/Blockchain/Core/Crypto/ECDSA.hs
+++ b/lib/Data/Blockchain/Core/Crypto/ECDSA.hs
@@ -8,17 +8,17 @@
     , generate
     ) where
 
-import qualified Crypto.Hash                   as Crypto
-import qualified Crypto.PubKey.ECC.ECDSA       as Crypto
-import qualified Crypto.PubKey.ECC.Generate    as Crypto
-import qualified Crypto.PubKey.ECC.Types       as Crypto
-import qualified Data.Aeson                    as Aeson
-import qualified Data.ByteString               as BS
-import qualified Data.Hashable                 as H
-import           Data.Monoid                   ((<>))
-import qualified Data.Text                     as Text
+import qualified Crypto.Hash                    as Crypto
+import qualified Crypto.PubKey.ECC.ECDSA        as Crypto
+import qualified Crypto.PubKey.ECC.Generate     as Crypto
+import qualified Crypto.PubKey.ECC.Types        as Crypto
+import qualified Data.Aeson                     as Aeson
+import qualified Data.ByteString                as BS
+import qualified Data.Hashable                  as H
+import           Data.Monoid                    ((<>))
+import qualified Data.Text                      as Text
 
-import           Data.Blockchain.Core.Util.Hex
+import           Data.Blockchain.Core.Types.Hex
 
 -- Types -----------------------------------------------------------------------------------------------------
 
diff --git a/lib/Data/Blockchain/Core/Crypto/Hash.hs b/lib/Data/Blockchain/Core/Crypto/Hash.hs
--- a/lib/Data/Blockchain/Core/Crypto/Hash.hs
+++ b/lib/Data/Blockchain/Core/Crypto/Hash.hs
@@ -6,17 +6,17 @@
     , unsafeFromByteString
     ) where
 
-import qualified Crypto.Hash                   as Crypto
-import qualified Data.Aeson                    as Aeson
-import qualified Data.ByteArray.Encoding       as Byte
-import qualified Data.ByteString               as BS
-import qualified Data.ByteString.Lazy          as Lazy
-import qualified Data.Hashable                 as H
-import qualified Data.Maybe                    as Maybe
-import qualified Data.Text                     as Text
-import qualified Data.Text.Encoding            as Text
+import qualified Crypto.Hash                    as Crypto
+import qualified Data.Aeson                     as Aeson
+import qualified Data.ByteArray.Encoding        as Byte
+import qualified Data.ByteString                as BS
+import qualified Data.ByteString.Lazy           as Lazy
+import qualified Data.Hashable                  as H
+import qualified Data.Maybe                     as Maybe
+import qualified Data.Text                      as Text
+import qualified Data.Text.Encoding             as Text
 
-import qualified Data.Blockchain.Core.Util.Hex as Hex
+import qualified Data.Blockchain.Core.Types.Hex as Hex
 
 -- Types -----------------------------------------------------------------------------------------------------
 
diff --git a/lib/Data/Blockchain/Core/Types.hs b/lib/Data/Blockchain/Core/Types.hs
--- a/lib/Data/Blockchain/Core/Types.hs
+++ b/lib/Data/Blockchain/Core/Types.hs
@@ -1,8 +1,13 @@
 module Data.Blockchain.Core.Types
-    ( module X
+    ( module Data.Blockchain.Core.Types.Block
+    , module Data.Blockchain.Core.Types.BlockchainConfig
+    , module Data.Blockchain.Core.Types.Difficulty
+    , module Data.Blockchain.Core.Types.Hex
+    , module Data.Blockchain.Core.Types.Transaction
     ) where
 
-import           Data.Blockchain.Core.Types.Block            as X
-import           Data.Blockchain.Core.Types.BlockchainConfig as X
-import           Data.Blockchain.Core.Types.Difficulty       as X
-import           Data.Blockchain.Core.Types.Transaction      as X
+import           Data.Blockchain.Core.Types.Block
+import           Data.Blockchain.Core.Types.BlockchainConfig
+import           Data.Blockchain.Core.Types.Difficulty
+import           Data.Blockchain.Core.Types.Hex
+import           Data.Blockchain.Core.Types.Transaction
diff --git a/lib/Data/Blockchain/Core/Types/BlockchainConfig.hs b/lib/Data/Blockchain/Core/Types/BlockchainConfig.hs
--- a/lib/Data/Blockchain/Core/Types/BlockchainConfig.hs
+++ b/lib/Data/Blockchain/Core/Types/BlockchainConfig.hs
@@ -13,12 +13,12 @@
 
 import           Data.Blockchain.Core.Types.Block
 import           Data.Blockchain.Core.Types.Difficulty
-import qualified Data.Blockchain.Core.Util.Hex         as Hex
+import           Data.Blockchain.Core.Types.Hex
 
 data BlockchainConfig = BlockchainConfig
     { initialDifficulty             :: Difficulty
     -- Maximum hash - difficulties will be calculated using this value
-    , difficulty1Target             :: Hex.Hex256
+    , difficulty1Target             :: Hex256
     , targetSecondsPerBlock         :: Word.Word
     , difficultyRecalculationHeight :: Word.Word
     , initialMiningReward           :: Word.Word
@@ -30,16 +30,32 @@
 instance Aeson.FromJSON BlockchainConfig
 instance Aeson.ToJSON BlockchainConfig
 
+-- | A reasonable default config to use for testing. Mines blocks quickly and changes difficulty and rewards frequently.
+-- Note: reward will go to zero after 1100 blocks, which will take about 180 minutes of mining.
+--
+-- @
+-- defaultConfig :: BlockchainConfig
+-- defaultConfig = BlockchainConfig
+--     { initialDifficulty             = Difficulty 1
+--     , difficulty1Target             = hex256LeadingZeros 4
+--     , targetSecondsPerBlock         = 10
+--     , difficultyRecalculationHeight = 50
+--     , initialMiningReward           = 1024
+--     , miningRewardHalvingHeight     = 100
+--     }
+-- @
+--
 defaultConfig :: BlockchainConfig
 defaultConfig = BlockchainConfig
     { initialDifficulty             = Difficulty 1
-    , difficulty1Target             = Hex.hex256LeadingZeros 4
+    , difficulty1Target             = hex256LeadingZeros 4
     , targetSecondsPerBlock         = 10
-    , difficultyRecalculationHeight = 100
-    , initialMiningReward           = 100
-    , miningRewardHalvingHeight     = 500
+    , difficultyRecalculationHeight = 50
+    , initialMiningReward           = 1024
+    , miningRewardHalvingHeight     = 100
     }
 
+-- | Calculates the target reward for a blockchain. Uses the longest chain.
 targetReward :: BlockchainConfig -> Word.Word -> Word.Word
 targetReward config height = either id id $ do
     let initialReward = initialMiningReward config
@@ -58,6 +74,8 @@
 -- TODO: array of blocks hold no assurances of expected invariants
 -- for example block1 could be created more recently than blockN
 -- should create a `SingleChain` wrapper
+-- TODO: take in entire blockchain
+-- | Calculates the target difficulty for a blockchain. Uses the longest chain.
 targetDifficulty :: BlockchainConfig -> [Block] -> Difficulty
 targetDifficulty config []                                            = initialDifficulty config
 targetDifficulty config _ | difficultyRecalculationHeight config == 0 = initialDifficulty config
diff --git a/lib/Data/Blockchain/Core/Types/Difficulty.hs b/lib/Data/Blockchain/Core/Types/Difficulty.hs
--- a/lib/Data/Blockchain/Core/Types/Difficulty.hs
+++ b/lib/Data/Blockchain/Core/Types/Difficulty.hs
@@ -2,10 +2,10 @@
     ( Difficulty(..)
     ) where
 
-import qualified Data.Aeson                    as Aeson
-import qualified Numeric.Natural               as Natural
+import qualified Data.Aeson                     as Aeson
+import qualified Numeric.Natural                as Natural
 
-import qualified Data.Blockchain.Core.Util.Hex as Hex
+import qualified Data.Blockchain.Core.Types.Hex as Hex
 
 newtype Difficulty = Difficulty { unDifficulty :: Natural.Natural }
   deriving (Aeson.FromJSON, Aeson.ToJSON, Enum, Eq, Integral, Num, Real, Ord, Show)
diff --git a/lib/Data/Blockchain/Core/Types/Hex.hs b/lib/Data/Blockchain/Core/Types/Hex.hs
new file mode 100644
--- /dev/null
+++ b/lib/Data/Blockchain/Core/Types/Hex.hs
@@ -0,0 +1,64 @@
+module Data.Blockchain.Core.Types.Hex
+    ( Hex256(..)
+    , hex256
+    , hex256LeadingZeros
+    ) where
+
+import           Control.Monad   (unless)
+import qualified Data.Aeson      as Aeson
+import qualified Data.Maybe      as Maybe
+import           Data.Monoid     ((<>))
+import qualified Data.Text       as Text
+import qualified Data.Word       as Word
+import qualified Numeric
+import qualified Numeric.Natural as Natural
+
+-- Types -----------------------------------------------------------------------------------------------------
+
+newtype Hex256 = Hex256 { unHex256 :: Natural.Natural }
+  deriving (Enum, Eq, Integral, Num, Real, Ord)
+
+instance Show Hex256 where
+    show = zeroPadded 64 . showHex . unHex256
+
+instance Bounded Hex256 where
+    minBound = 0
+    maxBound = Maybe.fromMaybe (error "Unexpected parse failure") $ readHexMaybe $ replicate 64 'f'
+
+instance Aeson.ToJSON Hex256 where
+    toJSON = Aeson.String . Text.pack . show
+
+instance Aeson.FromJSON Hex256 where
+    parseJSON = Aeson.withText "Hex256" parseHex256
+      where
+        parseHex256 = maybe (fail "Invalid hex 256 string") return . hex256 . Text.unpack
+
+-- Construction helpers --------------------------------------------------------------------------------------
+
+-- | Create a Hex256 value with the specificed amount of leading zeros.
+-- Useful for creating a 'Data.Blockchain.Core.Types.BlockchainConfig.difficulty1Target' when creating a blockchain.
+--
+-- >>> hex256LeadingZeros 4
+-- 0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+--
+hex256LeadingZeros :: Word.Word -> Hex256
+hex256LeadingZeros n = maxBound `div` Hex256 (16 ^ n)
+
+hex256 :: String -> Maybe Hex256
+hex256 str = do
+    unless (length str == 64) Nothing
+    x <- readHexMaybe str
+    return (Hex256 x)
+
+readHexMaybe :: (Num a, Eq a) => String -> Maybe a
+readHexMaybe str = case Numeric.readHex str of
+    [(x, "")] -> Just x
+    _         -> Nothing
+
+-- Utils -----------------------------------------------------------------------------------------------------
+
+showHex :: (Show a, Integral a) => a -> String
+showHex x = Numeric.showHex x mempty
+
+zeroPadded :: Int -> String -> String
+zeroPadded x str = replicate (x - length str) '0' <> str
diff --git a/lib/Data/Blockchain/Core/Types/Transaction.hs b/lib/Data/Blockchain/Core/Types/Transaction.hs
--- a/lib/Data/Blockchain/Core/Types/Transaction.hs
+++ b/lib/Data/Blockchain/Core/Types/Transaction.hs
@@ -40,8 +40,7 @@
 
 data TransactionIn = TransactionIn
     { transactionOutRef :: TransactionOutRef
-     -- Signature from prev transaction, using pubkey from prev transaction
-    , signature         :: Crypto.Signature
+    , signature         :: Crypto.Signature -- ^ Signature from prev transaction, using pubkey from prev transaction
     }
   deriving (Generic.Generic, Eq, Show)
 
@@ -49,7 +48,7 @@
 instance Aeson.FromJSON TransactionIn
 instance Crypto.ToHash TransactionIn
 
--- Pointer to a specific TransactionOut
+-- | Pointer to a specific TransactionOut
 data TransactionOutRef = TransactionOutRef
     { transactionHash     :: Either (Crypto.Hash CoinbaseTransaction) (Crypto.Hash Transaction)
     , transactionOutIndex :: Word.Word
@@ -63,7 +62,7 @@
 
 data TransactionOut = TransactionOut
     { value           :: Word.Word
-    , signaturePubKey :: Crypto.PublicKey -- aka. address of where funds go
+    , signaturePubKey :: Crypto.PublicKey -- ^ Address of where funds go
     }
   deriving (Generic.Generic, Eq, Show)
 
diff --git a/lib/Data/Blockchain/Core/Util/Hex.hs b/lib/Data/Blockchain/Core/Util/Hex.hs
deleted file mode 100644
--- a/lib/Data/Blockchain/Core/Util/Hex.hs
+++ /dev/null
@@ -1,58 +0,0 @@
-module Data.Blockchain.Core.Util.Hex
-    ( Hex256(..)
-    , hex256
-    , hex256LeadingZeros
-    ) where
-
-import           Control.Monad   (unless)
-import qualified Data.Aeson      as Aeson
-import qualified Data.Maybe      as Maybe
-import           Data.Monoid     ((<>))
-import qualified Data.Text       as Text
-import qualified Data.Word       as Word
-import qualified Numeric
-import qualified Numeric.Natural as Natural
-
--- Types -----------------------------------------------------------------------------------------------------
-
-newtype Hex256 = Hex256 { unHex256 :: Natural.Natural }
-  deriving (Enum, Eq, Integral, Num, Real, Ord)
-
-instance Show Hex256 where
-    show = zeroPadded 64 . showHex . unHex256
-
-instance Bounded Hex256 where
-    minBound = 0
-    maxBound = Maybe.fromMaybe (error "Unexpected parse failure") $ readHexMaybe $ replicate 64 'f'
-
-instance Aeson.ToJSON Hex256 where
-    toJSON = Aeson.String . Text.pack . show
-
-instance Aeson.FromJSON Hex256 where
-    parseJSON = Aeson.withText "Hex256" parseHex256
-      where
-        parseHex256 = maybe (fail "Invalid hex 256 string") return . hex256 . Text.unpack
-
--- Construction helpers --------------------------------------------------------------------------------------
-
-hex256LeadingZeros :: Word.Word -> Hex256
-hex256LeadingZeros n = maxBound `div` Hex256 (16 ^ n)
-
-hex256 :: String -> Maybe Hex256
-hex256 str = do
-    unless (length str == 64) Nothing
-    x <- readHexMaybe str
-    return (Hex256 x)
-
-readHexMaybe :: (Num a, Eq a) => String -> Maybe a
-readHexMaybe str = case Numeric.readHex str of
-    [(x, "")] -> Just x
-    _         -> Nothing
-
--- Utils -----------------------------------------------------------------------------------------------------
-
-showHex :: (Show a, Integral a) => a -> String
-showHex x = Numeric.showHex x mempty
-
-zeroPadded :: Int -> String -> String
-zeroPadded x str = replicate (x - length str) '0' <> str
diff --git a/lib/Data/Blockchain/Mining.hs b/lib/Data/Blockchain/Mining.hs
new file mode 100644
--- /dev/null
+++ b/lib/Data/Blockchain/Mining.hs
@@ -0,0 +1,7 @@
+module Data.Blockchain.Mining
+    ( module Data.Blockchain.Mining.Block
+    , module Data.Blockchain.Mining.Blockchain
+    ) where
+
+import           Data.Blockchain.Mining.Block
+import           Data.Blockchain.Mining.Blockchain
diff --git a/lib/Data/Blockchain/Mining/Block.hs b/lib/Data/Blockchain/Mining/Block.hs
--- a/lib/Data/Blockchain/Mining/Block.hs
+++ b/lib/Data/Blockchain/Mining/Block.hs
@@ -13,15 +13,16 @@
 import qualified Data.Blockchain.Core.Blockchain as Blockchain
 import qualified Data.Blockchain.Core.Crypto     as Crypto
 import qualified Data.Blockchain.Core.Types      as Blockchain
-import qualified Data.Blockchain.Core.Util.Hex   as Hex
 
 data MineBlockException
     = InvalidTransactionList
-    -- | ...
   deriving (Eq, Show)
 
+-- | Finds the next block of a blockchain. Depending on blockchain configuration, this function may take a long time to complete.
 mineBlock
-    :: Crypto.PublicKey -> [Blockchain.Transaction] -> Blockchain.Blockchain Blockchain.Validated
+    :: Crypto.PublicKey         -- ^ PublicKey address where coinbase reward will be sent
+    -> [Blockchain.Transaction] -- ^ List of transactions to include in transaction
+    -> Blockchain.Blockchain Blockchain.Validated -- ^ Validated blockchain
     -> IO (Either MineBlockException Blockchain.Block)
 mineBlock pubKey txs blockchain =
     case Blockchain.validateTransactions blockchain txs of
@@ -36,16 +37,20 @@
     prevBlock           = NonEmpty.last prevBlocks
     prevBlockHeaderHash = Crypto.hash (Blockchain.blockHeader prevBlock)
 
-
+-- | Finds the next block of a blockchain, without including any transactions.
+-- Most useful for testing - removes the invariant of an invalid transaction list.
+-- Depending on blockchain configuration, this function may take a long time to complete.
 mineEmptyBlock
-    :: Crypto.PublicKey -> Blockchain.Blockchain Blockchain.Validated
+    :: Crypto.PublicKey -- ^ PublicKey address where coinbase reward will be sent
+    -> Blockchain.Blockchain Blockchain.Validated -- ^ Validated blockchain
     -> IO (Either MineBlockException Blockchain.Block)
 mineEmptyBlock pubKey = mineBlock pubKey mempty
 
-
+-- | Finds the first block of a blockchain.
+-- Depending on blockchain configuration, this function may take a long time to complete.
+-- Note: this generates a keypair but throws away the private key. Coinbase reward in genesis block cannot never be spent.
 mineGenesisBlock :: Blockchain.BlockchainConfig -> IO Blockchain.Block
 mineGenesisBlock config = do
-    -- Note: ignore private key, coinbase reward in genesis block cannot be spent
     (Crypto.KeyPair pubKey _privKey) <- Crypto.generate
 
     mineBlockInternal pubKey reward diff1 difficulty prevBlockHeaderHash mempty
@@ -57,7 +62,7 @@
 
 -- TODO: accept multiple public keys
 mineBlockInternal
-    :: Crypto.PublicKey -> Word.Word -> Hex.Hex256 -> Blockchain.Difficulty
+    :: Crypto.PublicKey -> Word.Word -> Blockchain.Hex256 -> Blockchain.Difficulty
     -> Crypto.Hash Blockchain.BlockHeader -> [Blockchain.Transaction]
     -> IO Blockchain.Block
 mineBlockInternal pubKey reward diff1 difficulty prevBlockHeaderHash txs = do
@@ -79,7 +84,7 @@
     :: Crypto.Hash Blockchain.BlockHeader
     -> Crypto.Hash Blockchain.CoinbaseTransaction
     -> Crypto.HashTreeRoot Blockchain.Transaction
-    -> Hex.Hex256
+    -> Blockchain.Hex256
     -> Blockchain.Difficulty
     -> IO Blockchain.BlockHeader
 mineHeader prevBlockHeaderHash coinbaseTransactionHash transactionHashTreeRoot diff1 difficulty = do
diff --git a/lib/Data/Blockchain/Mining/Blockchain.hs b/lib/Data/Blockchain/Mining/Blockchain.hs
--- a/lib/Data/Blockchain/Mining/Blockchain.hs
+++ b/lib/Data/Blockchain/Mining/Blockchain.hs
@@ -1,5 +1,5 @@
 module Data.Blockchain.Mining.Blockchain
-    ( createBlockchain
+    ( mineBlockchain
     ) where
 
 import           Data.Monoid                     ((<>))
@@ -8,9 +8,10 @@
 import qualified Data.Blockchain.Core.Types      as Blockchain
 import           Data.Blockchain.Mining.Block
 
-
-createBlockchain :: Blockchain.BlockchainConfig -> IO (Blockchain.Blockchain Blockchain.Validated)
-createBlockchain config = either throwValidationError id <$> do
+-- | Creates a blockchain from the given config.
+-- This includes mining a genesis block.
+mineBlockchain :: Blockchain.BlockchainConfig -> IO (Blockchain.Blockchain Blockchain.Validated)
+mineBlockchain config = either throwValidationError id <$> do
     genesisBlock <- mineGenesisBlock config
 
     let node  = Blockchain.BlockchainNode genesisBlock mempty
diff --git a/test/ArbitraryInstances.hs b/test/ArbitraryInstances.hs
--- a/test/ArbitraryInstances.hs
+++ b/test/ArbitraryInstances.hs
@@ -6,18 +6,17 @@
 
 import           Test.QuickCheck
 
-import qualified Crypto.PubKey.ECC.ECDSA       as Crypto
-import qualified Crypto.PubKey.ECC.Types       as Crypto
-import qualified Data.ByteString.Char8         as BS
-import qualified Data.List.NonEmpty            as NonEmpty
-import           Data.Monoid                   ((<>))
-import qualified Data.Time.Calendar            as Time
-import qualified Data.Time.Clock               as Time
-import qualified Data.Word                     as Word
+import qualified Crypto.PubKey.ECC.ECDSA     as Crypto
+import qualified Crypto.PubKey.ECC.Types     as Crypto
+import qualified Data.ByteString.Char8       as BS
+import qualified Data.List.NonEmpty          as NonEmpty
+import           Data.Monoid                 ((<>))
+import qualified Data.Time.Calendar          as Time
+import qualified Data.Time.Clock             as Time
+import qualified Data.Word                   as Word
 
 import           Data.Blockchain.Core.Crypto
 import           Data.Blockchain.Core.Types
-import           Data.Blockchain.Core.Util.Hex
 
 -- Blockchain types
 
diff --git a/test/Data/Blockchain/Core/Builder/TransactionSpec.hs b/test/Data/Blockchain/Core/Builder/TransactionSpec.hs
--- a/test/Data/Blockchain/Core/Builder/TransactionSpec.hs
+++ b/test/Data/Blockchain/Core/Builder/TransactionSpec.hs
@@ -2,10 +2,10 @@
 
 import           TestUtil
 
-import qualified Data.List.NonEmpty                       as NonEmpty
+import qualified Data.List.NonEmpty              as NonEmpty
 
 import           Data.Blockchain.Core.Blockchain
-import           Data.Blockchain.Core.Builder.Transaction
+import           Data.Blockchain.Core.Builder
 import           Data.Blockchain.Core.Crypto
 import           Data.Blockchain.Core.Types
 
diff --git a/test/Data/Blockchain/Core/Crypto/ECDSASpec.hs b/test/Data/Blockchain/Core/Crypto/ECDSASpec.hs
--- a/test/Data/Blockchain/Core/Crypto/ECDSASpec.hs
+++ b/test/Data/Blockchain/Core/Crypto/ECDSASpec.hs
@@ -2,7 +2,7 @@
 
 import           TestUtil
 
-import           Data.Blockchain.Core.Crypto.ECDSA
+import           Data.Blockchain.Core.Crypto
 
 spec :: Spec
 spec =
diff --git a/test/Data/Blockchain/Core/Crypto/HashSpec.hs b/test/Data/Blockchain/Core/Crypto/HashSpec.hs
--- a/test/Data/Blockchain/Core/Crypto/HashSpec.hs
+++ b/test/Data/Blockchain/Core/Crypto/HashSpec.hs
@@ -2,11 +2,11 @@
 
 import           TestUtil
 
-import qualified Data.Aeson                       as Aeson
-import qualified Data.ByteString                  as BS
-import qualified Data.ByteString.Char8            as Char8
+import qualified Data.Aeson                  as Aeson
+import qualified Data.ByteString             as BS
+import qualified Data.ByteString.Char8       as Char8
 
-import           Data.Blockchain.Core.Crypto.Hash
+import           Data.Blockchain.Core.Crypto
 
 spec :: Spec
 spec =
diff --git a/test/Data/Blockchain/Core/Types/BlockchainConfigSpec.hs b/test/Data/Blockchain/Core/Types/BlockchainConfigSpec.hs
--- a/test/Data/Blockchain/Core/Types/BlockchainConfigSpec.hs
+++ b/test/Data/Blockchain/Core/Types/BlockchainConfigSpec.hs
@@ -2,11 +2,10 @@
 
 import           TestUtil
 
-import           Data.Monoid                   ((<>))
-import qualified Data.Time.Clock               as Time
+import           Data.Monoid                ((<>))
+import qualified Data.Time.Clock            as Time
 
 import           Data.Blockchain.Core.Types
-import           Data.Blockchain.Core.Util.Hex
 
 testConfig :: BlockchainConfig
 testConfig = BlockchainConfig
diff --git a/test/Data/Blockchain/Core/Types/DifficultySpec.hs b/test/Data/Blockchain/Core/Types/DifficultySpec.hs
--- a/test/Data/Blockchain/Core/Types/DifficultySpec.hs
+++ b/test/Data/Blockchain/Core/Types/DifficultySpec.hs
@@ -2,9 +2,9 @@
 
 import           TestUtil
 
-import qualified Data.Aeson                            as Aeson
+import qualified Data.Aeson                 as Aeson
 
-import           Data.Blockchain.Core.Types.Difficulty
+import           Data.Blockchain.Core.Types
 
 spec :: Spec
 spec =
diff --git a/test/Data/Blockchain/Core/Types/HexSpec.hs b/test/Data/Blockchain/Core/Types/HexSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Data/Blockchain/Core/Types/HexSpec.hs
@@ -0,0 +1,11 @@
+module Data.Blockchain.Core.Types.HexSpec (spec) where
+
+import           TestUtil
+
+import           Data.Blockchain.Core.Types
+
+spec :: Spec
+spec =
+    describe "Data.Blockchain.Core.Util.Hex" $ do
+        safeJSONDeserializeSpec (Proxy :: Proxy Hex256)
+        roundTripJSONSpec (Proxy :: Proxy Hex256)
diff --git a/test/Data/Blockchain/Core/Types/TransactionSpec.hs b/test/Data/Blockchain/Core/Types/TransactionSpec.hs
--- a/test/Data/Blockchain/Core/Types/TransactionSpec.hs
+++ b/test/Data/Blockchain/Core/Types/TransactionSpec.hs
@@ -2,8 +2,8 @@
 
 import           TestUtil
 
-import           Data.Blockchain.Core.Crypto.ECDSA
-import           Data.Blockchain.Core.Types.Transaction
+import           Data.Blockchain.Core.Crypto
+import           Data.Blockchain.Core.Types
 
 spec :: Spec
 spec =
diff --git a/test/Data/Blockchain/Core/Util/HexSpec.hs b/test/Data/Blockchain/Core/Util/HexSpec.hs
deleted file mode 100644
--- a/test/Data/Blockchain/Core/Util/HexSpec.hs
+++ /dev/null
@@ -1,11 +0,0 @@
-module Data.Blockchain.Core.Util.HexSpec (spec) where
-
-import           TestUtil
-
-import           Data.Blockchain.Core.Util.Hex
-
-spec :: Spec
-spec =
-    describe "Data.Blockchain.Core.Util.Hex" $ do
-        safeJSONDeserializeSpec (Proxy :: Proxy Hex256)
-        roundTripJSONSpec (Proxy :: Proxy Hex256)
diff --git a/test/Data/Blockchain/Mining/BlockSpec.hs b/test/Data/Blockchain/Mining/BlockSpec.hs
--- a/test/Data/Blockchain/Mining/BlockSpec.hs
+++ b/test/Data/Blockchain/Mining/BlockSpec.hs
@@ -4,8 +4,7 @@
 
 import           Data.Blockchain.Core.Blockchain
 import           Data.Blockchain.Core.Types
-import           Data.Blockchain.Core.Util.Hex
-import           Data.Blockchain.Mining.Block
+import           Data.Blockchain.Mining
 
 spec :: Spec
 spec = describe "Data.Blockchain.Mining.Block" $ do
diff --git a/test/Integration/Mining.hs b/test/Integration/Mining.hs
--- a/test/Integration/Mining.hs
+++ b/test/Integration/Mining.hs
@@ -2,20 +2,19 @@
     ( mineTestChain
     ) where
 
-import qualified Control.Concurrent.Async          as Async
-import qualified Control.Concurrent.MVar           as MVar
-import           Control.Monad                     (forM, void)
-import qualified Data.Aeson                        as Aeson
-import qualified Data.ByteString.Lazy              as Lazy
-import qualified Data.List.NonEmpty                as NonEmpty
-import           Data.Monoid                       ((<>))
-import qualified Data.Time.Clock                   as Time
+import qualified Control.Concurrent.Async        as Async
+import qualified Control.Concurrent.MVar         as MVar
+import           Control.Monad                   (forM, void)
+import qualified Data.Aeson                      as Aeson
+import qualified Data.ByteString.Lazy            as Lazy
+import qualified Data.List.NonEmpty              as NonEmpty
+import           Data.Monoid                     ((<>))
+import qualified Data.Time.Clock                 as Time
 
-import qualified Data.Blockchain.Core.Blockchain   as B
-import qualified Data.Blockchain.Core.Crypto       as Crypto
-import qualified Data.Blockchain.Core.Types        as B
-import qualified Data.Blockchain.Mining.Block      as Mining
-import qualified Data.Blockchain.Mining.Blockchain as Mining
+import qualified Data.Blockchain.Core.Blockchain as B
+import qualified Data.Blockchain.Core.Crypto     as Crypto
+import qualified Data.Blockchain.Core.Types      as B
+import qualified Data.Blockchain.Mining          as Mining
 
 data MinerSpec = MinerSpec
     { mid               :: Int
@@ -42,7 +41,7 @@
     -> (Int -> B.Blockchain B.Validated -> IO ()) -> IO ()
 runTestMultiMiner numMiners config persist = do
     putStrLn "Creating blockchain and mining genesis block"
-    blockchain <- Mining.createBlockchain config
+    blockchain <- Mining.mineBlockchain config
 
     let idList = [1..numMiners]
 
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -11,8 +11,8 @@
 import qualified Data.Blockchain.Core.Crypto.HashTreeSpec
 import qualified Data.Blockchain.Core.Types.BlockchainConfigSpec
 import qualified Data.Blockchain.Core.Types.DifficultySpec
+import qualified Data.Blockchain.Core.Types.HexSpec
 import qualified Data.Blockchain.Core.Types.TransactionSpec
-import qualified Data.Blockchain.Core.Util.HexSpec
 import qualified Data.Blockchain.Mining.BlockSpec
 import qualified Integration.Mining
 import qualified Integration.Stats
@@ -35,7 +35,7 @@
         , Data.Blockchain.Core.Crypto.HashTreeSpec.spec
         , Data.Blockchain.Core.Types.BlockchainConfigSpec.spec
         , Data.Blockchain.Core.Types.DifficultySpec.spec
+        , Data.Blockchain.Core.Types.HexSpec.spec
         , Data.Blockchain.Core.Types.TransactionSpec.spec
-        , Data.Blockchain.Core.Util.HexSpec.spec
         , Data.Blockchain.Mining.BlockSpec.spec
         ]
