diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,11 @@
 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.0
+### Removed
+- Removed `deepseq` dependency.
+- Removed network constant reference from address and extended keys.
+
 ## 0.7.0
 ### Added
 - Add `Serialize` instance for network constants.
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: bee4365adfac078ce0642cae3009ffca1f4cb61498f0b9fe7aec964ff232a650
+-- hash: cbf094166d4f1898eb4612906475bb613308e67160bd645e906ddac986809644
 
 name:           haskoin-core
-version:        0.7.0
+version:        0.8.0
 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
@@ -88,7 +88,6 @@
     , conduit
     , containers
     , cryptonite
-    , deepseq
     , entropy
     , hashable
     , memory
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
@@ -1,3 +1,4 @@
+{-# LANGUAGE DeriveAnyClass    #-}
 {-# LANGUAGE DeriveGeneric     #-}
 {-# LANGUAGE FlexibleContexts  #-}
 {-# LANGUAGE OverloadedStrings #-}
@@ -12,16 +13,14 @@
 Base58, CashAddr, Bech32 address and WIF private key serialization support.
 -}
 module Network.Haskoin.Address
-    ( Address
-    , getAddrHash160
-    , getAddrHash256
-    , getAddrNet
+    ( Address(..)
     , isPubKeyAddress
     , isScriptAddress
     , isWitnessPubKeyAddress
     , isWitnessScriptAddress
     , addrToString
     , stringToAddr
+    , addrToJSON
     , addrFromJSON
     , pubKeyAddr
     , pubKeyWitnessAddr
@@ -44,7 +43,6 @@
     ) where
 
 import           Control.Applicative
-import           Control.DeepSeq
 import           Control.Monad
 import           Data.Aeson                       as A
 import           Data.Aeson.Types
@@ -52,12 +50,10 @@
 import qualified Data.ByteString                  as B
 import           Data.Function
 import           Data.Hashable
-import           Data.List
 import           Data.Maybe
 import           Data.Serialize                   as S
-import           Data.String.Conversions
 import           Data.Text                        (Text)
-import           GHC.Generics                     as G (Generic)
+import           GHC.Generics                     (Generic)
 import           Network.Haskoin.Address.Base58
 import           Network.Haskoin.Address.Bech32
 import           Network.Haskoin.Address.CashAddr
@@ -66,68 +62,44 @@
 import           Network.Haskoin.Keys.Common
 import           Network.Haskoin.Script
 import           Network.Haskoin.Util
-import           Text.Read                        as R
 
 -- | Address format for Bitcoin and Bitcoin Cash.
 data Address
     -- | pay to public key hash (regular)
     = PubKeyAddress { getAddrHash160 :: !Hash160
-                        -- ^ RIPEMD160 hash of public key's SHA256 hash
-                    , getAddrNet     :: !Network
-                        -- ^ address network
+                      -- ^ RIPEMD160 hash of public key's SHA256 hash
                      }
     -- | pay to script hash
     | ScriptAddress { getAddrHash160 :: !Hash160
-                        -- ^ RIPEMD160 hash of script's SHA256 hash
-                    , getAddrNet     :: !Network
-                        -- ^ address network
+                      -- ^ RIPEMD160 hash of script's SHA256 hash
                      }
     -- | pay to witness public key hash
     | WitnessPubKeyAddress { getAddrHash160 :: !Hash160
-                               -- ^ RIPEMD160 hash of public key's SHA256 hash
-                           , getAddrNet     :: !Network
-                               -- ^ address network
-                           }
+                             -- ^ RIPEMD160 hash of public key's SHA256 hash
+                            }
     -- | pay to witness script hash
     | WitnessScriptAddress { getAddrHash256 :: !Hash256
-                               -- ^ HASH256 hash of script
-                           , getAddrNet     :: !Network
-                               -- ^ address network
-                           }
-    deriving (Eq, G.Generic)
-
-instance Serialize Address where
-    put a = do
-        put $ getAddrNet a
-        let bs = addressToScriptBS a
-        put $ B.length bs
-        putByteString bs
-    get = do
-        net <- S.get
-        bs <- getByteString =<< S.get
-        case scriptToAddressBS net bs of
-            Nothing -> fail "Could not decode address"
-            Just a -> return a
+                             -- ^ 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
+    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
-
-instance NFData Address
+        f (PubKeyAddress h)        = S.encode h
+        f (ScriptAddress h)        = S.encode h
+        f (WitnessPubKeyAddress h) = S.encode h
+        f (WitnessScriptAddress h) = S.encode h
 
 -- | 'Address' pays to a public key hash.
 isPubKeyAddress :: Address -> Bool
@@ -158,32 +130,22 @@
     f pfx addr
   where
     f x a
-        | x == getAddrPrefix net = return (PubKeyAddress a net)
-        | x == getScriptPrefix net = return (ScriptAddress a net)
+        | x == getAddrPrefix net = return $ PubKeyAddress a
+        | x == getScriptPrefix net = return $ ScriptAddress a
         | otherwise = fail "Does not recognize address prefix"
 
 -- | Binary serializer for 'Base58' addresses.
-base58put :: Putter Address
-base58put (PubKeyAddress h net) = do
+base58put :: Network -> Putter Address
+base58put net (PubKeyAddress h) = do
         putWord8 (getAddrPrefix net)
         put h
-base58put (ScriptAddress h net) = do
+base58put net (ScriptAddress h) = do
         putWord8 (getScriptPrefix net)
         put h
-base58put _ = error "Cannot serialize this address as Base58"
-
-instance Show Address where
-    showsPrec _ a = shows (addrToString a)
-
-instance Read Address where
-    readPrec = do
-        R.String str <- lexP
-        let bs = cs str
-        maybe pfail return $
-            foldl' (\a n -> a <|> stringToAddr n bs) Nothing allNets
+base58put _ _ = error "Cannot serialize this address as Base58"
 
-instance ToJSON Address where
-    toJSON = A.String . addrToString
+addrToJSON :: Network -> Address -> Value
+addrToJSON net = String . addrToString net
 
 -- | JSON parsing for Bitcoin addresses. Works with 'Base58', 'CashAddr' and
 -- 'Bech32'.
@@ -196,28 +158,25 @@
 
 -- | Convert address to human-readable string. Uses 'Base58', 'Bech32', or
 -- 'CashAddr' depending on network.
-addrToString :: Address -> Text
-addrToString a@PubKeyAddress {getAddrHash160 = h, getAddrNet = net}
+addrToString :: Network -> Address -> Text
+addrToString net a@PubKeyAddress {getAddrHash160 = h}
     | isNothing (getCashAddrPrefix net) =
-        encodeBase58Check $ runPut $ base58put a
+        encodeBase58Check $ runPut $ base58put net a
     | otherwise =
         fromMaybe (error "Colud not encode a CashAddr") $
         cashAddrEncode net 0 (S.encode h)
-
-addrToString a@ScriptAddress {getAddrHash160 = h, getAddrNet = net}
+addrToString net a@ScriptAddress {getAddrHash160 = h}
     | isNothing (getCashAddrPrefix net) =
-        encodeBase58Check $ runPut $ base58put a
+        encodeBase58Check $ runPut $ base58put net a
     | otherwise =
         fromMaybe (error "Could not encode a CashAddr") $
         cashAddrEncode net 1 (S.encode h)
-
-addrToString WitnessPubKeyAddress {getAddrHash160 = h, getAddrNet = net} =
+addrToString net WitnessPubKeyAddress {getAddrHash160 = h} =
     let mt = do
             hrp <- getBech32Prefix net
             segwitEncode hrp 0 (B.unpack (S.encode h))
      in fromMaybe (error "Could not encode a Bech32 address") mt
-
-addrToString WitnessScriptAddress {getAddrHash256 = h, getAddrNet = net} =
+addrToString net WitnessScriptAddress {getAddrHash256 = h} =
     let mt = do
             hrp <- getBech32Prefix net
             segwitEncode hrp 0 (B.unpack (S.encode h))
@@ -231,10 +190,10 @@
     cash = cashAddrDecode net bs >>= \(ver, bs') -> case ver of
         0 -> do
             h <- eitherToMaybe (S.decode bs')
-            return $ PubKeyAddress h net
+            return $ PubKeyAddress h
         1 -> do
             h <- eitherToMaybe (S.decode bs')
-            return $ ScriptAddress h net
+            return $ ScriptAddress h
         _ -> Nothing
     segwit = do
         hrp <- getBech32Prefix net
@@ -244,60 +203,52 @@
         case B.length bs'' of
             20 -> do
                 h <- eitherToMaybe (S.decode bs'')
-                return $ WitnessPubKeyAddress h net
+                return $ WitnessPubKeyAddress h
             32 -> do
                 h <- eitherToMaybe (S.decode bs'')
-                return $ WitnessScriptAddress h net
+                return $ WitnessScriptAddress h
             _ -> Nothing
 
 -- | Obtain a P2PKH address from a public key.
-pubKeyAddr :: Network -> PubKeyI -> Address
-pubKeyAddr net k = PubKeyAddress (addressHash (S.encode k)) net
+pubKeyAddr :: PubKeyI -> Address
+pubKeyAddr = PubKeyAddress . addressHash . S.encode
 
 -- | Obtain a P2PKH address from a 'Hash160'.
-p2pkhAddr :: Network -> Hash160 -> Address
-p2pkhAddr net h = PubKeyAddress h net
+p2pkhAddr :: Hash160 -> Address
+p2pkhAddr = PubKeyAddress
 
 -- | Obtain a P2WPKH address from a public key. Only on SegWit networks.
-pubKeyWitnessAddr :: Network -> PubKeyI -> Maybe Address
-pubKeyWitnessAddr net k
-    | getSegWit net = Just $ WitnessPubKeyAddress (addressHash (S.encode k)) net
-    | otherwise = Nothing
+pubKeyWitnessAddr :: PubKeyI -> Address
+pubKeyWitnessAddr = WitnessPubKeyAddress . addressHash . S.encode
 
 -- | Obtain a P2WPKH address from a 'Hash160'.
-p2wpkhAddr :: Network -> Hash160 -> Maybe Address
-p2wpkhAddr net h
-    | getSegWit net = Just $ WitnessPubKeyAddress h net
-    | otherwise = Nothing
+p2wpkhAddr :: Hash160 -> Address
+p2wpkhAddr = WitnessPubKeyAddress
 
 -- | Obtain a P2SH address from a 'Hash160'.
-p2shAddr :: Network -> Hash160 -> Address
-p2shAddr net h = ScriptAddress h net
+p2shAddr :: Hash160 -> Address
+p2shAddr = ScriptAddress
 
 -- | Obtain a P2WSH address from a 'Hash256'
-p2wshAddr :: Network -> Hash256 -> Maybe Address
-p2wshAddr net h
-    | getSegWit net = Just $ WitnessScriptAddress h net
-    | otherwise = Nothing
+p2wshAddr :: Hash256 -> Address
+p2wshAddr = WitnessScriptAddress
 
 -- | Compute a pay-to-script-hash address for an output script.
-payToScriptAddress :: Network -> ScriptOutput -> Address
-payToScriptAddress net out = p2shAddr net (addressHash (encodeOutputBS out))
+payToScriptAddress :: ScriptOutput -> Address
+payToScriptAddress = p2shAddr . addressHash . encodeOutputBS
 
 -- | Compute a pay-to-witness-script-hash address for an output script. Only on
 -- SegWit networks.
-payToWitnessScriptAddress :: Network -> ScriptOutput -> Maybe Address
-payToWitnessScriptAddress net out = p2wshAddr net (sha256 (encodeOutputBS out))
+payToWitnessScriptAddress :: ScriptOutput -> Address
+payToWitnessScriptAddress = p2wshAddr . sha256 . encodeOutputBS
 
 -- | Encode an output script from an address. Will fail if using a
 -- pay-to-witness address on a non-SegWit network.
 addressToOutput :: Address -> ScriptOutput
-addressToOutput a
-    | isPubKeyAddress a = PayPKHash (getAddrHash160 a)
-    | isScriptAddress a = PayScriptHash (getAddrHash160 a)
-    | isWitnessPubKeyAddress a = PayWitnessPKHash (getAddrHash160 a)
-    | isWitnessScriptAddress a = PayWitnessScriptHash (getAddrHash256 a)
-    | otherwise = undefined
+addressToOutput (PubKeyAddress h)        = PayPKHash h
+addressToOutput (ScriptAddress h)        = PayScriptHash h
+addressToOutput (WitnessPubKeyAddress h) = PayWitnessPKHash h
+addressToOutput (WitnessScriptAddress h) = PayWitnessScriptHash h
 
 -- | Get output script AST for an 'Address'.
 addressToScript :: Address -> Script
@@ -308,34 +259,29 @@
 addressToScriptBS = S.encode . addressToScript
 
 -- | Decode an output script into an 'Address' if it has such representation.
-scriptToAddress :: Network -> Script -> Maybe Address
-scriptToAddress net = eitherToMaybe . (outputAddress net <=< decodeOutput)
+scriptToAddress :: Script -> Either String Address
+scriptToAddress =
+    maybeToEither "Could not decode address" . outputAddress <=< decodeOutput
 
 -- | Decode a serialized script into an 'Address'.
-scriptToAddressBS :: Network -> ByteString -> Maybe Address
-scriptToAddressBS net = eitherToMaybe . (outputAddress net <=< decodeOutputBS)
+scriptToAddressBS :: ByteString -> Either String Address
+scriptToAddressBS =
+    maybeToEither "Could not decode address" . outputAddress <=< decodeOutputBS
 
 -- | Get the 'Address' of a 'ScriptOutput'.
-outputAddress :: Network -> ScriptOutput -> Either String Address
-outputAddress net s =
-    case s of
-        PayPKHash h -> Right $ p2pkhAddr net h
-        PayScriptHash h -> Right $ p2shAddr net h
-        PayPK k -> Right $ pubKeyAddr net k
-        PayWitnessPKHash h ->
-            maybeToEither "outputAddress: segwit not supported in this network" $
-            p2wpkhAddr net h
-        PayWitnessScriptHash h ->
-            maybeToEither "outputAddress: segwit not supported in this network" $
-            p2wshAddr net h
-        _ -> Left "outputAddress: bad output script type"
+outputAddress :: ScriptOutput -> Maybe Address
+outputAddress (PayPKHash h)            = Just $ PubKeyAddress h
+outputAddress (PayScriptHash h)        = Just $ ScriptAddress h
+outputAddress (PayPK k)                = Just $ pubKeyAddr k
+outputAddress (PayWitnessPKHash h)     = Just $ WitnessPubKeyAddress h
+outputAddress (PayWitnessScriptHash h) = Just $ WitnessScriptAddress h
+outputAddress _                        = Nothing
 
--- | Infer the address of a 'ScriptInput'
-inputAddress :: Network -> ScriptInput -> Either String Address
-inputAddress net s = case s of
-    RegularInput (SpendPKHash _ key) -> return $ pubKeyAddr net key
-    ScriptHashInput _ rdm -> return $ payToScriptAddress net rdm
-    _ -> Left "inputAddress: bad input script type"
+-- | Infer the 'Address' of a 'ScriptInput'.
+inputAddress :: ScriptInput -> Maybe Address
+inputAddress (RegularInput (SpendPKHash _ key)) = Just $ pubKeyAddr key
+inputAddress (ScriptHashInput _ rdm) = Just $ payToScriptAddress rdm
+inputAddress _ = Nothing
 
 -- | Decode private key from WIF (wallet import format) string.
 fromWif :: Network -> Base58 -> Maybe SecKeyI
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
@@ -27,7 +27,6 @@
     , encodeCompact
     ) where
 
-import           Control.DeepSeq                    (NFData, rnf)
 import           Control.Monad                      (forM_, liftM2, mzero,
                                                      replicateM)
 import           Data.Aeson                         (FromJSON, ToJSON,
@@ -64,9 +63,6 @@
           , blockTxns   :: ![Tx]
           } deriving (Eq, Show, Read)
 
-instance NFData Block where
-    rnf (Block h ts) = rnf h `seq` rnf ts
-
 instance Serialize Block where
     get = do
         header     <- get
@@ -81,7 +77,7 @@
 -- | Block header hash. To be serialized reversed for display purposes.
 newtype BlockHash = BlockHash
     { getBlockHash :: Hash256 }
-    deriving (Eq, Ord, NFData, Hashable, Serialize)
+    deriving (Eq, Ord, Hashable, Serialize)
 
 instance Show BlockHash where
     showsPrec _ = shows . blockHashToHex
@@ -140,11 +136,6 @@
 headerHash :: BlockHeader -> BlockHash
 headerHash = BlockHash . doubleSHA256 . encode
 
-instance NFData BlockHeader where
-    rnf (BlockHeader v p m t b n) =
-        rnf v `seq` rnf p `seq` rnf m `seq`
-        rnf t `seq` rnf b `seq` rnf n
-
 instance Serialize BlockHeader where
     get = do
         v <- getWord32le
@@ -193,9 +184,6 @@
               , getBlocksHashStop :: !BlockHash
               } deriving (Eq, Show)
 
-instance NFData GetBlocks where
-    rnf (GetBlocks v l h) = rnf v `seq` rnf l `seq` rnf h
-
 instance Serialize GetBlocks where
 
     get = GetBlocks <$> getWord32le
@@ -228,9 +216,6 @@
                , getHeadersHashStop :: !BlockHash
                } deriving (Eq, Show)
 
-instance NFData GetHeaders where
-    rnf (GetHeaders v l h) = rnf v `seq` rnf l `seq` rnf h
-
 instance Serialize GetHeaders where
 
     get = GetHeaders <$> getWord32le
@@ -251,9 +236,6 @@
               headersList :: [BlockHeaderCount]
             }
     deriving (Eq, Show)
-
-instance NFData Headers where
-    rnf (Headers l) = rnf l
 
 instance Serialize Headers where
 
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
@@ -59,7 +59,6 @@
     , ) where
 
 import           Control.Applicative                ((<|>))
-import           Control.DeepSeq                    (NFData, rnf)
 import           Control.Monad                      (guard, unless, when)
 import           Control.Monad.Except               (ExceptT (..), runExceptT,
                                                      throwError)
@@ -134,12 +133,6 @@
             GenesisNode {} -> return ()
             BlockNode {}   -> put $ nodeSkip bn
 
-instance NFData BlockNode where
-    rnf BlockNode {..} =
-        rnf nodeHeader `seq` rnf nodeHeight `seq` rnf nodeSkip
-    rnf GenesisNode {..} =
-        rnf nodeHeader `seq` rnf nodeHeight `seq` rnf nodeWork
-
 instance Eq BlockNode where
     (==) = (==) `on` nodeHeader
 
@@ -151,10 +144,6 @@
     { memoryHeaderMap  :: !BlockMap
     , memoryBestHeader :: !BlockNode
     } deriving (Eq, Typeable)
-
-instance NFData HeaderMemory where
-    rnf HeaderMemory{..} =
-        rnf memoryHeaderMap `seq` rnf memoryBestHeader
 
 -- | Typeclass for block header chain storage monad.
 class Monad m => BlockHeaders m where
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
@@ -31,7 +31,6 @@
     , boolsToWord8
     ) where
 
