diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,10 +4,14 @@
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
 
+## 0.8.1
+### Added
+- Add instances of `Hashable` and `Generic` where possible.
+
 ## 0.8.0
 ### Removed
-- Removed `deepseq` dependency.
-- Removed network constant reference from address and extended keys.
+- Remove `deepseq` dependency.
+- Remove network constant reference from address and extended keys.
 
 ## 0.7.0
 ### Added
diff --git a/haskoin-core.cabal b/haskoin-core.cabal
--- a/haskoin-core.cabal
+++ b/haskoin-core.cabal
@@ -2,10 +2,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: cbf094166d4f1898eb4612906475bb613308e67160bd645e906ddac986809644
+-- hash: d7e0b231b457cf236bd574573b0f30a57243822185cba58241e94d2b2c790137
 
 name:           haskoin-core
-version:        0.8.0
+version:        0.8.1
 synopsis:       Bitcoin & Bitcoin Cash library for Haskell
 description:    Haskoin Core is a complete Bitcoin and Bitcoin Cash library of functions and data types for Haskell developers.
 category:       Bitcoin, Finance, Network
diff --git a/src/Network/Haskoin/Address.hs b/src/Network/Haskoin/Address.hs
--- a/src/Network/Haskoin/Address.hs
+++ b/src/Network/Haskoin/Address.hs
@@ -48,7 +48,6 @@
 import           Data.Aeson.Types
 import           Data.ByteString                  (ByteString)
 import qualified Data.ByteString                  as B
-import           Data.Function
 import           Data.Hashable
 import           Data.Maybe
 import           Data.Serialize                   as S
@@ -81,25 +80,7 @@
     | WitnessScriptAddress { getAddrHash256 :: !Hash256
                              -- ^ HASH256 hash of script
                             }
-    deriving (Eq, Generic, Show, Read, Serialize)
-
-instance Hashable Address where
-    hashWithSalt i (PubKeyAddress h)        = i `hashWithSalt` h
-    hashWithSalt i (ScriptAddress h)        = i `hashWithSalt` h
-    hashWithSalt i (WitnessPubKeyAddress h) = i `hashWithSalt` h
-    hashWithSalt i (WitnessScriptAddress h) = i `hashWithSalt` h
-    hash (PubKeyAddress h)        = hash h
-    hash (ScriptAddress h)        = hash h
-    hash (WitnessPubKeyAddress h) = hash h
-    hash (WitnessScriptAddress h) = hash h
-
-instance Ord Address where
-    compare = compare `on` f
-      where
-        f (PubKeyAddress h)        = S.encode h
-        f (ScriptAddress h)        = S.encode h
-        f (WitnessPubKeyAddress h) = S.encode h
-        f (WitnessScriptAddress h) = S.encode h
+    deriving (Eq, Ord, Generic, Show, Read, Serialize, Hashable)
 
 -- | 'Address' pays to a public key hash.
 isPubKeyAddress :: Address -> Bool
diff --git a/src/Network/Haskoin/Block/Common.hs b/src/Network/Haskoin/Block/Common.hs
--- a/src/Network/Haskoin/Block/Common.hs
+++ b/src/Network/Haskoin/Block/Common.hs
@@ -1,4 +1,5 @@
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DeriveGeneric  #-}
 {-|
 Module      : Network.Haskoin.Block.Common
 Copyright   : No rights reserved
@@ -45,6 +46,7 @@
 import           Data.String.Conversions            (cs)
 import           Data.Text                          (Text)
 import           Data.Word                          (Word32)
+import           GHC.Generics
 import           Network.Haskoin.Crypto.Hash
 import           Network.Haskoin.Network.Common
 import           Network.Haskoin.Transaction.Common
@@ -61,7 +63,7 @@
 data Block =
     Block { blockHeader :: !BlockHeader
           , blockTxns   :: ![Tx]
-          } deriving (Eq, Show, Read)
+          } deriving (Eq, Show, Read, Generic, Hashable)
 
 instance Serialize Block where
     get = do
@@ -77,7 +79,7 @@
 -- | Block header hash. To be serialized reversed for display purposes.
 newtype BlockHash = BlockHash
     { getBlockHash :: Hash256 }
-    deriving (Eq, Ord, Hashable, Serialize)
+    deriving (Eq, Ord, Generic, Hashable, Serialize)
 
 instance Show BlockHash where
     showsPrec _ = shows . blockHashToHex
@@ -130,7 +132,8 @@
                 , blockBits      :: !Word32      -- 16 bytes
                   -- | random nonce
                 , bhNonce        :: !Word32      -- 16 bytes
-                } deriving (Eq, Ord, Show, Read) -- 208 bytes (above + 16 bytes)
+                } deriving (Eq, Ord, Show, Read, Generic, Hashable)
+                                                 -- 208 bytes (above + 16 bytes)
 
 -- | Compute hash of 'BlockHeader'.
 headerHash :: BlockHeader -> BlockHash
diff --git a/src/Network/Haskoin/Block/Headers.hs b/src/Network/Haskoin/Block/Headers.hs
--- a/src/Network/Haskoin/Block/Headers.hs
+++ b/src/Network/Haskoin/Block/Headers.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE DeriveAnyClass    #-}
+{-# LANGUAGE DeriveGeneric     #-}
 {-# LANGUAGE FlexibleContexts  #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE LambdaCase        #-}
@@ -70,6 +72,7 @@
 import           Data.ByteString.Short              (ShortByteString, fromShort,
                                                      toShort)
 import           Data.Function                      (on)
+import           Data.Hashable
 import           Data.HashMap.Strict                (HashMap)
 import qualified Data.HashMap.Strict                as HashMap
 import           Data.List                          (sort, sortBy)
@@ -81,6 +84,7 @@
 import           Data.Serialize.Put                 as S
 import           Data.Typeable                      (Typeable)
 import           Data.Word                          (Word32, Word64)
+import           GHC.Generics
 import           Network.Haskoin.Block.Common
 import           Network.Haskoin.Constants
 import           Network.Haskoin.Crypto
@@ -113,7 +117,7 @@
     | GenesisNode { nodeHeader :: !BlockHeader
                   , nodeHeight :: !BlockHeight
                   , nodeWork   :: !BlockWork }
-    deriving (Show)
+    deriving (Show, Read, Generic, Hashable)
 
 instance Serialize BlockNode where
     get = do
@@ -143,7 +147,7 @@
 data HeaderMemory = HeaderMemory
     { memoryHeaderMap  :: !BlockMap
     , memoryBestHeader :: !BlockNode
-    } deriving (Eq, Typeable)
+    } deriving (Eq, Typeable, Show, Read, Generic, Hashable)
 
 -- | Typeclass for block header chain storage monad.
 class Monad m => BlockHeaders m where
@@ -441,9 +445,9 @@
       -> BlockHeight  -- ^ new child height
       -> BlockHash    -- ^ new child hash
       -> Bool
-bip34 net height hash
+bip34 net height hsh
     | fst (getBip34Block net) == 0 = True
-    | fst (getBip34Block net) == height = snd (getBip34Block net) == hash
+    | fst (getBip34Block net) == height = snd (getBip34Block net) == hsh
     | otherwise = True
 
 -- | Check if the provided block height and version are valid.
diff --git a/src/Network/Haskoin/Block/Merkle.hs b/src/Network/Haskoin/Block/Merkle.hs
--- a/src/Network/Haskoin/Block/Merkle.hs
+++ b/src/Network/Haskoin/Block/Merkle.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DeriveGeneric  #-}
 {-|
 Module      : Network.Haskoin.Block.Merkle
 Copyright   : No rights reserved
@@ -31,15 +33,18 @@
     , boolsToWord8
     ) where
 
-import           Control.Monad                     (forM_, replicateM, when)
+import           Control.Monad                      (forM_, replicateM, when)
 import           Data.Bits
-import qualified Data.ByteString                   as BS
-import           Data.Either                       (isRight)
+import qualified Data.ByteString                    as BS
+import           Data.Either                        (isRight)
+import           Data.Hashable
 import           Data.Maybe
-import           Data.Serialize                    (Serialize, encode, get, put)
-import           Data.Serialize.Get                (getWord32le, getWord8)
-import           Data.Serialize.Put                (putWord32le, putWord8)
-import           Data.Word                         (Word32, Word8)
+import           Data.Serialize                     (Serialize, encode, get,
+                                                     put)
+import           Data.Serialize.Get                 (getWord32le, getWord8)
+import           Data.Serialize.Put                 (putWord32le, putWord8)
+import           Data.Word                          (Word32, Word8)
+import           GHC.Generics
 import           Network.Haskoin.Block.Common
 import           Network.Haskoin.Constants
 import           Network.Haskoin.Crypto.Hash
@@ -67,7 +72,7 @@
                 , mHashes         :: !PartialMerkleTree
                 -- | bits to rebuild partial merkle tree
                 , mFlags          :: !FlagBits
-                } deriving (Eq, Show)
+                } deriving (Eq, Show, Read, Generic, Hashable)
 
 instance Serialize MerkleBlock where
 