-import           Control.DeepSeq                   (NFData, rnf)
 import           Control.Monad                     (forM_, replicateM, when)
 import           Data.Bits
 import qualified Data.ByteString                   as BS
@@ -69,9 +68,6 @@
                 -- | bits to rebuild partial merkle tree
                 , mFlags          :: !FlagBits
                 } deriving (Eq, Show)
-
-instance NFData MerkleBlock where
-    rnf (MerkleBlock m t h f) = rnf m `seq` rnf t `seq` rnf h `seq` rnf f
 
 instance Serialize MerkleBlock where
 
diff --git a/src/Network/Haskoin/Constants.hs b/src/Network/Haskoin/Constants.hs
--- a/src/Network/Haskoin/Constants.hs
+++ b/src/Network/Haskoin/Constants.hs
@@ -24,7 +24,6 @@
     , netByIdent
     ) where
 
-import           Control.DeepSeq
 import           Data.ByteString              (ByteString)
 import           Data.List
 import           Data.Maybe
@@ -116,8 +115,6 @@
         case find ((== magic) . getNetworkMagic) allNets of
             Nothing  -> fail $ "Network magic unknown: " <> show magic
             Just net -> return net
-
-instance NFData Network
 
 instance Show Network where
     show = getNetworkIdent
diff --git a/src/Network/Haskoin/Crypto/Hash.hs b/src/Network/Haskoin/Crypto/Hash.hs
--- a/src/Network/Haskoin/Crypto/Hash.hs
+++ b/src/Network/Haskoin/Crypto/Hash.hs
@@ -29,7 +29,6 @@
     , join512
     ) where
 
-import           Control.DeepSeq         (NFData)
 import           Crypto.Hash             (RIPEMD160 (..), SHA1 (..),
                                           SHA256 (..), SHA512 (..), hashWith)
 import           Crypto.MAC.HMAC         (HMAC, hmac)
@@ -53,19 +52,19 @@
 -- | 'Word32' wrapped for type-safe 32-bit checksums.
 newtype CheckSum32 = CheckSum32
     { getCheckSum32 :: Word32
-    } deriving (Eq, Ord, Serialize, NFData, Show, Read, Hashable)
+    } deriving (Eq, Ord, Serialize, Show, Read, Hashable)
 
 -- | Type for 512-bit hashes.
 newtype Hash512 = Hash512 { getHash512 :: ShortByteString }
-    deriving (Eq, Ord, NFData, Hashable)
+    deriving (Eq, Ord, Hashable)
 
 -- | Type for 256-bit hashes.
 newtype Hash256 = Hash256 { getHash256 :: ShortByteString }
-    deriving (Eq, Ord, NFData, Hashable)
+    deriving (Eq, Ord, Hashable)
 
 -- | Type for 160-bit hashes.
 newtype Hash160 = Hash160 { getHash160 :: ShortByteString }
-    deriving (Eq, Ord, NFData, Hashable)
+    deriving (Eq, Ord, Hashable)
 
 instance Show Hash512 where
     showsPrec _ = shows . encodeHex . BSS.fromShort . getHash512
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 DeriveGeneric     #-}
 {-# LANGUAGE FlexibleContexts  #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE OverloadedStrings #-}
@@ -30,7 +31,6 @@
     ) where
 
 import           Control.Applicative         ((<|>))
-import           Control.DeepSeq             (NFData, rnf)
 import           Control.Monad               (guard, mzero, (<=<))
 import           Crypto.Secp256k1
 import           Data.Aeson                  (FromJSON, ToJSON, Value (String),
@@ -44,24 +44,15 @@
 import           Data.Serialize.Put          (Putter, putByteString)
 import           Data.String                 (IsString, fromString)
 import           Data.String.Conversions     (cs)
+import           GHC.Generics                (Generic)
 import           Network.Haskoin.Crypto.Hash
 import           Network.Haskoin.Util
-import           Text.Read                   (lexP, parens, pfail, readPrec)
-import qualified Text.Read                   as Read
 
 -- | Elliptic curve public key type with expected serialized compression flag.
 data PubKeyI = PubKeyI
     { pubKeyPoint      :: !PubKey
     , pubKeyCompressed :: !Bool
-    } deriving (Eq)
-
-instance Show PubKeyI where
-    showsPrec _ = shows . encodeHex . encode
-
-instance Read PubKeyI where
-    readPrec = parens $ do
-        Read.String str <- lexP
-        maybe pfail return $ eitherToMaybe . decode <=< decodeHex $ cs str
+    } deriving (Generic, Eq, Show, Read)
 
 instance IsString PubKeyI where
     fromString str =
@@ -69,9 +60,6 @@
       where
         e = error "Could not decode public key"
 
-instance NFData PubKeyI where
-    rnf (PubKeyI p c) = p `seq` rnf c `seq` rnf ()
-
 instance ToJSON PubKeyI where
     toJSON = String . encodeHex . encode
 
@@ -114,9 +102,6 @@
     { secKeyData       :: !SecKey
     , secKeyCompressed :: !Bool
     } deriving (Eq, Show, Read)
-
-instance NFData SecKeyI where
-    rnf (SecKeyI k c) = k `seq` rnf c `seq` ()
 
 -- | Wrap private key with corresponding public key compression flag.
 wrapSecKey :: Bool -> SecKey -> SecKeyI
diff --git a/src/Network/Haskoin/Keys/Extended.hs b/src/Network/Haskoin/Keys/Extended.hs
--- a/src/Network/Haskoin/Keys/Extended.hs
+++ b/src/Network/Haskoin/Keys/Extended.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE DeriveGeneric     #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE GADTs             #-}
 {-# LANGUAGE OverloadedStrings #-}
@@ -33,7 +34,11 @@
     , xPrvFP
     , xPubAddr
     , xPubExport
+    , xPubToJSON
+    , xPubFromJSON
     , xPrvExport
+    , xPrvToJSON
+    , xPrvFromJSON
     , xPubImport
     , xPrvImport
     , xPrvWif
@@ -41,8 +46,6 @@
     , putXPubKey
     , getXPrvKey
     , getXPubKey
-    , xPubFromJSON
-    , xPrvFromJSON
 
       -- ** Helpers
     , prvSubKeys
@@ -88,7 +91,6 @@
     ) where
 
 import           Control.Applicative
-import           Control.DeepSeq                (NFData, rnf)
 import           Control.Exception              (Exception, throw)
 import           Control.Monad                  (guard, mzero, unless, (<=<))
 import           Crypto.Secp256k1
@@ -114,6 +116,7 @@
 import           Data.String.Conversions        (cs)
 import           Data.Typeable                  (Typeable)
 import           Data.Word                      (Word32, Word8)
+import           GHC.Generics                   (Generic)
 import           Network.Haskoin.Address
 import           Network.Haskoin.Address.Base58
 import           Network.Haskoin.Constants
@@ -147,29 +150,10 @@
     , xPrvIndex  :: !KeyIndex  -- ^ derivation index
     , xPrvChain  :: !ChainCode -- ^ chain code
     , xPrvKey    :: !SecKey    -- ^ private key of this node
-    , xPrvNet    :: !Network
-    } deriving (Eq)
-
-instance Ord XPrvKey where
-    compare k1 k2 = xPrvExport k1 `compare` xPrvExport k2
-
-instance Show XPrvKey where
-    showsPrec _ = shows . xPrvExport
-
-instance Read XPrvKey where
-    readPrec = do
-        R.String str <- lexP
-        let bs = cs str
-            f k n = k <|> xPrvImport n bs
-        maybe pfail return $ foldl' f Nothing allNets
-
-instance NFData XPrvKey where
-    rnf (XPrvKey d p i c k n) =
-        rnf d `seq`
-        rnf p `seq` rnf i `seq` rnf c `seq` k `seq` rnf n `seq` ()
+    } deriving (Generic, Eq, Show, Read)
 
-instance ToJSON XPrvKey where
-    toJSON = A.String . xPrvExport
+xPrvToJSON :: Network -> XPrvKey -> Value
+xPrvToJSON net = A.String . xPrvExport net
 
 -- | Data type representing an extended BIP32 public key.
 data XPubKey = XPubKey
@@ -178,30 +162,9 @@
     , xPubIndex  :: !KeyIndex  -- ^ derivation index
     , xPubChain  :: !ChainCode -- ^ chain code
     , xPubKey    :: !PubKey    -- ^ public key of this node
-    , xPubNet    :: !Network
-    } deriving (Eq)
+    } deriving (Eq, Show, Read)
 
-instance Ord XPubKey where
-    compare k1 k2 = xPubExport k1 `compare` xPubExport k2
 
-instance Show XPubKey where
-    showsPrec _ = shows . xPubExport
-
-instance Read XPubKey where
-    readPrec = do
-        R.String str <- lexP
-        let bs = cs str
-            f k n = k <|> xPubImport n bs
-        maybe pfail return $ foldl' f Nothing allNets
-
-instance NFData XPubKey where
-    rnf (XPubKey d p i c k n) =
-        rnf d `seq`
-        rnf p `seq` rnf i `seq` rnf c `seq` k `seq` rnf n `seq` ()
-
-instance ToJSON XPubKey where
-    toJSON = A.String . xPubExport
-
 -- | Decode an extended public key from a JSON string
 xPubFromJSON :: Network -> Value -> Parser XPubKey
 xPubFromJSON net =
@@ -210,6 +173,10 @@
             Nothing -> fail "could not read xpub"
             Just x  -> return x
 
+-- | Get JSON 'Value' from 'XPubKey'.
+xPubToJSON :: Network -> XPubKey -> Value
+xPubToJSON net = A.String . xPubExport net
+
 -- | Decode an extended private key from a JSON string
 xPrvFromJSON :: Network -> Value -> Parser XPrvKey
 xPrvFromJSON net =
@@ -220,9 +187,9 @@
 
 -- | Build a BIP32 compatible extended private key from a bytestring. This will
 -- produce a root node (@depth=0@ and @parent=0@).
-makeXPrvKey :: Network -> ByteString -> XPrvKey
-makeXPrvKey net bs =
-    XPrvKey 0 0 0 c k net
+makeXPrvKey :: ByteString -> XPrvKey
+makeXPrvKey bs =
+    XPrvKey 0 0 0 c k
   where
     (p, c) = split512 $ hmac512 "Bitcoin seed" bs
     k     = fromMaybe err (secKey (encode p))
@@ -232,7 +199,7 @@
 -- will preserve the depth, parent, index and chaincode fields of the extended
 -- private keys.
 deriveXPubKey :: XPrvKey -> XPubKey
-deriveXPubKey (XPrvKey d p i c k n) = XPubKey d p i c (derivePubKey k) n
+deriveXPubKey (XPrvKey d p i c k) = XPubKey d p i c (derivePubKey k)
 
 -- | Compute a private, soft child key derivation. A private soft derivation
 -- will allow the equivalent extended public key to derive the public key for
@@ -248,7 +215,7 @@
           -> XPrvKey  -- ^ extended child private key
 prvSubKey xkey child
     | child >= 0 && child < 0x80000000 =
-        XPrvKey (xPrvDepth xkey + 1) (xPrvFP xkey) child c k (xPrvNet xkey)
+        XPrvKey (xPrvDepth xkey + 1) (xPrvFP xkey) child c k
     | otherwise = error "Invalid child derivation index"
   where
     pK = xPubKey $ deriveXPubKey xkey
@@ -264,7 +231,7 @@
           -> XPubKey  -- ^ extended child public key
 pubSubKey xKey child
     | child >= 0 && child < 0x80000000 =
-        XPubKey (xPubDepth xKey + 1) (xPubFP xKey) child c pK (xPubNet xKey)
+        XPubKey (xPubDepth xKey + 1) (xPubFP xKey) child c pK
     | otherwise = error "Invalid child derivation index"
   where
     m      = B.append (exportPubKey True (xPubKey xKey)) (encode child)
@@ -283,7 +250,7 @@
            -> XPrvKey  -- ^ extended child private key
 hardSubKey xkey child
     | child >= 0 && child < 0x80000000 =
-        XPrvKey (xPrvDepth xkey + 1) (xPrvFP xkey) i c k (xPrvNet xkey)
+        XPrvKey (xPrvDepth xkey + 1) (xPrvFP xkey) i c k
     | otherwise = error "Invalid child derivation index"
   where
     i      = setBit child 31
@@ -336,15 +303,15 @@
 
 -- | Computer the 'Address' of an extended public key.
 xPubAddr :: XPubKey -> Address
-xPubAddr xkey = pubKeyAddr (xPubNet xkey) (wrapPubKey True (xPubKey xkey))
+xPubAddr xkey = pubKeyAddr (wrapPubKey True (xPubKey xkey))
 
 -- | Exports an extended private key to the BIP32 key export format ('Base58').
-xPrvExport :: XPrvKey -> Base58
-xPrvExport = encodeBase58Check . runPut . putXPrvKey
+xPrvExport :: Network -> XPrvKey -> Base58
+xPrvExport net = encodeBase58Check . runPut . putXPrvKey net
 
 -- | Exports an extended public key to the BIP32 key export format ('Base58').