diff --git a/src/Network/Haskoin/Keys/Common.hs b/src/Network/Haskoin/Keys/Common.hs
--- a/src/Network/Haskoin/Keys/Common.hs
+++ b/src/Network/Haskoin/Keys/Common.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE DeriveAnyClass    #-}
 {-# LANGUAGE DeriveGeneric     #-}
 {-# LANGUAGE FlexibleContexts  #-}
 {-# LANGUAGE FlexibleInstances #-}
@@ -37,6 +38,7 @@
                                               parseJSON, toJSON, withText)
 import           Data.ByteString             (ByteString)
 import qualified Data.ByteString             as BS
+import           Data.Hashable
 import           Data.Maybe                  (fromMaybe)
 import           Data.Serialize              (Serialize, decode, encode, get,
                                               put)
@@ -52,7 +54,7 @@
 data PubKeyI = PubKeyI
     { pubKeyPoint      :: !PubKey
     , pubKeyCompressed :: !Bool
-    } deriving (Generic, Eq, Show, Read)
+    } deriving (Generic, Eq, Show, Read, Hashable)
 
 instance IsString PubKeyI where
     fromString str =
diff --git a/src/Network/Haskoin/Script/Common.hs b/src/Network/Haskoin/Script/Common.hs
--- a/src/Network/Haskoin/Script/Common.hs
+++ b/src/Network/Haskoin/Script/Common.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE DeriveAnyClass    #-}
+{-# LANGUAGE DeriveGeneric     #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-|
 Module      : Network.Haskoin.Script.Common
@@ -10,37 +12,39 @@
 Common script-related functions and data types.
 -}
 module Network.Haskoin.Script.Common
-( ScriptOp(..)
-, Script(..)
-, PushDataType(..)
-, ScriptOutput(..)
-, isPayPK
-, isPayPKHash
-, isPayMulSig
-, isPayScriptHash
-, isPayWitnessPKHash
-, isPayWitnessScriptHash
-, isDataCarrier
-, encodeOutput
-, encodeOutputBS
-, decodeOutput
-, decodeOutputBS
-, isPushOp
-, opPushData
-, intToScriptOp
-, scriptOpToInt
-) where
+    ( ScriptOp(..)
+    , Script(..)
+    , PushDataType(..)
+    , ScriptOutput(..)
+    , isPayPK
+    , isPayPKHash
+    , isPayMulSig
+    , isPayScriptHash
+    , isPayWitnessPKHash
+    , isPayWitnessScriptHash
+    , isDataCarrier
+    , encodeOutput
+    , encodeOutputBS
+    , decodeOutput
+    , decodeOutputBS
+    , isPushOp
+    , opPushData
+    , intToScriptOp
+    , scriptOpToInt
+    ) where
 
 import           Control.Monad
 import           Data.Aeson                  as A
 import           Data.ByteString             (ByteString)
 import qualified Data.ByteString             as B
+import           Data.Hashable
 import           Data.Serialize              as S
 import           Data.Serialize.Get          (getByteString, getWord16le,
                                               getWord32le, getWord8, isEmpty)
 import           Data.Serialize.Put          (putByteString, putWord16le,
                                               putWord32le, putWord8)
 import           Data.Word                   (Word8)
+import           GHC.Generics                (Generic)
 import           Network.Haskoin.Crypto.Hash
 import           Network.Haskoin.Keys.Common
 import           Network.Haskoin.Util
@@ -59,7 +63,7 @@
              -- | script operators defining this script
              scriptOps :: [ScriptOp]
            }