-xPubExport :: XPubKey -> Base58
-xPubExport = encodeBase58Check . runPut . putXPubKey
+xPubExport :: Network -> XPubKey -> Base58
+xPubExport net = encodeBase58Check . runPut . putXPubKey net
 
 -- | Decodes a BIP32 encoded extended private key. This function will fail if
 -- invalid base 58 characters are detected or if the checksum fails.
@@ -357,8 +324,8 @@
 xPubImport net = eitherToMaybe . runGet (getXPubKey net) <=< decodeBase58Check
 
 -- | Export an extended private key to WIF (Wallet Import Format).
-xPrvWif :: XPrvKey -> Base58
-xPrvWif xkey = toWif (xPrvNet xkey) (wrapSecKey True (xPrvKey xkey))
+xPrvWif :: Network -> XPrvKey -> Base58
+xPrvWif net xkey = toWif net (wrapSecKey True (xPrvKey xkey))
 
 -- | Parse a binary extended private key.
 getXPrvKey :: Network -> Get XPrvKey
@@ -371,12 +338,11 @@
                 <*> getWord32be
                 <*> S.get
                 <*> getPadPrvKey
-                <*> pure net
 
 -- | Serialize an extended private key.
-putXPrvKey :: Putter XPrvKey
-putXPrvKey k = do
-        putWord32be  $ getExtSecretPrefix (xPrvNet k)
+putXPrvKey :: Network -> Putter XPrvKey
+putXPrvKey net k = do
+        putWord32be  $ getExtSecretPrefix net
         putWord8     $ xPrvDepth k
         putWord32be  $ xPrvParent k
         putWord32be  $ xPrvIndex k
@@ -394,12 +360,11 @@
                 <*> getWord32be
                 <*> S.get
                 <*> (pubKeyPoint <$> S.get)
-                <*> pure net
 
 -- | Serialize an extended public key.
-putXPubKey :: Putter XPubKey
-putXPubKey k = do
-        putWord32be $ getExtPubKeyPrefix (xPubNet k)
+putXPubKey :: Network -> Putter XPubKey
+putXPubKey net k = do
+        putWord32be $ getExtPubKeyPrefix net
         putWord8    $ xPubDepth k
         putWord32be $ xPubParent k
         putWord32be $ xPubIndex k
@@ -442,10 +407,8 @@
 -- | Derive a multisig address from a list of public keys, the number of
 -- required signatures /m/ and a derivation index. The derivation type is a
 -- public, soft derivation.
-deriveMSAddr :: Network -> [XPubKey] -> Int -> KeyIndex -> (Address, RedeemScript)
-deriveMSAddr net keys m i
-    | all ((== net) . xPubNet) keys = (payToScriptAddress net rdm, rdm)
-    | otherwise = error "Some extended public keys on the wrong network"
+deriveMSAddr :: [XPubKey] -> Int -> KeyIndex -> (Address, RedeemScript)
+deriveMSAddr keys m i = (payToScriptAddress rdm, rdm)
   where
     rdm = sortMulSig $ PayMulSig k m
     k = map (wrapPubKey True . xPubKey . flip pubSubKey i) keys
@@ -453,12 +416,12 @@
 -- | Cyclic list of all multisig addresses derived from a list of public keys,
 -- a number of required signatures /m/ and starting from an offset index. The
 -- derivation type is a public, soft derivation.
-deriveMSAddrs :: Network -> [XPubKey] -> Int -> KeyIndex
+deriveMSAddrs :: [XPubKey] -> Int -> KeyIndex
               -> [(Address, RedeemScript, KeyIndex)]
-deriveMSAddrs net keys m = map f . cycleIndex
+deriveMSAddrs keys m = map f . cycleIndex
   where
     f i =
-        let (a, rdm) = deriveMSAddr net keys m i
+        let (a, rdm) = deriveMSAddr keys m i
          in (a, rdm, i)
 
 -- | Helper function to go through derivation indices.
@@ -519,12 +482,6 @@
     (:/)  :: AnyOrSoft t => !(DerivPathI t) -> !KeyIndex -> DerivPathI t
     Deriv :: DerivPathI t
 
-instance NFData (DerivPathI t) where
-    rnf p = case p of
-        next :| i -> rnf i `seq` rnf next
-        next :/ i -> rnf i `seq` rnf next
-        Deriv     -> ()
-
 instance Eq (DerivPathI t) where
     (nextA :| iA) == (nextB :| iB) = iA == iB && nextA == nextB
     (nextA :/ iA) == (nextB :/ iB) = iA == iB && nextA == nextB
@@ -843,27 +800,25 @@
 -- | Derive a multisig address from a given parent path. The number of required
 -- signatures (m in m of n) is also needed.
 derivePathMSAddr ::
-       Network
-    -> [XPubKey]
+       [XPubKey]
     -> SoftPath
     -> Int
     -> KeyIndex
     -> (Address, RedeemScript)
-derivePathMSAddr net keys path =
-    deriveMSAddr net $ map (derivePubPath path) keys
+derivePathMSAddr keys path =
+    deriveMSAddr $ map (derivePubPath path) keys
 
 -- | Cyclic list of all multisig addresses derived from a given parent path and
 -- starting from the given offset index. The number of required signatures
 -- (m in m of n) is also needed.
 derivePathMSAddrs ::
-       Network
-    -> [XPubKey]
+       [XPubKey]
     -> SoftPath
     -> Int
     -> KeyIndex
     -> [(Address, RedeemScript, KeyIndex)]
-derivePathMSAddrs net keys path =
-    deriveMSAddrs net $ map (derivePubPath path) keys
+derivePathMSAddrs keys path =
+    deriveMSAddrs $ map (derivePubPath path) keys
 
 {- Utilities for extended keys -}
 
diff --git a/src/Network/Haskoin/Network/Bloom.hs b/src/Network/Haskoin/Network/Bloom.hs
--- a/src/Network/Haskoin/Network/Bloom.hs
+++ b/src/Network/Haskoin/Network/Bloom.hs
@@ -26,7 +26,6 @@
     , acceptsFilters
     ) where
 
-import           Control.DeepSeq                (NFData, rnf)
 import           Control.Monad                  (forM_, replicateM)
 import           Data.Bits
 import           Data.ByteString                (ByteString)
@@ -67,8 +66,6 @@
     -- ^ auto-update on pay-to-pubkey or pay-to-multisig (default)
     deriving (Eq, Show, Read)
 
-instance NFData BloomFlags where rnf x = seq x ()
-
 instance Serialize BloomFlags where
     get = go =<< getWord8
       where
@@ -100,10 +97,6 @@
     }
     deriving (Eq, Show, Read)
 
-instance NFData BloomFilter where
-    rnf (BloomFilter d h t g) =
-        rnf d `seq` rnf h `seq` rnf t `seq` rnf g
-
 instance Serialize BloomFilter where
 
     get = BloomFilter <$> (S.fromList <$> (readDat =<< get))
@@ -123,9 +116,6 @@
 newtype FilterLoad = FilterLoad { filterLoadBloomFilter :: BloomFilter }
     deriving (Eq, Show, Read)
 
-instance NFData FilterLoad where
-    rnf (FilterLoad f) = rnf f
-
 instance Serialize FilterLoad where
     get = FilterLoad <$> get
     put (FilterLoad f) = put f
@@ -134,9 +124,6 @@
 -- requiring a completely new one to be set.
 newtype FilterAdd = FilterAdd { getFilterData :: ByteString }
     deriving (Eq, Show, Read)
-
-instance NFData FilterAdd where
-    rnf (FilterAdd f) = rnf f
 
 instance Serialize FilterAdd where
     get = do
diff --git a/src/Network/Haskoin/Network/Common.hs b/src/Network/Haskoin/Network/Common.hs
--- a/src/Network/Haskoin/Network/Common.hs
+++ b/src/Network/Haskoin/Network/Common.hs
@@ -1,5 +1,4 @@
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE RecordWildCards   #-}
 {-|
 Module      : Network.Haskoin.Network.Common
 Copyright   : No rights reserved
@@ -41,7 +40,6 @@
     , stringToCommand
     ) where
 
-import           Control.DeepSeq             (NFData, rnf)
 import           Control.Monad               (forM_, liftM2, replicateM, unless)
 import           Data.Bits                   (shiftL)
 import           Data.ByteString             (ByteString)
@@ -90,9 +88,6 @@
           , alertSignature :: !VarString
           } deriving (Eq, Show, Read)
 
-instance NFData Alert where
-    rnf (Alert p s) = rnf p `seq` rnf s
-
 instance Serialize Alert where
     get = Alert <$> S.get <*> S.get
     put (Alert p s) = put p >> put s
@@ -109,9 +104,6 @@
               getDataList :: [InvVector]
             } deriving (Eq, Show)
 
-instance NFData GetData where
-    rnf (GetData l) = rnf l
-
 instance Serialize GetData where
 
     get = GetData <$> (repList =<< S.get)
@@ -131,9 +123,6 @@
           invList :: [InvVector]
         } deriving (Eq, Show)
 
-instance NFData Inv where
-    rnf (Inv l) = rnf l
-
 instance Serialize Inv where
 
     get = Inv <$> (repList =<< S.get)
@@ -156,8 +145,6 @@
     | InvWitnessMerkleBlock -- ^ segwit filtere block
     deriving (Eq, Show, Read)
 
-instance NFData InvType where rnf x = seq x ()
-
 instance Serialize InvType where
     get = go =<< getWord32le
       where
@@ -194,9 +181,6 @@
               , invHash :: !Hash256
               } deriving (Eq, Show)
 
-instance NFData InvVector where
-    rnf (InvVector t h) = rnf t `seq` rnf h
-
 instance Serialize InvVector where
     get = InvVector <$> S.get <*> S.get
     put (InvVector t h) = put t >> put h
@@ -211,9 +195,6 @@
                    , naAddress  :: !SockAddr
                    } deriving (Eq, Show)
 
-instance NFData NetworkAddress where
-    rnf NetworkAddress{..} = rnf naServices `seq` naAddress `seq` ()
-
 instance Serialize NetworkAddress where
 
     get = NetworkAddress <$> getWord64le
@@ -260,9 +241,6 @@
                notFoundList :: [InvVector]
              } deriving (Eq, Show)
 
-instance NFData NotFound where
-    rnf (NotFound l) = rnf l
-
 instance Serialize NotFound where
 
     get = NotFound <$> (repList =<< S.get)
@@ -281,9 +259,6 @@
            pingNonce :: Word64
          } deriving (Eq, Show, Read)
 
-instance NFData Ping where
-    rnf (Ping n) = rnf n
-
 -- | A Pong message is sent as a response to a ping message.
 newtype Pong =
     Pong {
@@ -291,9 +266,6 @@
            pongNonce :: Word64
          } deriving (Eq, Show, Read)
 
-instance NFData Pong where
-    rnf (Pong n) = rnf n
-
 instance Serialize Ping where
     get = Ping <$> getWord64le
     put (Ping n) = putWord64le n
@@ -379,9 +351,6 @@
 newtype VarInt = VarInt { getVarInt :: Word64 }
     deriving (Eq, Show, Read)
 