-    deriving (Eq, Show, Read)
+    deriving (Eq, Show, Read, Generic, Hashable)
 
 instance Serialize Script where
     get =
@@ -84,7 +88,7 @@
     | OPDATA2
       -- | next four bytes contains the number of bytes to be pushed
     | OPDATA4
-    deriving (Show, Read, Eq)
+    deriving (Show, Read, Eq, Generic, Hashable)
 
 -- | Data type representing an operator allowed inside a 'Script'.
 data ScriptOp
@@ -210,7 +214,7 @@
     | OP_PUBKEYHASH
     | OP_PUBKEY
     | OP_INVALIDOPCODE !Word8
-    deriving (Show, Read, Eq)
+    deriving (Show, Read, Eq, Generic, Hashable)
 
 instance Serialize ScriptOp where
     get = go =<< (fromIntegral <$> getWord8)
@@ -591,7 +595,7 @@
     | PayWitnessScriptHash { getScriptHash :: !Hash256 }
       -- | provably unspendable data carrier
     | DataCarrier { getOutputData :: !ByteString }
-    deriving (Eq, Show)
+    deriving (Eq, Show, Read, Generic, Hashable)
 
 instance FromJSON ScriptOutput where
     parseJSON = withText "scriptoutput" $ \t -> either fail return $