-instance NFData VarInt where
-    rnf (VarInt w) = rnf w
-
 instance Serialize VarInt where
 
     get = VarInt <$> ( getWord8 >>= go )
@@ -408,9 +377,6 @@
 newtype VarString = VarString { getVarString :: ByteString }
     deriving (Eq, Show, Read)
 
-instance NFData VarString where
-    rnf (VarString s) = rnf s
-
 instance Serialize VarString where
 
     get = VarString <$> (readBS =<< S.get)
@@ -446,18 +412,6 @@
             , relay       :: !Bool
             } deriving (Eq, Show)
 
-instance NFData Version where
-    rnf Version{..} =
-        rnf version `seq`
-        rnf services `seq`
-        rnf timestamp `seq`
-        rnf addrRecv `seq`
-        rnf addrSend `seq`
-        rnf verNonce `seq`
-        rnf userAgent `seq`
-        rnf startHeight `seq`
-        rnf relay
-
 instance Serialize Version where
 
     get = Version <$> getWord32le
@@ -532,8 +486,6 @@
     readPrec = do
         String str <- lexP
         maybe pfail return (stringToCommand (cs str))
-
-instance NFData MessageCommand where rnf x = seq x ()
 
 instance Serialize MessageCommand where
     get = go =<< getByteString 12
diff --git a/src/Network/Haskoin/Network/Message.hs b/src/Network/Haskoin/Network/Message.hs
--- a/src/Network/Haskoin/Network/Message.hs
+++ b/src/Network/Haskoin/Network/Message.hs
@@ -17,7 +17,6 @@
     , getMessage
     ) where
 
-import           Control.DeepSeq                    (NFData, rnf)
 import           Control.Monad                      (unless)
 import qualified Data.ByteString                    as BS
 import           Data.Serialize                     (Serialize, encode, get,
@@ -48,9 +47,6 @@
       -- | checksum of payload
     , headChecksum    :: !CheckSum32
     } deriving (Eq, Show)
-
-instance NFData MessageHeader where
-    rnf (MessageHeader m c p s) = rnf m `seq` rnf c `seq` rnf p `seq` rnf s
 
 instance Serialize MessageHeader where
 
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
@@ -31,18 +31,16 @@
 , scriptOpToInt
 ) where
 
-import           Control.DeepSeq                    (NFData, rnf)
 import           Control.Monad
-import           Data.Aeson                         as A
-import           Data.ByteString                    (ByteString)
-import qualified Data.ByteString                    as B
-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           Data.Aeson                  as A
+import           Data.ByteString             (ByteString)
+import qualified Data.ByteString             as B
+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           Network.Haskoin.Crypto.Hash
 import           Network.Haskoin.Keys.Common
 import           Network.Haskoin.Util
@@ -63,9 +61,6 @@
            }
     deriving (Eq, Show, Read)
 
-instance NFData Script where
-    rnf (Script o) = rnf o
-
 instance Serialize Script where
     get =
         Script <$> getScriptOps
@@ -91,32 +86,41 @@
     | OPDATA4
     deriving (Show, Read, Eq)
 
-instance NFData PushDataType where rnf x = seq x ()
-
 -- | Data type representing an operator allowed inside a 'Script'.
 data ScriptOp
       -- Pushing Data
-    = OP_PUSHDATA !ByteString !PushDataType
+    = OP_PUSHDATA !ByteString
+                  !PushDataType
     | OP_0
     | OP_1NEGATE
     | OP_RESERVED
-    | OP_1  | OP_2  | OP_3  | OP_4
-    | OP_5  | OP_6  | OP_7  | OP_8
-    | OP_9  | OP_10 | OP_11 | OP_12
-    | OP_13 | OP_14 | OP_15 | OP_16
-
+    | OP_1
+    | OP_2
+    | OP_3
+    | OP_4
+    | OP_5
+    | OP_6
+    | OP_7
+    | OP_8
+    | OP_9
+    | OP_10
+    | OP_11
+    | OP_12
+    | OP_13
+    | OP_14
+    | OP_15
+    | OP_16
       -- Flow control
     | OP_NOP
-    | OP_VER        -- reserved
+    | OP_VER -- reserved
     | OP_IF
     | OP_NOTIF
-    | OP_VERIF      -- resreved
-    | OP_VERNOTIF   -- reserved
+    | OP_VERIF -- resreved
+    | OP_VERNOTIF -- reserved
     | OP_ELSE
     | OP_ENDIF
     | OP_VERIFY
     | OP_RETURN
-
       -- Stack operations
     | OP_TOALTSTACK
     | OP_FROMALTSTACK
@@ -137,14 +141,12 @@
     | OP_2OVER
     | OP_2ROT
     | OP_2SWAP
-
       -- Splice
     | OP_CAT
     | OP_SUBSTR
     | OP_LEFT
     | OP_RIGHT
     | OP_SIZE
-
       -- Bitwise logic
     | OP_INVERT
     | OP_AND
@@ -154,7 +156,6 @@
     | OP_EQUALVERIFY
     | OP_RESERVED1
     | OP_RESERVED2
-
       -- Arithmetic
     | OP_1ADD
     | OP_1SUB
@@ -183,7 +184,6 @@
     | OP_MIN
     | OP_MAX
     | OP_WITHIN
-
       -- Crypto
     | OP_RIPEMD160
     | OP_SHA1
@@ -195,28 +195,24 @@
     | OP_CHECKSIGVERIFY
     | OP_CHECKMULTISIG
     | OP_CHECKMULTISIGVERIFY
-
       -- Expansion
-    | OP_NOP1 | OP_NOP2 | OP_NOP3 | OP_NOP4 | OP_NOP5
-    | OP_NOP6 | OP_NOP7 | OP_NOP8 | OP_NOP9 | OP_NOP10
-
-
+    | OP_NOP1
+    | OP_NOP2
+    | OP_NOP3
+    | OP_NOP4
+    | OP_NOP5
+    | OP_NOP6
+    | OP_NOP7
+    | OP_NOP8
+    | OP_NOP9
+    | OP_NOP10
       -- Other
     | OP_PUBKEYHASH
     | OP_PUBKEY
     | OP_INVALIDOPCODE !Word8
-
-        deriving (Show, Read, Eq)
-
-
-instance NFData ScriptOp where
-    rnf (OP_PUSHDATA b t)    = rnf b `seq` rnf t
-    rnf (OP_INVALIDOPCODE c) = rnf c
-    rnf x                    = x `seq` ()
-
+    deriving (Show, Read, Eq)
 
 instance Serialize ScriptOp where
-
     get = go =<< (fromIntegral <$> getWord8)
       where
         go op
@@ -255,6 +251,7 @@
             | op == 0x5e = return OP_14
             | op == 0x5f = return OP_15
             | op == 0x60 = return OP_16
+
             -- Flow control
             | op == 0x61 = return OP_NOP
             | op == 0x62 = return OP_VER        -- reserved
@@ -603,15 +600,6 @@
 
 instance ToJSON ScriptOutput where
     toJSON = String . encodeHex . encodeOutputBS
-
-instance NFData ScriptOutput where
-    rnf (PayPK k)                = rnf k
-    rnf (PayPKHash a)            = rnf a
-    rnf (PayMulSig k r)          = rnf k `seq` rnf r
-    rnf (PayScriptHash a)        = rnf a
-    rnf (PayWitnessPKHash a)     = rnf a
-    rnf (PayWitnessScriptHash h) = rnf h
-    rnf (DataCarrier a)          = rnf a
 
 -- | Is script a pay-to-public-key output?
 isPayPK :: ScriptOutput -> Bool
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
@@ -34,7 +34,6 @@
 , decodeTxSig
 ) where
 
-import           Control.DeepSeq                    (NFData, rnf)
 import           Control.Monad
 import           Crypto.Secp256k1
 import qualified Data.Aeson                         as J
@@ -93,7 +92,7 @@
 -- 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, NFData, Show, Read)
+    deriving (Eq, Ord, Enum, Bits, Num, Real, Integral, Show, Read)
 
 instance J.FromJSON SigHash where
     parseJSON =
@@ -275,10 +274,6 @@
                   }
     | TxSignatureEmpty
     deriving (Eq, Show)
-
-instance NFData TxSignature where
-    rnf (TxSignature s h) = s `seq` rnf h `seq` ()
-    rnf TxSignatureEmpty  = ()
 
 -- | Serialize a 'TxSignature'.
 encodeTxSig :: TxSignature -> ByteString
diff --git a/src/Network/Haskoin/Script/Standard.hs b/src/Network/Haskoin/Script/Standard.hs
--- a/src/Network/Haskoin/Script/Standard.hs
+++ b/src/Network/Haskoin/Script/Standard.hs
@@ -27,7 +27,6 @@
     ) where
 
 import           Control.Applicative            ((<|>))
-import           Control.DeepSeq                (NFData, rnf)
 import           Control.Monad                  (guard, (<=<))
 import           Data.ByteString                (ByteString)
 import           Data.Function                  (on)
@@ -61,11 +60,6 @@
                    }
     deriving (Eq, Show)
 
-instance NFData SimpleInput where
-    rnf (SpendPK i)       = rnf i
-    rnf (SpendPKHash i k) = rnf i `seq` rnf k
-    rnf (SpendMulSig k)   = rnf k
-
 -- | Returns true if the input script is spending from a pay-to-public-key
 -- output.
 isSpendPK :: ScriptInput -> Bool
@@ -105,10 +99,6 @@
                 -- ^ redeem script
             }
     deriving (Eq, Show)
-
-instance NFData ScriptInput where
-    rnf (RegularInput i)      = rnf i
-    rnf (ScriptHashInput i o) = rnf i `seq` rnf o
 
 -- | Heuristic to decode an input script into one of the standard types.
 decodeSimpleInput :: Network -> Script -> Either String SimpleInput
diff --git a/src/Network/Haskoin/Test/Address.hs b/src/Network/Haskoin/Test/Address.hs
--- a/src/Network/Haskoin/Test/Address.hs
+++ b/src/Network/Haskoin/Test/Address.hs
@@ -9,19 +9,17 @@
 module Network.Haskoin.Test.Address where
 
 import           Network.Haskoin.Address
-import           Network.Haskoin.Constants
 import           Network.Haskoin.Test.Crypto
 import           Test.QuickCheck
 
 -- | Arbitrary pay-to-public-key-hash or pay-to-script-hash address.
-arbitraryAddress :: Network -> Gen Address
-arbitraryAddress net =
-    oneof [arbitraryPubKeyAddress net, arbitraryScriptAddress net]
+arbitraryAddress :: Gen Address
+arbitraryAddress = oneof [arbitraryPubKeyAddress, arbitraryScriptAddress]
 
 -- | Arbitrary pay-to-public-key-hash address.
-arbitraryPubKeyAddress :: Network -> Gen Address
-arbitraryPubKeyAddress net = p2pkhAddr net <$> arbitraryHash160
+arbitraryPubKeyAddress :: Gen Address
+arbitraryPubKeyAddress = p2pkhAddr <$> arbitraryHash160
 
 -- | Arbitrary pay-to-script-hash address.
-arbitraryScriptAddress :: Network -> Gen Address
-arbitraryScriptAddress net = p2shAddr net <$> arbitraryHash160
+arbitraryScriptAddress :: Gen Address
+arbitraryScriptAddress = p2shAddr <$> arbitraryHash160
diff --git a/src/Network/Haskoin/Test/Keys.hs b/src/Network/Haskoin/Test/Keys.hs
--- a/src/Network/Haskoin/Test/Keys.hs
+++ b/src/Network/Haskoin/Test/Keys.hs
@@ -11,7 +11,6 @@
 import           Data.Bits                     (clearBit)
 import           Data.List                     (foldl')
 import           Data.Word                     (Word32)
-import           Network.Haskoin.Constants
 import           Network.Haskoin.Crypto
 import           Network.Haskoin.Keys.Common
 import           Network.Haskoin.Keys.Extended
@@ -29,18 +28,17 @@
     return (k, derivePubKeyI k)
 
 -- | Arbitrary extended private key.
-arbitraryXPrvKey :: Network -> Gen XPrvKey
-arbitraryXPrvKey net =
+arbitraryXPrvKey :: Gen XPrvKey
+arbitraryXPrvKey =
     XPrvKey <$> arbitrary
             <*> arbitrary
             <*> arbitrary
             <*> arbitraryHash256
             <*> arbitrary
-            <*> pure net
 
 -- | Arbitrary extended public key with its corresponding private key.
-arbitraryXPubKey :: Network -> Gen (XPrvKey, XPubKey)
-arbitraryXPubKey net = (\k -> (k, deriveXPubKey k)) <$> arbitraryXPrvKey net
+arbitraryXPubKey :: Gen (XPrvKey, XPubKey)
+arbitraryXPubKey = (\k -> (k, deriveXPubKey k)) <$> arbitraryXPrvKey
 
 {- Custom derivations -}
 
diff --git a/src/Network/Haskoin/Test/Script.hs b/src/Network/Haskoin/Test/Script.hs
--- a/src/Network/Haskoin/Test/Script.hs
+++ b/src/Network/Haskoin/Test/Script.hs
@@ -220,7 +220,7 @@
     [ arbitraryPKOutput
     , arbitraryPKHashOutput
     , arbitraryMSOutput
-    , arbitrarySHOutput net
+    , arbitrarySHOutput
     , arbitraryDCOutput
     ] ++
     if getSegWit net
@@ -229,7 +229,7 @@
 
 -- | Arbitrary 'ScriptOutput' of type 'PayPK', 'PayPKHash' or 'PayMS'
 -- (Not 'PayScriptHash', 'DataCarrier', or SegWit)
-arbitrarySimpleOutput ::Gen ScriptOutput
+arbitrarySimpleOutput :: Gen ScriptOutput
 arbitrarySimpleOutput =
     oneof
         [ arbitraryPKOutput
@@ -270,9 +270,8 @@
     return $ PayMulSig keys m
 
 -- | Arbitrary 'ScriptOutput' of type 'PayScriptHash'.
-arbitrarySHOutput :: Network -> Gen ScriptOutput
-arbitrarySHOutput net =
-    PayScriptHash . getAddrHash160 <$> arbitraryScriptAddress net
+arbitrarySHOutput :: Gen ScriptOutput
+arbitrarySHOutput = PayScriptHash . getAddrHash160 <$> arbitraryScriptAddress
 
 -- | Arbitrary 'ScriptOutput' of type 'DataCarrier'.
 arbitraryDCOutput :: Gen ScriptOutput
diff --git a/src/Network/Haskoin/Test/Transaction.hs b/src/Network/Haskoin/Test/Transaction.hs
--- a/src/Network/Haskoin/Test/Transaction.hs
+++ b/src/Network/Haskoin/Test/Transaction.hs
@@ -124,7 +124,7 @@
 arbitraryAddrOnlyTxOut :: Network -> Gen TxOut
 arbitraryAddrOnlyTxOut net = do
     v <- getTestCoin <$> arbitrarySatoshi net
-    out <- oneof [ arbitraryPKHashOutput, arbitrarySHOutput net ]
+    out <- oneof [arbitraryPKHashOutput, arbitrarySHOutput]
     return $ TxOut v $ encodeOutputBS out
 
 -- | Arbitrary 'SigInput' with the corresponding private keys used
@@ -150,7 +150,7 @@
 arbitraryAnyInput :: Network -> Bool -> Gen (SigInput, SecKeyI)
 arbitraryAnyInput net pkh = do
     (k, p) <- arbitraryKeyPair
-    let out | pkh = PayPKHash $ getAddrHash160 $ pubKeyAddr net p
+    let out | pkh = PayPKHash $ getAddrHash160 $ pubKeyAddr p
             | otherwise = PayPK p
     (val, op, sh) <- arbitraryInputStuff net
     return (SigInput out val op sh Nothing, k)
@@ -183,7 +183,7 @@
         , f <$> arbitraryPKHashSigInput net
         , arbitraryMSSigInput net
         ]
-    let out = PayScriptHash $ getAddrHash160 $ payToScriptAddress net rdm
+    let out = PayScriptHash $ getAddrHash160 $ payToScriptAddress rdm
     return (SigInput out val op sh $ Just rdm, ks)
   where
     f (si, k) = (si, [k])
@@ -245,7 +245,7 @@
         let so = PayMulSig pubKeys m
         elements
             [ (so, val, Nothing, prvKeys, m, n)
-            , ( PayScriptHash $ getAddrHash160 $ payToScriptAddress net so
+            , ( PayScriptHash $ getAddrHash160 $ payToScriptAddress so
               , val
               , Just so
               , prvKeys
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
@@ -40,7 +40,6 @@
     ) where
 
 import           Control.Arrow                      (first)
-import           Control.DeepSeq                    (NFData, rnf)
 import           Control.Monad                      (foldM, mzero, unless, when)
 import           Control.Monad.Identity             (runIdentity)
 import           Crypto.Secp256k1
@@ -275,10 +274,6 @@
     , sigInputRedeem :: !(Maybe RedeemScript) -- ^ sedeem script
     } deriving (Eq, Show)
 
-instance NFData SigInput where
-    rnf (SigInput o v p h b) =
-        rnf o `seq` rnf v `seq` rnf p `seq` rnf h `seq` rnf b
-
 instance ToJSON SigInput where
     toJSON (SigInput so val op sh rdm) = object $
         [ "pkscript" .= so
@@ -311,7 +306,7 @@
   where
     ti = txIn otx
     go tx (sigi@(SigInput so _ _ _ rdmM), i) = do
-        keys <- sigKeys net so rdmM allKeys
+        keys <- sigKeys so rdmM allKeys
         foldM (\t k -> signInput net t i sigi k) tx keys
 
 -- | Sign a single input in a transaction deterministically (RFC-6979).
@@ -339,21 +334,20 @@
 -- | Find from the list of provided private keys which one is required to sign
 -- the 'ScriptOutput'.
 sigKeys ::
-       Network
-    -> ScriptOutput
+       ScriptOutput
     -> Maybe RedeemScript
     -> [SecKey]
     -> Either String [SecKeyI]
-sigKeys net so rdmM keys =
+sigKeys so rdmM keys =
     case (so, rdmM) of
         (PayPK p, Nothing) ->
             return . map fst . maybeToList $ find ((== p) . snd) zipKeys
         (PayPKHash h, Nothing) ->
             return . map fst . maybeToList $
-            find ((== h) . getAddrHash160 . pubKeyAddr net . snd) zipKeys
+            find ((== h) . getAddrHash160 . pubKeyAddr . snd) zipKeys
         (PayMulSig ps r, Nothing) ->
             return $ map fst $ take r $ filter ((`elem` ps) . snd) zipKeys
-        (PayScriptHash _, Just rdm) -> sigKeys net rdm Nothing keys
+        (PayScriptHash _, Just rdm) -> sigKeys rdm Nothing keys
         _ -> Left "sigKeys: Could not decode output script"
   where
     zipKeys =
@@ -494,7 +488,7 @@
             Right (RegularInput (SpendPKHash (TxSignature sig sh) pub)) ->
                 case so of
                     PayPKHash h ->
-                        pubKeyAddr net pub == p2pkhAddr net h &&
+                        pubKeyAddr pub == p2pkhAddr h &&
                         verifyHashSig
                             (txSigHash net tx out val i sh)
                             sig
@@ -509,7 +503,7 @@
             Right (ScriptHashInput si rdm) ->
                 case so of
                     PayScriptHash h ->
-                        payToScriptAddress net rdm == p2shAddr net h &&
+                        payToScriptAddress rdm == p2shAddr h &&
                         go (encodeInputBS $ RegularInput si) rdm val
                     _ -> False
             _ -> False
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
@@ -28,7 +28,6 @@
     ) where
 
 import           Control.Applicative            ((<|>))
-import           Control.DeepSeq                (NFData, rnf)
 import           Control.Monad                  (forM_, guard, liftM2, mzero,
                                                  replicateM, (<=<))
 import           Data.Aeson                     as A
@@ -49,7 +48,7 @@
 
 -- | Transaction id: hash of transaction excluding witness data.
 newtype TxHash = TxHash { getTxHash :: Hash256 }
-    deriving (Eq, Ord, NFData, Hashable, Serialize)
+    deriving (Eq, Ord, Hashable, Serialize)
 
 instance Show TxHash where
     showsPrec _ = shows . txHashToHex
@@ -128,9 +127,6 @@
       where
         e = error "Could not read transaction from hex string"
 
-instance NFData Tx where
-    rnf (Tx v i o w l) = rnf v `seq` rnf i `seq` rnf o `seq` rnf w `seq` rnf l
-
 instance Serialize Tx where
     get = parseWitnessTx <|> parseLegacyTx
     put tx
@@ -231,9 +227,6 @@
          , txInSequence :: !Word32
          } deriving (Eq, Show, Ord)
 
-instance NFData TxIn where
-    rnf (TxIn p i s) = rnf p `seq` rnf i `seq` rnf s
-
 instance Serialize TxIn where
     get =
         TxIn <$> S.get <*> (readBS =<< S.get) <*> getWord32le
@@ -255,9 +248,6 @@
           , scriptOutput :: !ByteString
           } deriving (Eq, Show, Ord)
 
-instance NFData TxOut where
-    rnf (TxOut v o) = rnf v `seq` rnf o
-
 instance Serialize TxOut where
     get = do
         val <- getWord64le
@@ -276,9 +266,6 @@
       -- | position of output in previous transaction
     , outPointIndex :: !Word32
     } deriving (Show, Read, Eq, Ord)