diff --git a/src/Network/Haskoin/Script/SigHash.hs b/src/Network/Haskoin/Script/SigHash.hs
--- a/src/Network/Haskoin/Script/SigHash.hs
+++ b/src/Network/Haskoin/Script/SigHash.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE DeriveGeneric              #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE OverloadedStrings          #-}
 {-|
@@ -40,11 +41,13 @@
 import           Data.Bits
 import           Data.ByteString                    (ByteString)
 import qualified Data.ByteString                    as BS
+import           Data.Hashable
 import           Data.Maybe
 import           Data.Scientific
 import           Data.Serialize
 import           Data.Serialize.Put                 (runPut)
 import           Data.Word
+import           GHC.Generics
 import           Network.Haskoin.Constants
 import           Network.Haskoin.Crypto.Hash
 import           Network.Haskoin.Crypto.Signature
@@ -65,8 +68,10 @@
       -- ^ replay protection for Bitcoin Cash transactions
     | SIGHASH_ANYONECANPAY
       -- ^ new inputs can be added
-    deriving (Eq, Ord, Show)
+    deriving (Eq, Ord, Show, Read, Generic)
 
+instance Hashable SigHashFlag
+
 instance Enum SigHashFlag where
     fromEnum SIGHASH_ALL          = 0x01
     fromEnum SIGHASH_NONE         = 0x02
@@ -91,8 +96,20 @@
 -- If the 'SIGHASH_ANYONECANPAY' flag is set (true), then only the current input
 -- is signed. Otherwise, all of the inputs of a transaction are signed. The
 -- default value for 'SIGHASH_ANYONECANPAY' is unset (false).
-newtype SigHash = SigHash Word32
-    deriving (Eq, Ord, Enum, Bits, Num, Real, Integral, Show, Read)
+newtype SigHash =
+    SigHash Word32
+    deriving ( Eq
+             , Ord
+             , Enum
+             , Bits
+             , Num
+             , Real
+             , Integral
+             , Show
+             , Read
+             , Generic
+             , Hashable
+             )
 
 instance J.FromJSON SigHash where
     parseJSON =
diff --git a/src/Network/Haskoin/Transaction/Builder.hs b/src/Network/Haskoin/Transaction/Builder.hs
--- a/src/Network/Haskoin/Transaction/Builder.hs
+++ b/src/Network/Haskoin/Transaction/Builder.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE DeriveAnyClass    #-}
+{-# LANGUAGE DeriveGeneric     #-}
 {-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-|
@@ -51,6 +53,7 @@
 import           Data.Conduit                       (ConduitT, Void, await,
                                                      runConduit, (.|))
 import           Data.Conduit.List                  (sourceList)
+import           Data.Hashable
 import           Data.List                          (find, nub)
 import           Data.Maybe                         (catMaybes, fromJust,
                                                      fromMaybe, isJust,
@@ -59,6 +62,7 @@
 import           Data.String.Conversions            (cs)
 import           Data.Text                          (Text)
 import           Data.Word                          (Word64)
+import           GHC.Generics
 import           Network.Haskoin.Address
 import           Network.Haskoin.Constants
 import           Network.Haskoin.Crypto.Signature
@@ -272,7 +276,7 @@
     , sigInputOP     :: !OutPoint     -- ^ outpoint to spend
     , sigInputSH     :: !SigHash      -- ^ signature type
     , sigInputRedeem :: !(Maybe RedeemScript) -- ^ sedeem script
-    } deriving (Eq, Show)
+    } deriving (Eq, Show, Read, Generic, Hashable)
 
 instance ToJSON SigInput where
     toJSON (SigInput so val op sh rdm) = object $
diff --git a/src/Network/Haskoin/Transaction/Common.hs b/src/Network/Haskoin/Transaction/Common.hs
--- a/src/Network/Haskoin/Transaction/Common.hs
+++ b/src/Network/Haskoin/Transaction/Common.hs
@@ -1,4 +1,5 @@
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE DeriveAnyClass             #-}
+{-# LANGUAGE DeriveGeneric              #-}
 {-# LANGUAGE OverloadedStrings          #-}
 {-|
 Module      : Network.Haskoin.Transaction.Common
@@ -40,6 +41,7 @@
 import           Data.String.Conversions        (cs)
 import           Data.Text                      (Text)
 import           Data.Word                      (Word32, Word64)
+import           GHC.Generics
 import           Network.Haskoin.Crypto.Hash
 import           Network.Haskoin.Network.Common
 import           Network.Haskoin.Script.Common
@@ -48,7 +50,7 @@
 
 -- | Transaction id: hash of transaction excluding witness data.
 newtype TxHash = TxHash { getTxHash :: Hash256 }
-    deriving (Eq, Ord, Hashable, Serialize)
+    deriving (Eq, Ord, Generic, Hashable, Serialize)
 
 instance Show TxHash where
     showsPrec _ = shows . txHashToHex
@@ -107,20 +109,12 @@
     , txWitness  :: !WitnessData
       -- | earliest mining height or time
     , txLockTime :: !Word32
-    } deriving (Eq, Ord)
+    } deriving (Show, Read, Eq, Ord, Generic, Hashable)
 
 -- | Compute transaction hash.
 txHash :: Tx -> TxHash
 txHash tx = TxHash (doubleSHA256 (S.encode tx {txWitness = []}))
 
-instance Show Tx where
-    showsPrec _ = shows . encodeHex . S.encode
-
-instance Read Tx where
-    readPrec = do
-        R.String str <- R.lexP
-        maybe R.pfail return $ (eitherToMaybe . S.decode) =<< decodeHex (cs str)
-
 instance IsString Tx where
     fromString =
         fromMaybe e . (eitherToMaybe . S.decode <=< decodeHex) . cs
@@ -225,7 +219,7 @@
          , scriptInput  :: !ByteString
            -- | lock-time using sequence numbers (BIP-68)
          , txInSequence :: !Word32
-         } deriving (Eq, Show, Ord)
+         } deriving (Eq, Show, Read, Ord, Generic, Hashable)
 
 instance Serialize TxIn where
     get =
@@ -246,7 +240,7 @@
             outValue     :: !Word64
             -- | pubkey script
           , scriptOutput :: !ByteString
-          } deriving (Eq, Show, Ord)
+          } deriving (Eq, Show, Read, Ord, Generic, Hashable)
 
 instance Serialize TxOut where
     get = do
@@ -265,7 +259,7 @@
       outPointHash  :: !TxHash
       -- | position of output in previous transaction
     , outPointIndex :: !Word32
-    } deriving (Show, Read, Eq, Ord)
+    } deriving (Show, Read, Eq, Ord, Generic, Hashable)
 
 instance FromJSON OutPoint where
     parseJSON = withText "OutPoint" $