-
-instance NFData OutPoint where
-    rnf (OutPoint h i) = rnf h `seq` rnf i
 
 instance FromJSON OutPoint where
     parseJSON = withText "OutPoint" $
diff --git a/test/Network/Haskoin/Address/CashAddrSpec.hs b/test/Network/Haskoin/Address/CashAddrSpec.hs
--- a/test/Network/Haskoin/Address/CashAddrSpec.hs
+++ b/test/Network/Haskoin/Address/CashAddrSpec.hs
@@ -15,80 +15,117 @@
 
 spec :: Spec
 spec = do
-  describe "cashaddr checksum test vectors" $ do
-    it "prefix:x64nx6hz" $ do
-      let mpb = cash32decode "prefix:x64nx6hz"
-      mpb `shouldBe` Just ("prefix", "")
-    it "p:gpf8m4h7" $ do
-      let mpb = cash32decode "p:gpf8m4h7"
-      mpb `shouldBe` Just ("p", "")
-    it "bitcoincash:qpzry9x8gf2tvdw0s3jn54khce6mua7lcw20ayyn" $ do
-      let mpb = cash32decode "bitcoincash:qpzry9x8gf2tvdw0s3jn54khce6mua7lcw20ayyn"
-      mpb `shouldBe` Just ("bitcoincash","\NULD2\DC4\199BT\182\&5\207\132e:V\215\198u\190w\223")
-    it "bchtest:testnetaddress4d6njnut" $ do
-      let mpb = cash32decode "bchtest:testnetaddress4d6njnut"
-      mpb `shouldBe` Just ("bchtest","^`\185\229}kG\152")
-    it "bchreg:555555555555555555555555555555555555555555555udxmlmrz" $ do
-      let mpb = cash32decode "bchreg:555555555555555555555555555555555555555555555udxmlmrz"
-      mpb `shouldBe` Just ("bchreg","\165)JR\148\165)JR\148\165)JR\148\165)JR\148\165)JR\148\165)J")
-
-  describe "cashaddr to base58 translation test vectors" $ do
-    it "1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu" $ do
-      let addr = base58ToCashAddr "1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu"
-      addr `shouldBe` Just "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a"
-    it "1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR" $ do
-      let addr = base58ToCashAddr "1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR"
-      addr `shouldBe` Just "bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy"
-    it "16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb" $ do
-      let addr = base58ToCashAddr "16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb"
-      addr `shouldBe` Just "bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r"
-    it "3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC" $ do
-      let addr = base58ToCashAddr "3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC"
-      addr `shouldBe` Just "bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq"
-    it "3LDsS579y7sruadqu11beEJoTjdFiFCdX4" $ do
-      let addr = base58ToCashAddr "3LDsS579y7sruadqu11beEJoTjdFiFCdX4"
-      addr `shouldBe` Just "bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e"
-    it "31nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw" $ do
-      let addr = base58ToCashAddr "31nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw"
-      addr `shouldBe` Just "bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37"
-
-  describe "base58 to cashaddr translation test vectors" $ do
-    it "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a" $ do
-      let addr = cashAddrtoBase58 "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a"
-      addr `shouldBe` Just "1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu"
-    it "bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy" $ do
-      let addr = cashAddrtoBase58 "bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy"
-      addr `shouldBe` Just "1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR"
-    it "bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r" $ do
-      let addr = cashAddrtoBase58 "bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r"
-      addr `shouldBe` Just "16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb"
-    it "bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq" $ do
-      let addr = cashAddrtoBase58 "bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq"
-      addr `shouldBe` Just "3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC"
-    it "bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e" $ do
-      let addr = cashAddrtoBase58 "bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e"
-      addr `shouldBe` Just "3LDsS579y7sruadqu11beEJoTjdFiFCdX4"
-    it "bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37" $ do
-      let addr = cashAddrtoBase58 "bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37"
-      addr `shouldBe` Just "31nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw"
-
-  describe "cashaddr larger test vectors" $
-      forM_ (zip [0..] vectors) $ \(i, vec) ->
-          it ("cashaddr test vector " <> show (i :: Int)) $ testCashAddr vec
+    describe "cashaddr checksum test vectors" $ do
+        it "prefix:x64nx6hz" $ do
+            let mpb = cash32decode "prefix:x64nx6hz"
+            mpb `shouldBe` Just ("prefix", "")
+        it "p:gpf8m4h7" $ do
+            let mpb = cash32decode "p:gpf8m4h7"
+            mpb `shouldBe` Just ("p", "")
+        it "bitcoincash:qpzry9x8gf2tvdw0s3jn54khce6mua7lcw20ayyn" $ do
+            let mpb =
+                    cash32decode
+                        "bitcoincash:qpzry9x8gf2tvdw0s3jn54khce6mua7lcw20ayyn"
+            mpb `shouldBe`
+                Just
+                    ( "bitcoincash"
+                    , "\NULD2\DC4\199BT\182\&5\207\132e:V\215\198u\190w\223")
+        it "bchtest:testnetaddress4d6njnut" $ do
+            let mpb = cash32decode "bchtest:testnetaddress4d6njnut"
+            mpb `shouldBe` Just ("bchtest", "^`\185\229}kG\152")
+        it "bchreg:555555555555555555555555555555555555555555555udxmlmrz" $ do
+            let mpb =
+                    cash32decode
+                        "bchreg:555555555555555555555555555555555555555555555udxmlmrz"
+            mpb `shouldBe`
+                Just
+                    ( "bchreg"
+                    , "\165)JR\148\165)JR\148\165)JR\148\165)JR\148\165)JR\148\165)J")
+    describe "cashaddr to base58 translation test vectors" $ do
+        it "1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu" $ do
+            let addr =
+                    addrToString bch <$>
+                    stringToAddr btc "1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu"
+            addr `shouldBe`
+                Just "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a"
+        it "1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR" $ do
+            let addr =
+                    addrToString bch <$>
+                    stringToAddr btc "1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR"
+            addr `shouldBe`
+                Just "bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy"
+        it "16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb" $ do
+            let addr =
+                    addrToString bch <$>
+                    stringToAddr btc "16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb"
+            addr `shouldBe`
+                Just "bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r"
+        it "3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC" $ do
+            let addr =
+                    addrToString bch <$>
+                    stringToAddr btc "3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC"
+            addr `shouldBe`
+                Just "bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq"
+        it "3LDsS579y7sruadqu11beEJoTjdFiFCdX4" $ do
+            let addr =
+                    addrToString bch <$>
+                    stringToAddr btc "3LDsS579y7sruadqu11beEJoTjdFiFCdX4"
+            addr `shouldBe`
+                Just "bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e"
+        it "31nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw" $ do
+            let addr =
+                    addrToString bch <$>
+                    stringToAddr btc "31nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw"
+            addr `shouldBe`
+                Just "bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37"
+    describe "base58 to cashaddr translation test vectors" $ do
+        it "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a" $ do
+            let addr =
+                    addrToString btc <$>
+                    stringToAddr
+                        bch
+                        "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a"
+            addr `shouldBe` Just "1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu"
+        it "bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy" $ do
+            let addr =
+                    addrToString btc <$>
+                    stringToAddr
+                        bch
+                        "bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy"
+            addr `shouldBe` Just "1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR"
+        it "bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r" $ do
+            let addr =
+                    addrToString btc <$>
+                    stringToAddr
+                        bch
+                        "bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r"
+            addr `shouldBe` Just "16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb"
+        it "bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq" $ do
+            let addr =
+                    addrToString btc <$>
+                    stringToAddr
+                        bch
+                        "bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq"
+            addr `shouldBe` Just "3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC"
+        it "bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e" $ do
+            let addr =
+                    addrToString btc <$>
+                    stringToAddr
+                        bch
+                        "bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e"
+            addr `shouldBe` Just "3LDsS579y7sruadqu11beEJoTjdFiFCdX4"
+        it "bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37" $ do
+            let addr =
+                    addrToString btc <$>
+                    stringToAddr
+                        bch
+                        "bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37"
+            addr `shouldBe` Just "31nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw"
+    describe "cashaddr larger test vectors" $
+        forM_ (zip [0 ..] vectors) $ \(i, vec) ->
+            it ("cashaddr test vector " <> show (i :: Int)) $ testCashAddr vec
 
 {- Various utilities -}
-
-base58ToCashAddr :: Text -> Maybe Text
-base58ToCashAddr b58 = toCashAddr <$> fromBase58 b58
-  where
-    fromBase58 = stringToAddr btc
-    toCashAddr a = addrToString a { getAddrNet = bch }
-
-cashAddrtoBase58 :: Text -> Maybe Text
-cashAddrtoBase58 c32 = toBase58 <$> fromCashAddr c32
-  where
-    fromCashAddr = stringToAddr bch
-    toBase58 a = addrToString a { getAddrNet = btc }
 
 testCashAddr :: (Int, CashVersion, Cash32, Text) -> Assertion
 testCashAddr (len, typ, addr, hex) = do
diff --git a/test/Network/Haskoin/AddressSpec.hs b/test/Network/Haskoin/AddressSpec.hs
--- a/test/Network/Haskoin/AddressSpec.hs
+++ b/test/Network/Haskoin/AddressSpec.hs
@@ -25,7 +25,7 @@
     describe "bch-regtest address" $ props bchRegTest
     describe "json serialization" $
         it "encodes and decodes address" $
-            forAll (arbitraryAddress net) (testCustom (addrFromJSON net))
+            forAll arbitraryAddress (testCustom (addrFromJSON net) (addrToJSON net))
 
 props :: Network -> Spec
 props net = do
@@ -38,10 +38,10 @@
             decodeBase58Check (encodeBase58Check bs) == Just bs
     it "encodes and decodes address" $
         property $
-        forAll (arbitraryAddress net) $ \a ->
-            stringToAddr net (addrToString a) == Just a
+        forAll arbitraryAddress $ \a ->
+            stringToAddr net (addrToString net a) == Just a
     it "shows and reads address" $
-        property $ forAll (arbitraryAddress net) $ \a -> read (show a) == a
+        property $ forAll arbitraryAddress $ \a -> read (show a) == a
 
 runVector :: (ByteString, Text, Text) -> Assertion
 runVector (bs, e, chk) = do
@@ -66,5 +66,5 @@
       )
     ]
 
-testCustom :: (ToJSON a, Eq a) => (Value -> Parser a) -> a -> Bool
-testCustom f x = parseMaybe f (toJSON x) == Just x
+testCustom :: Eq a => (Value -> Parser a) -> (a -> Value) -> a -> Bool
+testCustom f g x = parseMaybe f (g x) == Just x
diff --git a/test/Network/Haskoin/CryptoSpec.hs b/test/Network/Haskoin/CryptoSpec.hs
--- a/test/Network/Haskoin/CryptoSpec.hs
+++ b/test/Network/Haskoin/CryptoSpec.hs
@@ -136,10 +136,10 @@
 
 checkMatchingAddress :: Assertion
 checkMatchingAddress = do
-    assertBool "Key 1"  $ addr1  == addrToString (pubKeyAddr btc pub1)
-    assertBool "Key 2"  $ addr2  == addrToString (pubKeyAddr btc pub2)
-    assertBool "Key 1C" $ addr1C == addrToString (pubKeyAddr btc pub1C)
-    assertBool "Key 2C" $ addr2C == addrToString (pubKeyAddr btc pub2C)
+    assertBool "Key 1"  $ addr1  == addrToString btc (pubKeyAddr pub1)
+    assertBool "Key 2"  $ addr2  == addrToString btc (pubKeyAddr pub2)
+    assertBool "Key 1C" $ addr1C == addrToString btc (pubKeyAddr pub1C)
+    assertBool "Key 2C" $ addr2C == addrToString btc (pubKeyAddr pub2C)
 
 checkSignatures :: Hash256 -> Assertion
 checkSignatures h = do
diff --git a/test/Network/Haskoin/Keys/ExtendedSpec.hs b/test/Network/Haskoin/Keys/ExtendedSpec.hs
--- a/test/Network/Haskoin/Keys/ExtendedSpec.hs
+++ b/test/Network/Haskoin/Keys/ExtendedSpec.hs
@@ -49,16 +49,15 @@
     describe "extended keys" $ do
         let net = btc
         it "computes pubkey of a subkey is subkey of the pubkey" $
-            property $
-            forAll (arbitraryXPrvKey net) pubKeyOfSubKeyIsSubKeyOfPubKey
+            property $ forAll arbitraryXPrvKey pubKeyOfSubKeyIsSubKeyOfPubKey
         it "exports and imports extended private key" $
             property $
-            forAll (arbitraryXPrvKey net) $ \k ->
-                xPrvImport net (xPrvExport k) == Just k
+            forAll arbitraryXPrvKey $ \k ->
+                xPrvImport net (xPrvExport net k) == Just k
         it "exports and imports extended public key" $
             property $
-            forAll (arbitraryXPubKey net) $ \(_, k) ->
-                xPubImport net (xPubExport k) == Just k
+            forAll arbitraryXPubKey $ \(_, k) ->
+                xPubImport net (xPubExport net k) == Just k
         it "show and read derivation path" $
             property $ forAll arbitraryDerivPath $ \p -> read (show p) == p
         it "show and read hard derivation path" $
@@ -88,27 +87,28 @@
         it "read and show parsed path" $
             property $ forAll arbitraryParsedPath $ \p -> read (show p) == p
         it "encodes and decodes extended private key" $
-            forAll (arbitraryXPrvKey net) (testCustom (xPrvFromJSON net))
+            forAll
+                arbitraryXPrvKey
+                (testCustom (xPrvFromJSON net) (xPrvToJSON net))
         it "encodes and decodes extended public key" $
-            forAll (arbitraryXPubKey net) (testCustom (xPubFromJSON net) . snd)
+            forAll
+                arbitraryXPubKey
+                (testCustom (xPubFromJSON net) (xPubToJSON net) . snd)
         it "encodes and decodes derivation path" $
             forAll arbitraryDerivPath testID
         it "encodes and decodes parsed derivation path" $
             forAll arbitraryParsedPath testID
         it "encodes and decodes extended private key" $
             property $
-            forAll (arbitraryXPrvKey net) $
-            testPutGet (getXPrvKey net) putXPrvKey
+            forAll arbitraryXPrvKey $
+            testPutGet (getXPrvKey net) (putXPrvKey net)
         it "shows and reads extended private key" $
             property $
-            forAll (arbitraryXPrvKey net) $ \k -> do
-                let k' = read (show k)
-                k' {xPrvNet = xPrvNet k} `shouldBe` k
+            forAll arbitraryXPrvKey $ \k -> read (show k) `shouldBe` k
         it "shows and reads extended private key" $
             property $
-            forAll (arbitraryXPubKey net) $ \(_, k) -> do
-                let k' = read (show k)
-                k' {xPubNet = xPubNet k} `shouldBe` k
+            forAll arbitraryXPubKey $ \(prv, pub) ->
+                read (show (prv, pub)) `shouldBe` (prv, pub)
 
 testFromJsonPath :: Assertion
 testFromJsonPath =
@@ -293,17 +293,17 @@
     assertBool "xPrvID" $ encodeHex (S.encode $ xPrvID m) == head v
     assertBool "xPrvFP" $ encodeHex (S.encode $ xPrvFP m) == v !! 1
     assertBool "xPrvAddr" $
-        addrToString (xPubAddr $ deriveXPubKey m) == v !! 2
+        addrToString btc (xPubAddr $ deriveXPubKey m) == v !! 2
     assertBool "prvKey" $ encodeHex (getSecKey $ xPrvKey m) == v !! 3
-    assertBool "xPrvWIF" $ xPrvWif m == v !! 4
+    assertBool "xPrvWIF" $ xPrvWif btc m == v !! 4
     assertBool "pubKey" $
         encodeHex (exportPubKey True $ xPubKey $ deriveXPubKey m) == v !! 5
     assertBool "chain code" $ encodeHex (S.encode $ xPrvChain m) == v !! 6
     assertBool "Hex PubKey" $
-        encodeHex (runPut $ putXPubKey $ deriveXPubKey m) == v !! 7
-    assertBool "Hex PrvKey" $ encodeHex (runPut (putXPrvKey m)) == v !! 8
-    assertBool "Base58 PubKey" $ xPubExport (deriveXPubKey m) == v !! 9
-    assertBool "Base58 PrvKey" $ xPrvExport m == v !! 10
+        encodeHex (runPut $ putXPubKey btc $ deriveXPubKey m) == v !! 7
+    assertBool "Hex PrvKey" $ encodeHex (runPut (putXPrvKey btc m)) == v !! 8
+    assertBool "Base58 PubKey" $ xPubExport btc (deriveXPubKey m) == v !! 9
+    assertBool "Base58 PrvKey" $ xPrvExport btc m == v !! 10
 
 -- BIP 0032 Test Vectors
 -- https://en.bitcoin.it/wiki/BIP_0032_TestVectors
@@ -311,7 +311,7 @@
 xKeyVec :: [([Text], XPrvKey)]
 xKeyVec = zip xKeyResVec $ foldl f [m] der
     where f acc d = acc ++ [d $ last acc]
-          m   = makeXPrvKey btc $ fromJust $ decodeHex m0
+          m   = makeXPrvKey $ fromJust $ decodeHex m0
           der = [ flip hardSubKey 0
                 , flip prvSubKey 1
                 , flip hardSubKey 2
@@ -322,7 +322,7 @@
 xKeyVec2 :: [([Text], XPrvKey)]
 xKeyVec2 = zip xKeyResVec2 $ foldl f [m] der
     where f acc d = acc ++ [d $ last acc]
-          m   = makeXPrvKey btc $ fromJust $ decodeHex m1
+          m   = makeXPrvKey $ fromJust $ decodeHex m1
           der = [ flip prvSubKey 0
                 , flip hardSubKey 2147483647
                 , flip prvSubKey 1
@@ -514,8 +514,8 @@
     (A.decode . A.encode) (singleton ("object" :: String) x) ==
     Just (singleton ("object" :: String) x)
 
-testCustom :: (ToJSON a, Eq a) => (Value -> Parser a) -> a -> Bool
-testCustom f x = parseMaybe f (toJSON x) == Just x
+testCustom :: Eq a => (Value -> Parser a) -> (a -> Value) -> a -> Bool
+testCustom f g x = parseMaybe f (g x) == Just x
 
 testPutGet :: Eq a => Get a -> Putter a -> a -> Bool
 testPutGet g p a = runGet g (runPut (p a)) == Right a
diff --git a/test/Network/Haskoin/NetworkSpec.hs b/test/Network/Haskoin/NetworkSpec.hs
--- a/test/Network/Haskoin/NetworkSpec.hs
+++ b/test/Network/Haskoin/NetworkSpec.hs
@@ -1,15 +1,12 @@
 {-# LANGUAGE OverloadedStrings #-}
 module Network.Haskoin.NetworkSpec (spec) where
 
-import           Data.Aeson                as A
-import           Data.ByteString           (ByteString)
 import           Data.Maybe                (fromJust)
 import           Data.Serialize            as S
 import           Data.Text                 (Text)
 import           Data.Word                 (Word32)
 import           Network.Haskoin.Address
 import           Network.Haskoin.Constants
-import           Network.Haskoin.Crypto
 import           Network.Haskoin.Keys
 import           Network.Haskoin.Network
 import           Network.Haskoin.Test
@@ -100,7 +97,7 @@
   where
     f0 = bloomCreate 2 0.001 0 BloomUpdateAll
     f1 = bloomInsert f0 $ S.encode p
-    f2 = bloomInsert f1 $ S.encode $ getAddrHash160 $ pubKeyAddr btc p
+    f2 = bloomInsert f1 $ S.encode $ getAddrHash160 $ pubKeyAddr p
     k = fromJust $ fromWif btc "5Kg1gnAjaLfKiwhhPpGS3QfRg2m6awQvaj98JCZBZQ5SuS2F15C"
     p = derivePubKeyI k
     bs = fromJust $ decodeHex "038fc16b080000000000000001"
diff --git a/test/Network/Haskoin/ScriptSpec.hs b/test/Network/Haskoin/ScriptSpec.hs
--- a/test/Network/Haskoin/ScriptSpec.hs
+++ b/test/Network/Haskoin/ScriptSpec.hs
@@ -364,7 +364,7 @@
     b = do
         o <- s
         d <- eitherToMaybe $ decodeOutput o
-        return . addrToString $ payToScriptAddress btc d
+        return . addrToString btc $ payToScriptAddress d
 
 sigDecodeMap :: Network -> (Text, Int) -> Spec
 sigDecodeMap net (_, i) =
diff --git a/test/Network/Haskoin/TransactionSpec.hs b/test/Network/Haskoin/TransactionSpec.hs
--- a/test/Network/Haskoin/TransactionSpec.hs
+++ b/test/Network/Haskoin/TransactionSpec.hs
@@ -41,7 +41,7 @@
             forAll arbitraryTxHash $ \h -> fromString (cs $ txHashToHex h) == h
         it "building address tx" $
             property $
-            forAll (arbitraryAddress net) $
+            forAll arbitraryAddress $
             forAll (arbitrarySatoshi net) . testBuildAddrTx net
         it "guess transaction size" $
             property $ forAll (arbitraryAddrOnlyTxFull net) (testGuessSize net)
@@ -170,7 +170,7 @@
     | isScriptAddress a = Right (PayScriptHash (getAddrHash160 a)) == out
     | otherwise = undefined
   where
-    tx = buildAddrTx net [] [(addrToString a, v)]
+    tx = buildAddrTx net [] [(addrToString net a, v)]
     out =
         decodeOutputBS $
         scriptOutput $
