diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,18 @@
 # Changelog
 All notable changes to this project will be documented in this file.
 
+## [0.9.1.0] 2020-06-07
+### Added
+- SCALE codec implementation and tests 
+- SCALE codec example 
+
+### Changed
+- Supported GHC version: >=8.4.4
+- Imports optimized 
+
+### Removed
+- LTS-14 support
+
 ## [0.9.0.0] 2020-05-24
 ### Added
 - Experimental IPFS REST API client
diff --git a/examples/polkadot/package.yaml b/examples/polkadot/package.yaml
new file mode 100644
--- /dev/null
+++ b/examples/polkadot/package.yaml
@@ -0,0 +1,22 @@
+name:                example-polkadot
+version:             0.0.0.0
+synopsis:            Polkadot API example
+github:              "airalab/hs-web3"
+license:             BSD3
+author:              Alexander Krupenkin
+maintainer:          mail@akru.me
+copyright:           "(c) Alexander Krupenkin 2016"
+category:            Network
+
+dependencies:
+- base
+- web3 
+
+executables:
+  example-polkadot:
+    main:             Main.hs
+    source-dirs:      ./
+    ghc-options:
+    - -threaded
+    - -rtsopts
+    - -with-rtsopts=-N
diff --git a/examples/polkadot/stack.yaml b/examples/polkadot/stack.yaml
new file mode 100644
--- /dev/null
+++ b/examples/polkadot/stack.yaml
@@ -0,0 +1,70 @@
+# This file was automatically generated by 'stack init'
+#
+# Some commonly used options have been documented as comments in this file.
+# For advanced use and comprehensive documentation of the format, please see:
+# https://docs.haskellstack.org/en/stable/yaml_configuration/
+
+# Resolver to choose a 'specific' stackage snapshot or a compiler version.
+# A snapshot resolver dictates the compiler version and the set of packages
+# to be used for project dependencies. For example:
+#
+# resolver: lts-3.5
+# resolver: nightly-2015-09-21
+# resolver: ghc-7.10.2
+#
+# The location of a snapshot can be provided as a file or url. Stack assumes
+# a snapshot provided as a file might change, whereas a url resource does not.
+#
+# resolver: ./custom-snapshot.yaml
+# resolver: https://example.com/snapshots/2018-01-01.yaml
+resolver: lts-15.13
+
+# User packages to be built.
+# Various formats can be used as shown in the example below.
+#
+# packages:
+# - some-directory
+# - https://example.com/foo/bar/baz-0.0.2.tar.gz
+# - location:
+#    git: https://github.com/commercialhaskell/stack.git
+#    commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
+# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a
+#  subdirs:
+#  - auto-update
+#  - wai
+packages:
+- .
+- ../..
+# Dependency packages to be pulled from upstream that are not in the resolver
+# using the same syntax as the packages field.
+# (e.g., acme-missiles-0.3)
+extra-deps:
+- relapse-1.0.0.0@sha256:b89ea23189e07f377be4e2a4deccf3d6ba7f547ed8ad77e27b35d78801efd81c
+- vinyl-0.12.1@sha256:03f5e246fae2434250987bbfe708015dc6e23f60c20739c34738acde1383b96c
+
+# Override default flag values for local packages and extra-deps
+# flags: {}
+
+# Extra package databases containing global packages
+# extra-package-dbs: []
+
+# Control whether we use the GHC we find on the path
+# system-ghc: true
+#
+# Require a specific version of stack, using version ranges
+# require-stack-version: -any # Default
+# require-stack-version: ">=1.9"
+#
+# Override the architecture used by stack, especially useful on Windows
+# arch: i386
+# arch: x86_64
+#
+# Extra directories used by stack for building
+# extra-include-dirs: [/path/to/dir]
+# extra-lib-dirs: [/path/to/dir]
+#
+# Allow a newer minor version of GHC than the snapshot specifies
+# compiler-check: newer-minor
+nix:
+    packages:
+    - zlib
diff --git a/examples/scale/Main.hs b/examples/scale/Main.hs
new file mode 100644
--- /dev/null
+++ b/examples/scale/Main.hs
@@ -0,0 +1,30 @@
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DeriveGeneric  #-}
+module Main where
+
+import           Codec.Scale
+import           Codec.Scale.Skip
+import           Data.ByteArray.HexString (HexString)
+import           Data.Word                (Word32)
+import           Generics.SOP             (Generic)
+import qualified GHC.Generics             as GHC (Generic)
+
+data MyTransaction a = Tx
+    { from    :: Word32
+    , to      :: Word32
+    , balance :: Compact Integer
+    , note    :: Skip a
+    }
+    deriving (Show, Eq, GHC.Generic, Generic, Encode, Decode)
+
+main :: IO ()
+main = do
+    let alice = 42
+        bob = 15
+        my_tx = Tx { from = alice
+                   , to = bob
+                   , balance = Compact 1000000
+                   , note = Skip "Hello!"
+                   }
+    putStrLn "Encoded transaction:"
+    print (encode my_tx :: HexString)
diff --git a/examples/scale/package.yaml b/examples/scale/package.yaml
new file mode 100644
--- /dev/null
+++ b/examples/scale/package.yaml
@@ -0,0 +1,23 @@
+name:                example-scale
+version:             0.0.0.0
+synopsis:            SCALE codec example
+github:              "airalab/hs-web3"
+license:             BSD3
+author:              Alexander Krupenkin
+maintainer:          mail@akru.me
+copyright:           "(c) Alexander Krupenkin 2016"
+category:            Network
+
+dependencies:
+- base
+- web3 
+- generics-sop
+
+executables:
+  example-scale:
+    main:             Main.hs
+    source-dirs:      ./
+    ghc-options:
+    - -threaded
+    - -rtsopts
+    - -with-rtsopts=-N
diff --git a/examples/scale/stack.yaml b/examples/scale/stack.yaml
new file mode 100644
--- /dev/null
+++ b/examples/scale/stack.yaml
@@ -0,0 +1,70 @@
+# This file was automatically generated by 'stack init'
+#
+# Some commonly used options have been documented as comments in this file.
+# For advanced use and comprehensive documentation of the format, please see:
+# https://docs.haskellstack.org/en/stable/yaml_configuration/
+
+# Resolver to choose a 'specific' stackage snapshot or a compiler version.
+# A snapshot resolver dictates the compiler version and the set of packages
+# to be used for project dependencies. For example:
+#
+# resolver: lts-3.5
+# resolver: nightly-2015-09-21
+# resolver: ghc-7.10.2
+#
+# The location of a snapshot can be provided as a file or url. Stack assumes
+# a snapshot provided as a file might change, whereas a url resource does not.
+#
+# resolver: ./custom-snapshot.yaml
+# resolver: https://example.com/snapshots/2018-01-01.yaml
+resolver: lts-15.13
+
+# User packages to be built.
+# Various formats can be used as shown in the example below.
+#
+# packages:
+# - some-directory
+# - https://example.com/foo/bar/baz-0.0.2.tar.gz
+# - location:
+#    git: https://github.com/commercialhaskell/stack.git
+#    commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
+# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a
+#  subdirs:
+#  - auto-update
+#  - wai
+packages:
+- .
+- ../..
+# Dependency packages to be pulled from upstream that are not in the resolver
+# using the same syntax as the packages field.
+# (e.g., acme-missiles-0.3)
+extra-deps:
+- relapse-1.0.0.0@sha256:b89ea23189e07f377be4e2a4deccf3d6ba7f547ed8ad77e27b35d78801efd81c
+- vinyl-0.12.1@sha256:03f5e246fae2434250987bbfe708015dc6e23f60c20739c34738acde1383b96c
+
+# Override default flag values for local packages and extra-deps
+# flags: {}
+
+# Extra package databases containing global packages
+# extra-package-dbs: []
+
+# Control whether we use the GHC we find on the path
+# system-ghc: true
+#
+# Require a specific version of stack, using version ranges
+# require-stack-version: -any # Default
+# require-stack-version: ">=1.9"
+#
+# Override the architecture used by stack, especially useful on Windows
+# arch: i386
+# arch: x86_64
+#
+# Extra directories used by stack for building
+# extra-include-dirs: [/path/to/dir]
+# extra-lib-dirs: [/path/to/dir]
+#
+# Allow a newer minor version of GHC than the snapshot specifies
+# compiler-check: newer-minor
+nix:
+    packages:
+    - zlib
diff --git a/examples/token/package.yaml b/examples/token/package.yaml
new file mode 100644
--- /dev/null
+++ b/examples/token/package.yaml
@@ -0,0 +1,25 @@
+name:                example-erc20
+version:             0.0.0.0
+synopsis:            ERC20 token example
+github:              "airalab/hs-web3"
+license:             BSD3
+author:              Alexander Krupenkin
+maintainer:          mail@akru.me
+copyright:           "(c) Alexander Krupenkin 2016"
+category:            Network
+
+dependencies:
+- base
+- data-default
+- microlens
+- text
+- web3 
+
+executables:
+  example-erc20:
+    main:             Main.hs
+    source-dirs:      ./
+    ghc-options:
+    - -threaded
+    - -rtsopts
+    - -with-rtsopts=-N
diff --git a/examples/token/stack.yaml b/examples/token/stack.yaml
new file mode 100644
--- /dev/null
+++ b/examples/token/stack.yaml
@@ -0,0 +1,71 @@
+# This file was automatically generated by 'stack init'
+#
+# Some commonly used options have been documented as comments in this file.
+# For advanced use and comprehensive documentation of the format, please see:
+# https://docs.haskellstack.org/en/stable/yaml_configuration/
+
+# Resolver to choose a 'specific' stackage snapshot or a compiler version.
+# A snapshot resolver dictates the compiler version and the set of packages
+# to be used for project dependencies. For example:
+#
+# resolver: lts-3.5
+# resolver: nightly-2015-09-21
+# resolver: ghc-7.10.2
+#
+# The location of a snapshot can be provided as a file or url. Stack assumes
+# a snapshot provided as a file might change, whereas a url resource does not.
+#
+# resolver: ./custom-snapshot.yaml
+# resolver: https://example.com/snapshots/2018-01-01.yaml
+resolver: lts-15.13
+
+# User packages to be built.
+# Various formats can be used as shown in the example below.
+#
+# packages:
+# - some-directory
+# - https://example.com/foo/bar/baz-0.0.2.tar.gz
+# - location:
+#    git: https://github.com/commercialhaskell/stack.git
+#    commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
+# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a
+#  subdirs:
+#  - auto-update
+#  - wai
+packages:
+- .
+- ../..
+# Dependency packages to be pulled from upstream that are not in the resolver
+# using the same syntax as the packages field.
+# (e.g., acme-missiles-0.3)
+extra-deps:
+- relapse-1.0.0.0@sha256:b89ea23189e07f377be4e2a4deccf3d6ba7f547ed8ad77e27b35d78801efd81c
+- vinyl-0.12.1@sha256:03f5e246fae2434250987bbfe708015dc6e23f60c20739c34738acde1383b96c
+
+# Override default flag values for local packages and extra-deps
+# flags: {}
+
+# Extra package databases containing global packages
+# extra-package-dbs: []
+
+# Control whether we use the GHC we find on the path
+# system-ghc: true
+#
+# Require a specific version of stack, using version ranges
+# require-stack-version: -any # Default
+# require-stack-version: ">=1.9"
+#
+# Override the architecture used by stack, especially useful on Windows
+# arch: i386
+# arch: x86_64
+#
+# Extra directories used by stack for building
+# extra-include-dirs: [/path/to/dir]
+# extra-lib-dirs: [/path/to/dir]
+#
+# Allow a newer minor version of GHC than the snapshot specifies
+# compiler-check: newer-minor
+nix:
+    packages:
+    - zlib
+    - secp256k1
diff --git a/src/Codec/Scale.hs b/src/Codec/Scale.hs
new file mode 100644
--- /dev/null
+++ b/src/Codec/Scale.hs
@@ -0,0 +1,71 @@
+{-# LANGUAGE TypeFamilies #-}
+
+-- |
+-- Module      :  Codec.Scale.Class
+-- Copyright   :  Alexander Krupenkin 2016
+-- License     :  BSD3
+--
+-- Maintainer  :  mail@akru.me
+-- Stability   :  experimental
+-- Portability :  unportable
+--
+-- The SCALE (Simple Concatenated Aggregate Little-Endian) Codec is
+-- a lightweight, efficient, binary serialization and deserialization codec.
+--
+-- It is designed for high-performance, copy-free encoding and decoding of data in
+-- resource-constrained execution contexts, like the Substrate runtime. It is not
+-- self-describing in any way and assumes the decoding context has all type
+-- knowledge about the encoded data.
+--
+
+module Codec.Scale
+    ( encode
+    , decode
+    , encode'
+    , decode'
+    , Encode
+    , Decode
+    , module Core
+    ) where
+
+import           Data.ByteArray    (ByteArray, ByteArrayAccess, convert)
+import           Data.Serialize    (runGet, runPut)
+import           Generics.SOP      (Generic, Rep, from, to)
+
+import           Codec.Scale.Class (Decode (..), Encode (..), GDecode (..),
+                                    GEncode (..))
+import           Codec.Scale.Core  as Core
+
+-- | Encode datatype to SCALE format.
+encode :: (Encode a, ByteArray ba)
+       => a
+       -> ba
+{-# INLINE encode #-}
+encode = convert . runPut . put
+
+-- | Generic driven version of 'encode'
+encode' :: (Generic a,
+            Rep a ~ rep,
+            GEncode rep,
+            ByteArray ba)
+        => a
+        -> ba
+{-# INLINE encode' #-}
+encode' = convert . runPut . gPut . from
+
+-- | Decode datatype from SCALE format.
+decode :: (ByteArrayAccess ba, Decode a)
+       => ba
+       -> Either String a
+{-# INLINE decode #-}
+decode = runGet get . convert
+
+-- | Generic driven version of 'decode'
+decode' :: (Generic a,
+            Rep a ~ rep,
+            GDecode rep,
+            ByteArrayAccess ba)
+        => ba
+        -> Either String a
+{-# INLINE decode' #-}
+decode' = runGet (to <$> gGet) . convert
diff --git a/src/Codec/Scale/Class.hs b/src/Codec/Scale/Class.hs
new file mode 100644
--- /dev/null
+++ b/src/Codec/Scale/Class.hs
@@ -0,0 +1,60 @@
+{-# LANGUAGE DefaultSignatures #-}
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE TypeFamilies      #-}
+
+-- |
+-- Module      :  Codec.Scale.Class
+-- Copyright   :  Alexander Krupenkin 2016
+-- License     :  BSD3
+--
+-- Maintainer  :  mail@akru.me
+-- Stability   :  experimental
+-- Portability :  unportable
+--
+--
+--
+
+module Codec.Scale.Class where
+
+import           Data.Serialize (Get, Putter)
+import           Generics.SOP   (Generic, Rep, from, to)
+
+-- | A class for encoding datatypes to SCALE format.
+--
+-- If your compiler has support for the @DeriveGeneric@ and
+-- @DefaultSignatures@ language extensions (@ghc >= 7.2.1@),
+-- the 'put' method will have default generic implementations.
+--
+-- To use this option, simply add a @deriving 'Generic'@ clause
+-- to your datatype and declare a 'Encode' instance for it without
+-- giving a definition for 'put'.
+--
+class Encode a where
+    put :: Putter a
+
+    default put :: (Generic a, Rep a ~ rep, GEncode rep) => Putter a
+    put = gPut . from
+
+-- | A class for encoding generically composed datatypes to SCALE format.
+class GEncode a where
+    gPut :: Putter a
+
+-- | A class for decoding datatypes from SCALE format.
+--
+-- If your compiler has support for the @DeriveGeneric@ and
+-- @DefaultSignatures@ language extensions (@ghc >= 7.2.1@),
+-- the 'get' method will have default generic implementations.
+--
+-- To use this option, simply add a @deriving 'Generic'@ clause
+-- to your datatype and declare a 'Decode' instance for it without
+-- giving a definition for 'get'.
+--
+class Decode a where
+    get :: Get a
+
+    default get :: (Generic a, Rep a ~ rep, GDecode rep) => Get a
+    get = to <$> gGet
+
+-- | A class for decoding generically composed datatypes from SCALE format.
+class GDecode a where
+    gGet :: Get a
diff --git a/src/Codec/Scale/Compact.hs b/src/Codec/Scale/Compact.hs
new file mode 100644
--- /dev/null
+++ b/src/Codec/Scale/Compact.hs
@@ -0,0 +1,70 @@
+-- |
+-- Module      :  Codec.Scale.Compact
+-- Copyright   :  Alexander Krupenkin 2016
+-- License     :  BSD3
+--
+-- Maintainer  :  mail@akru.me
+-- Stability   :  experimental
+-- Portability :  noportable
+--
+-- Efficient general integer codec.
+--
+
+module Codec.Scale.Compact (Compact(..)) where
+
+import           Control.Monad      (replicateM)
+import           Data.Bits          (shiftL, shiftR, (.&.), (.|.))
+import           Data.List          (unfoldr)
+import           Data.Serialize.Get (getWord16le, getWord32le, getWord8,
+                                     lookAhead)
+import           Data.Serialize.Put (putWord16le, putWord32le, putWord8)
+
+import           Codec.Scale.Class  (Decode (..), Encode (..))
+
+-- | A "compact" or general integer encoding is sufficient for encoding
+-- large integers (up to 2**536) and is more efficient at encoding most
+-- values than the fixed-width version.
+newtype Compact a = Compact { unCompact :: a }
+  deriving (Eq, Ord)
+
+instance Show a => Show (Compact a) where
+    show = ("Compact " ++) . show . unCompact
+
+instance Integral a => Encode (Compact a) where
+    put (Compact x)
+      | n < 0 = error "negatives not supported by compact codec"
+      | n < 64 = singleByteMode
+      | n < 2^14 = twoByteMode
+      | n < 2^30 = fourByteMode
+      | n < 2^536 = bigIntegerMode
+      | otherwise = error $ "unable to encode " ++ show n ++ " as compact"
+      where
+        n = toInteger x
+        singleByteMode = putWord8 (fromIntegral x `shiftL` 2)
+        twoByteMode = putWord16le (fromIntegral x `shiftL` 2 .|. 1)
+        fourByteMode = putWord32le (fromIntegral x `shiftL` 2 .|. 2)
+        bigIntegerMode = do
+            let step 0 = Nothing
+                step i = Just (fromIntegral i, i `shiftR` 8)
+                unroll = unfoldr step n
+            putWord8 (fromIntegral (length unroll) `shiftL` 2 .|. 3)
+            mapM_ putWord8 unroll
+
+instance Integral a => Decode (Compact a) where
+    get = do
+        mode <- lookAhead ((3 .&.) <$> getWord8)
+        Compact <$> case mode of
+          0 -> fromIntegral <$> singleByteMode
+          1 -> fromIntegral <$> twoByteMode
+          2 -> fromIntegral <$> fourByteMode
+          3 -> bigIntegerMode
+          _ -> fail "unexpected prefix decoding compact number"
+      where
+        singleByteMode = flip shiftR 2 <$> getWord8
+        twoByteMode = flip shiftR 2 <$> getWord16le
+        fourByteMode = flip shiftR 2 <$> getWord32le
+        bigIntegerMode = do
+            let unstep b a = a `shiftL` 8 .|. fromIntegral b
+                roll = fromInteger . foldr unstep 0
+            len <- flip shiftR 2 <$> getWord8
+            roll <$> replicateM (fromIntegral len) getWord8
diff --git a/src/Codec/Scale/Core.hs b/src/Codec/Scale/Core.hs
new file mode 100644
--- /dev/null
+++ b/src/Codec/Scale/Core.hs
@@ -0,0 +1,197 @@
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+
+-- |
+-- Module      :  Codec.Scale.Core
+-- Copyright   :  Alexander Krupenkin 2016
+-- License     :  BSD3
+--
+-- Maintainer  :  mail@akru.me
+-- Stability   :  experimental
+-- Portability :  unportable
+--
+-- Particular core type instances.
+--
+
+module Codec.Scale.Core (Compact(..)) where
+
+import           Control.Monad       (replicateM)
+import           Data.Bit            (Bit, castFromWords8, cloneToWords8)
+import           Data.Int            (Int16, Int32, Int64, Int8)
+import           Data.Serialize.Get  (getInt16le, getInt32le, getInt64le,
+                                      getInt8, getWord16le, getWord32le,
+                                      getWord64le, getWord8)
+import           Data.Serialize.Put  (putInt16le, putInt32le, putInt64le,
+                                      putInt8, putWord16le, putWord32le,
+                                      putWord64le, putWord8)
+import           Data.Vector.Unboxed (Unbox, Vector)
+import qualified Data.Vector.Unboxed as V
+import           Data.Word           (Word16, Word32, Word64, Word8)
+import           Generics.SOP        ()
+
+import           Codec.Scale.Class   (Decode (..), Encode (..))
+import           Codec.Scale.Compact (Compact (..))
+import           Codec.Scale.Generic ()
+import           Codec.Scale.TH      (tupleInstances)
+
+--
+-- Boolean instance.
+--
+
+instance Encode Bool where
+    put False = putWord8 0
+    put True  = putWord8 1
+
+instance Decode Bool where
+    get = do x <- getWord8
+             case x of
+               0 -> return False
+               1 -> return True
+               _ -> fail "invalid boolean representation"
+
+--
+-- Integer instances.
+--
+
+instance Encode Word8 where
+    put = putWord8
+
+instance Decode Word8 where
+    get = getWord8
+
+instance Encode Word16 where
+    put = putWord16le
+
+instance Decode Word16 where
+    get = getWord16le
+
+instance Encode Word32 where
+    put = putWord32le
+
+instance Decode Word32 where
+    get = getWord32le
+
+instance Encode Word64 where
+    put = putWord64le
+
+instance Decode Word64 where
+    get = getWord64le
+
+instance Encode Int8 where
+    put = putInt8
+
+instance Decode Int8 where
+    get = getInt8
+
+instance Encode Int16 where
+    put = putInt16le
+
+instance Decode Int16 where
+    get = getInt16le
+
+instance Encode Int32 where
+    put = putInt32le
+
+instance Decode Int32 where
+    get = getInt32le
+
+instance Encode Int64 where
+    put = putInt64le
+
+instance Decode Int64 where
+    get = getInt64le
+
+--
+-- Option type instances.
+--
+
+-- Let's map `Maybe a` type to Rust `Option<T>`: Just -> Some, Nothing -> None
+
+instance Encode a => Encode (Maybe a) where
+    put (Just a) = putWord8 1 >> put a
+    put Nothing  = putWord8 0
+
+instance Decode a => Decode (Maybe a) where
+    get = do
+        x <- getWord8
+        case x of
+          0 -> return Nothing
+          1 -> Just <$> get
+          _ -> fail "unexpecded first byte decoding Option"
+
+-- Option<bool> is exception and it is always one byte
+
+instance {-# OVERLAPPING #-} Encode (Maybe Bool) where
+    put Nothing      = putWord8 0
+    put (Just False) = putWord8 1
+    put (Just True)  = putWord8 2
+
+instance {-# OVERLAPPING #-} Decode (Maybe Bool) where
+    get = do
+        x <- getWord8
+        case x of
+          0 -> return Nothing
+          1 -> return (Just False)
+          2 -> return (Just True)
+          _ -> fail "unexpecded first byte decoding OptionBool"
+
+--
+-- Result type isntances.
+--
+
+-- Let's map `Ether a b` type to Rust `Result<T, E>`: Left -> Error, Right -> Ok
+
+instance (Encode a, Encode b) => Encode (Either a b) where
+    put (Right a) = putWord8 0 >> put a
+    put (Left a)  = putWord8 1 >> put a
+
+instance (Decode a, Decode b) => Decode (Either a b) where
+    get = do
+        x <- getWord8
+        case x of
+          0 -> Right <$> get
+          1 -> Left <$> get
+          _ -> fail "unexpected first byte decoding Result"
+
+
+--
+-- Tuple type instances.
+--
+
+$(concat <$> mapM tupleInstances [2..20])
+
+--
+-- Vector type instances.
+--
+
+instance Encode a => Encode [a] where
+    put list = do
+        put (Compact $ length list)
+        mapM_ put list
+
+instance Decode a => Decode [a] where
+    get = do
+        len <- get
+        replicateM (unCompact len) get
+
+instance (Encode a, Unbox a) => Encode (Vector a) where
+    put vec = do
+        put (Compact $ V.length vec)
+        V.mapM_ put vec
+
+instance (Decode a, Unbox a) => Decode (Vector a) where
+    get = do
+        len <- get
+        V.replicateM (unCompact len) get
+
+instance {-# OVERLAPPING #-} Encode (Vector Bit) where
+    put vec = do
+        let encoded = cloneToWords8 vec
+        put (Compact $ V.length encoded)
+        V.mapM_ put encoded
+
+instance {-# OVERLAPPING #-} Decode (Vector Bit) where
+    get = do
+        len <- get
+        castFromWords8 <$> V.replicateM (unCompact len) get
diff --git a/src/Codec/Scale/Generic.hs b/src/Codec/Scale/Generic.hs
new file mode 100644
--- /dev/null
+++ b/src/Codec/Scale/Generic.hs
@@ -0,0 +1,89 @@
+{-# LANGUAGE BangPatterns      #-}
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE RankNTypes        #-}
+{-# LANGUAGE TypeFamilies      #-}
+{-# LANGUAGE TypeInType        #-}
+{-# LANGUAGE TypeOperators     #-}
+
+-- |
+-- Module      :  Codec.Scale.Generic
+-- Copyright   :  Alexander Krupenkin 2016
+-- License     :  BSD3
+--
+-- Maintainer  :  mail@akru.me
+-- Stability   :  experimental
+-- Portability :  unportable
+--
+-- This module defines generic codec instances for data structures (including tuples)
+-- and enums (tagged-unions in Rust).
+--
+
+module Codec.Scale.Generic () where
+
+import           Data.Serialize.Get (Get, getWord8)
+import           Data.Serialize.Put (PutM, putWord8)
+import           Data.Word          (Word8)
+import           Generics.SOP       (All, Compose, I (..), NP (..), NS (..),
+                                     SOP (..), unSOP, unZ)
+
+import           Codec.Scale.Class  (Decode (..), Encode (..), GDecode (..),
+                                     GEncode (..))
+
+-- Enum has multiple sum types.
+instance ( GEncode (NP f xs)
+         , GEncode (NP f ys)
+         , All (GEncode `Compose` NP f) xss
+         ) => GEncode (SOP f (xs ': ys ': xss)) where
+    gPut = go 0 . unSOP
+      where
+        go :: forall f as . All (GEncode `Compose` f) as => Word8 -> NS f as -> PutM ()
+        go !acc (Z x) = putWord8 acc >> gPut x
+        go !acc (S x) = go (acc + 1) x
+
+-- Structures has only one sum type.
+instance GEncode (NP f xs) => GEncode (SOP f '[xs]) where
+    gPut = gPut . unZ . unSOP
+
+-- Product serialization is just encode each field step by step.
+instance (Encode a, GEncode (NP I as)) => GEncode (NP I (a ': as)) where
+    gPut (I a :* as) = put a >> gPut as
+
+-- Finish when all fields handled.
+instance GEncode (NP I '[]) where
+    gPut _ = mempty
+
+-- | Enum parser definition.
+--
+-- The index of sum type to parse given as an argument.
+class EnumParser xs where
+    enumParser :: All (GDecode `Compose` NP f) xs => Word8 -> Get (NS (NP f) xs)
+
+-- Enumerate enum index, zero means that we reach the goal.
+instance EnumParser as => EnumParser (a ': as) where
+    enumParser !i | i > 0     = S <$> enumParser (i - 1)
+                  | otherwise = Z <$> gGet
+
+-- When index out of type scope raise the error.
+instance EnumParser '[] where
+    enumParser _ = fail "wrong prefix during enum decoding"
+
+-- Decode enum when multiple sum types.
+instance ( GDecode (NP f xs)
+         , GDecode (NP f ys)
+         , All (GDecode `Compose` NP f) xss
+         , EnumParser xss
+         ) => GDecode (SOP f (xs ': ys ': xss)) where
+    gGet = SOP <$> (enumParser =<< getWord8)
+
+-- Decode plain structure when only one sum type.
+instance GDecode (NP f as) => GDecode (SOP f '[as]) where
+    gGet = SOP . Z <$> gGet
+
+-- Decode each field in sequence.
+instance (Decode a, GDecode (NP I as)) => GDecode (NP I (a ': as)) where
+    gGet = (:*) <$> (I <$> get) <*> gGet
+
+-- Finish decoding when empty.
+instance GDecode (NP I '[]) where
+    gGet = return Nil
diff --git a/src/Codec/Scale/SingletonEnum.hs b/src/Codec/Scale/SingletonEnum.hs
new file mode 100644
--- /dev/null
+++ b/src/Codec/Scale/SingletonEnum.hs
@@ -0,0 +1,30 @@
+-- |
+-- Module      :  Codec.Scale.SingletonEnum
+-- Copyright   :  Alexander Krupenkin 2016
+-- License     :  BSD3
+--
+-- Maintainer  :  mail@akru.me
+-- Stability   :  experimental
+-- Portability :  noportable
+--
+-- This type helps to encode/decode singleton Rust enums like:
+-- `enum Enum { Data { some_data: u32 } }`
+--
+
+module Codec.Scale.SingletonEnum (SingletonEnum(..)) where
+
+import           Data.Serialize.Get (getWord8)
+import           Data.Serialize.Put (putWord8)
+
+import           Codec.Scale.Class  (Decode (..), Encode (..))
+
+-- | Haskell don't permit to make Rust-like enum type with only one element.
+-- For this reason it is impossible to make generic parser for singleton enum type.
+-- This type helps to parse Rust encoded singleton enums.
+newtype SingletonEnum a = SingletonEnum { unSingletonEnum :: a }
+
+instance Encode a => Encode (SingletonEnum a) where
+    put (SingletonEnum x) = putWord8 0 >> put x
+
+instance Decode a => Decode (SingletonEnum a) where
+    get = getWord8 >> (SingletonEnum <$> get)
diff --git a/src/Codec/Scale/Skip.hs b/src/Codec/Scale/Skip.hs
new file mode 100644
--- /dev/null
+++ b/src/Codec/Scale/Skip.hs
@@ -0,0 +1,32 @@
+-- |
+-- Module      :  Codec.Scale.Skip
+-- Copyright   :  Alexander Krupenkin 2016
+-- License     :  BSD3
+--
+-- Maintainer  :  mail@akru.me
+-- Stability   :  experimental
+-- Portability :  noportable
+--
+-- This type helps to skip fields in encoded data type.
+--
+
+module Codec.Scale.Skip (Skip(..)) where
+
+import           Data.Default      (Default (..))
+
+import           Codec.Scale.Class (Decode (..), Encode (..))
+
+-- | This type hide filed from encoding context.
+-- It's useful in cases when serialization impossible or not needed.
+-- For decoding wrapped type should have 'Default' instance.
+newtype Skip a = Skip { unSkip :: a }
+  deriving (Eq, Ord, Show)
+
+instance Encode (Skip a) where
+    put _ = return ()
+
+instance Default a => Decode (Skip a) where
+    get = return def
+
+instance Default a => Default (Skip a) where
+    def = Skip def
diff --git a/src/Codec/Scale/TH.hs b/src/Codec/Scale/TH.hs
new file mode 100644
--- /dev/null
+++ b/src/Codec/Scale/TH.hs
@@ -0,0 +1,31 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+-- |
+-- Module      :  Codec.Scale.TH
+-- Copyright   :  Alexander Krupenkin 2016
+-- License     :  BSD3
+--
+-- Maintainer  :  mail@akru.me
+-- Stability   :  experimental
+-- Portability :  noportable
+--
+-- It contains template haskell SCALE helper functions.
+--
+
+module Codec.Scale.TH where
+
+
+import           Control.Monad       (replicateM)
+import           Language.Haskell.TH (DecsQ, Type (VarT), appT, conT, cxt,
+                                      instanceD, newName, tupleT)
+
+import           Codec.Scale.Class   (Decode, Encode)
+
+tupleInstances :: Int -> DecsQ
+tupleInstances n = do
+    vars <- replicateM n $ newName "a"
+    let types = fmap (pure . VarT) vars
+    sequence $
+      [ instanceD (cxt $ map (appT $ conT ''Decode) types) (appT (conT ''Decode) (foldl appT (tupleT n) types)) []
+      , instanceD (cxt $ map (appT $ conT ''Encode) types) (appT (conT ''Encode) (foldl appT (tupleT n) types)) []
+      ]
diff --git a/src/Crypto/Ecdsa/Signature.hs b/src/Crypto/Ecdsa/Signature.hs
--- a/src/Crypto/Ecdsa/Signature.hs
+++ b/src/Crypto/Ecdsa/Signature.hs
@@ -35,7 +35,6 @@
                                               convert, singleton, takeView,
                                               view)
 import qualified Data.ByteArray              as BA (unpack)
-import           Data.Monoid                 ((<>))
 import           Data.Word                   (Word8)
 
 import           Crypto.Ecdsa.Utils          (exportKey)
diff --git a/src/Crypto/Ecdsa/Utils.hs b/src/Crypto/Ecdsa/Utils.hs
--- a/src/Crypto/Ecdsa/Utils.hs
+++ b/src/Crypto/Ecdsa/Utils.hs
@@ -18,7 +18,6 @@
 import           Crypto.PubKey.ECC.Types    (CurveName (SEC_p256k1), Point (..),
                                              getCurveByName)
 import           Data.ByteArray             (ByteArray, ByteArrayAccess)
-import           Data.Monoid                ((<>))
 
 -- | Import ECDSA private key from byte array.
 --
diff --git a/src/Crypto/Ethereum/Keyfile.hs b/src/Crypto/Ethereum/Keyfile.hs
--- a/src/Crypto/Ethereum/Keyfile.hs
+++ b/src/Crypto/Ethereum/Keyfile.hs
@@ -39,7 +39,6 @@
 import           Data.ByteArray           (ByteArray, ByteArrayAccess, convert)
 import qualified Data.ByteArray           as BA (drop, take, unpack)
 import           Data.Maybe               (fromJust)
-import           Data.Monoid              ((<>))
 import           Data.Text                (Text)
 import           Data.UUID.Types          (UUID)
 import           Data.UUID.Types.Internal (buildFromBytes)
diff --git a/src/Crypto/Ethereum/Signature.hs b/src/Crypto/Ethereum/Signature.hs
--- a/src/Crypto/Ethereum/Signature.hs
+++ b/src/Crypto/Ethereum/Signature.hs
@@ -25,7 +25,6 @@
 import qualified Data.ByteArray          as BA (length)
 import           Data.ByteString.Builder (intDec, toLazyByteString)
 import qualified Data.ByteString.Lazy    as LBS (toStrict)
-import           Data.Monoid             ((<>))
 import           Data.Word               (Word8)
 
 import           Crypto.Ecdsa.Signature  (pack, sign)
diff --git a/src/Crypto/Random/HmacDrbg.hs b/src/Crypto/Random/HmacDrbg.hs
--- a/src/Crypto/Random/HmacDrbg.hs
+++ b/src/Crypto/Random/HmacDrbg.hs
@@ -30,7 +30,6 @@
 import qualified Data.ByteArray  as BA (null, take)
 import qualified Data.ByteString as B (replicate)
 import           Data.Maybe      (fromJust)
-import           Data.Monoid     ((<>))
 import           Data.Word       (Word8)
 
 -- | HMAC Deterministic Random Bytes Generator.
diff --git a/src/Data/ByteArray/HexString.hs b/src/Data/ByteArray/HexString.hs
--- a/src/Data/ByteArray/HexString.hs
+++ b/src/Data/ByteArray/HexString.hs
@@ -22,8 +22,6 @@
 import           Data.ByteArray.Encoding (Base (Base16), convertFromBase,
                                           convertToBase)
 import           Data.ByteString         (ByteString)
-import           Data.Monoid             (Monoid, (<>))
-import           Data.Semigroup          (Semigroup)
 import           Data.String             (IsString (..))
 import           Data.Text               (Text)
 import           Data.Text.Encoding      (decodeUtf8, encodeUtf8)
diff --git a/src/Data/Solidity/Abi/Codec.hs b/src/Data/Solidity/Abi/Codec.hs
--- a/src/Data/Solidity/Abi/Codec.hs
+++ b/src/Data/Solidity/Abi/Codec.hs
@@ -63,4 +63,5 @@
             ByteArrayAccess ba)
         => ba
         -> Either String a
+{-# INLINE decode' #-}
 decode' = runGet (to <$> gAbiGet) . convert
diff --git a/src/Data/Solidity/Abi/Generic.hs b/src/Data/Solidity/Abi/Generic.hs
--- a/src/Data/Solidity/Abi/Generic.hs
+++ b/src/Data/Solidity/Abi/Generic.hs
@@ -26,7 +26,6 @@
 import qualified Data.ByteString.Lazy   as LBS
 import           Data.Int               (Int64)
 import qualified Data.List              as L
-import           Data.Monoid            ((<>))
 import           Data.Proxy             (Proxy (..))
 import           Data.Serialize         (Get, Put)
 import           Data.Serialize.Get     (bytesRead, lookAheadE, skip)
@@ -37,11 +36,11 @@
                                          GenericAbiGet (..), GenericAbiPut (..))
 import           Data.Solidity.Prim.Int (getWord256, putWord256)
 
-data EncodedValue =
-  EncodedValue { order    :: Int64
-               , offset   :: Maybe Int64
-               , encoding :: Put
-               }
+data EncodedValue = EncodedValue
+    { order    :: Int64
+    , offset   :: Maybe Int64
+    , encoding :: Put
+    }
 
 instance Eq EncodedValue where
   ev1 == ev2 = order ev1 == order ev2
diff --git a/src/Data/Solidity/Prim/Address.hs b/src/Data/Solidity/Prim/Address.hs
--- a/src/Data/Solidity/Prim/Address.hs
+++ b/src/Data/Solidity/Prim/Address.hs
@@ -43,7 +43,6 @@
 import qualified Data.ByteString.Char8    as C8 (drop, length, pack, unpack)
 import qualified Data.Char                as C (toLower, toUpper)
 import           Data.Default             (Default (..))
-import           Data.Monoid              ((<>))
 import           Data.String              (IsString (..))
 import           Data.Text.Encoding       as T (encodeUtf8)
 import           Generics.SOP             (Generic)
diff --git a/src/Data/Solidity/Prim/Bytes.hs b/src/Data/Solidity/Prim/Bytes.hs
--- a/src/Data/Solidity/Prim/Bytes.hs
+++ b/src/Data/Solidity/Prim/Bytes.hs
@@ -38,7 +38,6 @@
 import qualified Data.ByteArray.Sized    as S (take)
 import           Data.ByteString         (ByteString)
 import qualified Data.ByteString.Char8   as C8
-import           Data.Monoid             ((<>))
 import           Data.Proxy              (Proxy (..))
 import           Data.Serialize          (Get, Putter, getBytes, putByteString)
 import           Data.String             (IsString (..))
diff --git a/src/Language/Solidity/Abi.hs b/src/Language/Solidity/Abi.hs
--- a/src/Language/Solidity/Abi.hs
+++ b/src/Language/Solidity/Abi.hs
@@ -38,7 +38,6 @@
                                      SumEncoding (TaggedObject),
                                      ToJSON (toJSON), defaultOptions)
 import           Data.Aeson.TH      (deriveJSON)
-import           Data.Monoid        ((<>))
 import           Data.Text          (Text)
 import qualified Data.Text          as T (dropEnd, pack, take, unlines, unpack)
 import           Data.Text.Encoding (encodeUtf8)
@@ -51,13 +50,14 @@
 
 -- | Method argument
 data FunctionArg = FunctionArg
-  { funArgName :: Text
-  -- ^ Argument name
-  , funArgType :: Text
-  -- ^ Argument type
-  , funArgComponents :: Maybe [FunctionArg]
-  -- ^ Argument components for tuples
-  } deriving (Show, Eq, Ord)
+    { funArgName       :: Text
+    -- ^ Argument name
+    , funArgType       :: Text
+    -- ^ Argument type
+    , funArgComponents :: Maybe [FunctionArg]
+    -- ^ Argument components for tuples
+    }
+    deriving (Show, Eq, Ord)
 
 $(deriveJSON
     (defaultOptions {fieldLabelModifier = toLowerFirst . drop 6})
@@ -65,34 +65,42 @@
 
 -- | Event argument
 data EventArg = EventArg
-  { eveArgName    :: Text
-  -- ^ Argument name
-  , eveArgType    :: Text
-  -- ^ Argument type
-  , eveArgIndexed :: Bool
-  -- ^ Argument is indexed (e.g. placed on topics of event)
-  } deriving (Show, Eq, Ord)
+    { eveArgName    :: Text
+    -- ^ Argument name
+    , eveArgType    :: Text
+    -- ^ Argument type
+    , eveArgIndexed :: Bool
+    -- ^ Argument is indexed (e.g. placed on topics of event)
+    }
+    deriving (Show, Eq, Ord)
 
 $(deriveJSON
     (defaultOptions {fieldLabelModifier = toLowerFirst . drop 6})
     ''EventArg)
 
 -- | Elementrary contract interface item
-data Declaration
-  = DConstructor { conInputs :: [FunctionArg] }
-  -- ^ Contract constructor
-  | DFunction { funName     :: Text
-              , funConstant :: Bool
-              , funInputs   :: [FunctionArg]
-              , funOutputs  :: Maybe [FunctionArg] }
-  -- ^ Method
-  | DEvent { eveName      :: Text
-           , eveInputs    :: [EventArg]
-           , eveAnonymous :: Bool }
-  -- ^ Event
-  | DFallback { falPayable :: Bool }
-  -- ^ Fallback function
-  deriving Show
+data Declaration = DConstructor
+    { conInputs :: [FunctionArg]
+    -- ^ Contract constructor
+    }
+    | DFunction
+    { funName     :: Text
+    , funConstant :: Bool
+    , funInputs   :: [FunctionArg]
+    , funOutputs  :: Maybe [FunctionArg]
+    -- ^ Method
+    }
+    | DEvent
+    { eveName      :: Text
+    , eveInputs    :: [EventArg]
+    , eveAnonymous :: Bool
+    -- ^ Event
+    }
+    | DFallback
+    { falPayable :: Bool
+    -- ^ Fallback function
+    }
+    deriving Show
 
 instance Eq Declaration where
     (DConstructor a) == (DConstructor b) = length a == length b
@@ -172,7 +180,7 @@
     args [] = ""
     args [x] = funArgType x
     args (x:xs) = case funArgComponents x of
-      Nothing -> funArgType x <> "," <> args xs
+      Nothing   -> funArgType x <> "," <> args xs
       Just cmps -> "(" <> args cmps <> ")," <> args xs
 
 signature (DFallback _) = "()"
@@ -183,7 +191,7 @@
     args [] = ""
     args [x] = funArgType x
     args (x:xs) = case funArgComponents x of
-      Nothing -> funArgType x <> "," <> args xs
+      Nothing   -> funArgType x <> "," <> args xs
       Just cmps -> "(" <> args cmps <> ")," <> args xs
 
 signature (DEvent name inputs _) = name <> "(" <> args inputs <> ")"
@@ -209,17 +217,16 @@
 eventId = ("0x" <>) . sha3 . signature
 
 -- | Solidity types and parsers
-data SolidityType =
-    SolidityBool
-  | SolidityAddress
-  | SolidityUint Int
-  | SolidityInt Int
-  | SolidityString
-  | SolidityBytesN Int
-  | SolidityBytes
-  | SolidityTuple Int [SolidityType]
-  | SolidityVector [Int] SolidityType
-  | SolidityArray SolidityType
+data SolidityType = SolidityBool
+    | SolidityAddress
+    | SolidityUint Int
+    | SolidityInt Int
+    | SolidityString
+    | SolidityBytesN Int
+    | SolidityBytes
+    | SolidityTuple Int [SolidityType]
+    | SolidityVector [Int] SolidityType
+    | SolidityArray SolidityType
     deriving (Eq, Show)
 
 numberParser :: Parser Int
@@ -294,8 +301,8 @@
 parseSolidityFunctionArgType :: FunctionArg -> Either ParseError SolidityType
 parseSolidityFunctionArgType (FunctionArg _ typ mcmps) = case mcmps of
   Nothing -> parse solidityTypeParser "Solidity" typ
-  Just cmps -> 
-    SolidityTuple (length cmps) 
+  Just cmps ->
+    SolidityTuple (length cmps)
     <$>  mapM parseSolidityFunctionArgType cmps
 
 
diff --git a/src/Network/Ethereum/Account/Default.hs b/src/Network/Ethereum/Account/Default.hs
--- a/src/Network/Ethereum/Account/Default.hs
+++ b/src/Network/Ethereum/Account/Default.hs
@@ -23,7 +23,6 @@
 import           Control.Monad.Trans               (MonadTrans (..))
 import qualified Data.ByteArray                    as BA (convert)
 import           Data.Maybe                        (listToMaybe)
-import           Data.Monoid                       ((<>))
 import           Data.Proxy                        (Proxy (..))
 
 import           Data.Solidity.Abi.Codec           (decode, encode)
diff --git a/src/Network/Ethereum/Account/LocalKey.hs b/src/Network/Ethereum/Account/LocalKey.hs
--- a/src/Network/Ethereum/Account/LocalKey.hs
+++ b/src/Network/Ethereum/Account/LocalKey.hs
@@ -27,7 +27,6 @@
 import           Data.ByteArray                    (convert)
 import           Data.ByteString                   (empty)
 import           Data.Default                      (Default (..))
-import           Data.Monoid                       ((<>))
 import           Data.Proxy                        (Proxy (..))
 
 import           Crypto.Ethereum                   (derivePubKey, importKey)
diff --git a/src/Network/Ethereum/Account/Personal.hs b/src/Network/Ethereum/Account/Personal.hs
--- a/src/Network/Ethereum/Account/Personal.hs
+++ b/src/Network/Ethereum/Account/Personal.hs
@@ -25,7 +25,6 @@
 import           Control.Monad.Trans               (lift)
 import qualified Data.ByteArray                    as BA (convert)
 import           Data.Default                      (Default (..))
-import           Data.Monoid                       ((<>))
 import           Data.Proxy                        (Proxy (..))
 
 import           Data.Solidity.Abi.Codec           (decode, encode)
diff --git a/src/Network/Ethereum/Api/Types.hs b/src/Network/Ethereum/Api/Types.hs
--- a/src/Network/Ethereum/Api/Types.hs
+++ b/src/Network/Ethereum/Api/Types.hs
@@ -23,7 +23,6 @@
                                              defaultOptions, object, (.=))
 import           Data.Aeson.TH              (deriveJSON)
 import           Data.Default               (Default (..))
-import           Data.Monoid                ((<>))
 import           Data.Solidity.Prim.Address (Address)
 import           Data.String                (IsString (..))
 import qualified Data.Text                  as T (pack)
@@ -76,19 +75,21 @@
 
 -- | An object with sync status data.
 data SyncActive = SyncActive
-  { syncStartingBlock :: !Quantity
-  -- ^ QUANTITY - The block at which the import started (will only be reset, after the sync reached his head).
-  , syncCurrentBlock  :: !Quantity
-  -- ^ QUANTITY - The current block, same as eth_blockNumber.
-  , syncHighestBlock  :: !Quantity
-  -- ^ QUANTITY - The estimated highest block.
-  } deriving (Eq, Generic, Show)
+    { syncStartingBlock :: !Quantity
+    -- ^ QUANTITY - The block at which the import started (will only be reset, after the sync reached his head).
+    , syncCurrentBlock  :: !Quantity
+    -- ^ QUANTITY - The current block, same as eth_blockNumber.
+    , syncHighestBlock  :: !Quantity
+    -- ^ QUANTITY - The estimated highest block.
+    }
+    deriving (Eq, Generic, Show)
 
 $(deriveJSON (defaultOptions
     { fieldLabelModifier = toLowerFirst . drop 4 }) ''SyncActive)
 
 -- | Sync state pulled by low-level call 'eth_syncing'.
-data SyncingState = Syncing SyncActive | NotSyncing
+data SyncingState = Syncing SyncActive
+    | NotSyncing
     deriving (Eq, Generic, Show)
 
 instance FromJSON SyncingState where
@@ -98,47 +99,46 @@
 -- | Changes pulled by low-level call 'eth_getFilterChanges', 'eth_getLogs',
 -- and 'eth_getFilterLogs'
 data Change = Change
-  { changeLogIndex         :: !(Maybe Quantity)
-  -- ^ QUANTITY - integer of the log index position in the block. null when its pending log.
-  , changeTransactionIndex :: !(Maybe Quantity)
-  -- ^ QUANTITY - integer of the transactions index position log was created from. null when its pending log.
-  , changeTransactionHash  :: !(Maybe HexString)
-  -- ^ DATA, 32 Bytes - hash of the transactions this log was created from. null when its pending log.
-  , changeBlockHash        :: !(Maybe HexString)
-  -- ^ DATA, 32 Bytes - hash of the block where this log was in. null when its pending. null when its pending log.
-  , changeBlockNumber      :: !(Maybe Quantity)
-  -- ^ QUANTITY - the block number where this log was in. null when its pending. null when its pending log.
-  , changeAddress          :: !Address
-  -- ^ DATA, 20 Bytes - address from which this log originated.
-  , changeData             :: !HexString
-  -- ^ DATA - contains one or more 32 Bytes non-indexed arguments of the log.
-  , changeTopics           :: ![HexString]
-  -- ^ Array of DATA - Array of 0 to 4 32 Bytes DATA of indexed log arguments.
-  -- (In solidity: The first topic is the hash of the signature of the event
-  -- (e.g. Deposit(address, bytes32, uint256)), except you declared the event with
-  -- the anonymous specifier.)
-  } deriving (Eq, Show, Generic)
+    { changeLogIndex         :: !(Maybe Quantity)
+    -- ^ QUANTITY - integer of the log index position in the block. null when its pending log.
+    , changeTransactionIndex :: !(Maybe Quantity)
+    -- ^ QUANTITY - integer of the transactions index position log was created from. null when its pending log.
+    , changeTransactionHash  :: !(Maybe HexString)
+    -- ^ DATA, 32 Bytes - hash of the transactions this log was created from. null when its pending log.
+    , changeBlockHash        :: !(Maybe HexString)
+    -- ^ DATA, 32 Bytes - hash of the block where this log was in. null when its pending. null when its pending log.
+    , changeBlockNumber      :: !(Maybe Quantity)
+    -- ^ QUANTITY - the block number where this log was in. null when its pending. null when its pending log.
+    , changeAddress          :: !Address
+    -- ^ DATA, 20 Bytes - address from which this log originated.
+    , changeData             :: !HexString
+    -- ^ DATA - contains one or more 32 Bytes non-indexed arguments of the log.
+    , changeTopics           :: ![HexString]
+    -- ^ Array of DATA - Array of 0 to 4 32 Bytes DATA of indexed log arguments.
+    }
+    deriving (Eq, Show, Generic)
 
 $(deriveJSON (defaultOptions
     { fieldLabelModifier = toLowerFirst . drop 6 }) ''Change)
 
 -- | The contract call params.
 data Call = Call
-  { callFrom     :: !(Maybe Address)
-  -- ^ DATA, 20 Bytes - The address the transaction is send from.
-  , callTo       :: !(Maybe Address)
-  -- ^ DATA, 20 Bytes - (optional when creating new contract) The address the transaction is directed to.
-  , callGas      :: !(Maybe Quantity)
-  -- ^ QUANTITY - (optional, default: 3000000) Integer of the gas provided for the transaction execution. It will return unused gas.
-  , callGasPrice :: !(Maybe Quantity)
-  -- ^ QUANTITY - (optional, default: To-Be-Determined) Integer of the gasPrice used for each paid gas.
-  , callValue    :: !(Maybe Quantity)
-  -- ^ QUANTITY - (optional) Integer of the value sent with this transaction.
-  , callData     :: !(Maybe HexString)
-  -- ^ DATA - The compiled code of a contract OR the hash of the invoked method signature and encoded parameters.
-  , callNonce    :: !(Maybe Quantity)
-  -- ^ QUANTITY - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce.
-  } deriving (Eq, Show, Generic)
+    { callFrom     :: !(Maybe Address)
+    -- ^ DATA, 20 Bytes - The address the transaction is send from.
+    , callTo       :: !(Maybe Address)
+    -- ^ DATA, 20 Bytes - (optional when creating new contract) The address the transaction is directed to.
+    , callGas      :: !(Maybe Quantity)
+    -- ^ QUANTITY - (optional, default: 3000000) Integer of the gas provided for the transaction execution. It will return unused gas.
+    , callGasPrice :: !(Maybe Quantity)
+    -- ^ QUANTITY - (optional, default: To-Be-Determined) Integer of the gasPrice used for each paid gas.
+    , callValue    :: !(Maybe Quantity)
+    -- ^ QUANTITY - (optional) Integer of the value sent with this transaction.
+    , callData     :: !(Maybe HexString)
+    -- ^ DATA - The compiled code of a contract OR the hash of the invoked method signature and encoded parameters.
+    , callNonce    :: !(Maybe Quantity)
+    -- ^ QUANTITY - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce.
+    }
+    deriving (Eq, Show, Generic)
 
 $(deriveJSON (defaultOptions
     { fieldLabelModifier = toLowerFirst . drop 4
@@ -149,9 +149,9 @@
 
 -- | The state of blockchain for contract call.
 data DefaultBlock = BlockWithNumber Quantity
-                  | Earliest
-                  | Latest
-                  | Pending
+    | Earliest
+    | Latest
+    | Pending
     deriving (Eq, Show, Generic)
 
 instance ToJSON DefaultBlock where
@@ -160,21 +160,16 @@
 
 -- | Low-level event filter data structure.
 data Filter e = Filter
-  { filterAddress   :: !(Maybe [Address])
-  -- ^ DATA|Array, 20 Bytes - (optional) Contract address or a list of addresses from which logs should originate.
-  , filterFromBlock :: !DefaultBlock
-  -- ^ QUANTITY|TAG - (optional, default: "latest") Integer block number, or "latest" for the last mined block or "pending", "earliest" for not yet mined transactions.
-  , filterToBlock   :: !DefaultBlock
-  -- ^ QUANTITY|TAG - (optional, default: "latest") Integer block number, or "latest" for the last mined block or "pending", "earliest" for not yet mined transactions.
-  , filterTopics    :: !(Maybe [Maybe HexString])
-  -- ^ Array of DATA, - (optional) Array of 32 Bytes DATA topics. Topics are order-dependent. Each topic can also be an array of DATA with "or" options.
-  -- Topics are order-dependent. A transaction with a log with topics [A, B] will be matched by the following topic filters:
-  -- * [] "anything"
-  -- * [A] "A in first position (and anything after)"
-  -- * [null, B] "anything in first position AND B in second position (and anything after)"
-  -- * [A, B] "A in first position AND B in second position (and anything after)"
-  -- * [[A, B], [A, B]] "(A OR B) in first position AND (A OR B) in second position (and anything after)"
-  } deriving (Eq, Show, Generic)
+    { filterAddress   :: !(Maybe [Address])
+    -- ^ DATA|Array, 20 Bytes - (optional) Contract address or a list of addresses from which logs should originate.
+    , filterFromBlock :: !DefaultBlock
+    -- ^ QUANTITY|TAG - (optional, default: "latest") Integer block number, or "latest" for the last mined block or "pending", "earliest" for not yet mined transactions.
+    , filterToBlock   :: !DefaultBlock
+    -- ^ QUANTITY|TAG - (optional, default: "latest") Integer block number, or "latest" for the last mined block or "pending", "earliest" for not yet mined transactions.
+    , filterTopics    :: !(Maybe [Maybe HexString])
+    -- ^ Array of DATA, - (optional) Array of 32 Bytes DATA topics. Topics are order-dependent. Each topic can also be an array of DATA with "or" options.
+    }
+    deriving (Eq, Show, Generic)
 
 instance ToJSON (Filter e) where
     toJSON f = object [ "address"   .= filterAddress f
@@ -198,101 +193,104 @@
 
 -- | The Receipt of a Transaction
 data TxReceipt = TxReceipt
-  { receiptTransactionHash   :: !HexString
-  -- ^ DATA, 32 Bytes - hash of the transaction.
-  , receiptTransactionIndex  :: !Quantity
-  -- ^ QUANTITY - index of the transaction.
-  , receiptBlockHash         :: !(Maybe HexString)
-  -- ^ DATA, 32 Bytes - hash of the block where this transaction was in. null when its pending.
-  , receiptBlockNumber       :: !(Maybe Quantity)
-  -- ^ QUANTITY - block number where this transaction was in. null when its pending.
-  , receiptCumulativeGasUsed :: !Quantity
-  -- ^ QUANTITY - The total amount of gas used when this transaction was executed in the block.
-  , receiptGasUsed           :: !Quantity
-  -- ^ QUANTITY - The amount of gas used by this specific transaction alone.
-  , receiptContractAddress   :: !(Maybe Address)
-  -- ^ DATA, 20 Bytes - The contract address created, if the transaction was a contract creation, otherwise null.
-  , receiptLogs              :: ![Change]
-  -- ^ Array - Array of log objects, which this transaction generated.
-  , receiptLogsBloom         :: !HexString
-  -- ^ DATA, 256 Bytes - Bloom filter for light clients to quickly retrieve related logs.
-  , receiptStatus            :: !(Maybe Quantity)
-  -- ^ QUANTITY either 1 (success) or 0 (failure)
-  } deriving (Show, Generic)
+    { receiptTransactionHash   :: !HexString
+    -- ^ DATA, 32 Bytes - hash of the transaction.
+    , receiptTransactionIndex  :: !Quantity
+    -- ^ QUANTITY - index of the transaction.
+    , receiptBlockHash         :: !(Maybe HexString)
+    -- ^ DATA, 32 Bytes - hash of the block where this transaction was in. null when its pending.
+    , receiptBlockNumber       :: !(Maybe Quantity)
+    -- ^ QUANTITY - block number where this transaction was in. null when its pending.
+    , receiptCumulativeGasUsed :: !Quantity
+    -- ^ QUANTITY - The total amount of gas used when this transaction was executed in the block.
+    , receiptGasUsed           :: !Quantity
+    -- ^ QUANTITY - The amount of gas used by this specific transaction alone.
+    , receiptContractAddress   :: !(Maybe Address)
+    -- ^ DATA, 20 Bytes - The contract address created, if the transaction was a contract creation, otherwise null.
+    , receiptLogs              :: ![Change]
+    -- ^ Array - Array of log objects, which this transaction generated.
+    , receiptLogsBloom         :: !HexString
+    -- ^ DATA, 256 Bytes - Bloom filter for light clients to quickly retrieve related logs.
+    , receiptStatus            :: !(Maybe Quantity)
+    -- ^ QUANTITY either 1 (success) or 0 (failure)
+    }
+    deriving (Show, Generic)
 
 $(deriveJSON (defaultOptions
     { fieldLabelModifier = toLowerFirst . drop 7 }) ''TxReceipt)
 
 -- | Transaction information.
 data Transaction = Transaction
-  { txHash             :: !HexString
-  -- ^ DATA, 32 Bytes - hash of the transaction.
-  , txNonce            :: !Quantity
-  -- ^ QUANTITY - the number of transactions made by the sender prior to this one.
-  , txBlockHash        :: !(Maybe HexString)
-  -- ^ DATA, 32 Bytes - hash of the block where this transaction was in. null when its pending.
-  , txBlockNumber      :: !(Maybe Quantity)
-  -- ^ QUANTITY - block number where this transaction was in. null when its pending.
-  , txTransactionIndex :: !(Maybe Quantity)
-  -- ^ QUANTITY - integer of the transactions index position in the block. null when its pending.
-  , txFrom             :: !Address
-  -- ^ DATA, 20 Bytes - address of the sender.
-  , txTo               :: !(Maybe Address)
-  -- ^ DATA, 20 Bytes - address of the receiver. null when its a contract creation transaction.
-  , txValue            :: !Quantity
-  -- ^ QUANTITY - value transferred in Wei.
-  , txGasPrice         :: !Quantity
-  -- ^ QUANTITY - gas price provided by the sender in Wei.
-  , txGas              :: !Quantity
-  -- ^ QUANTITY - gas provided by the sender.
-  , txInput            :: !HexString
-  -- ^ DATA - the data send along with the transaction.
-  } deriving (Eq, Show, Generic)
+    { txHash             :: !HexString
+    -- ^ DATA, 32 Bytes - hash of the transaction.
+    , txNonce            :: !Quantity
+    -- ^ QUANTITY - the number of transactions made by the sender prior to this one.
+    , txBlockHash        :: !(Maybe HexString)
+    -- ^ DATA, 32 Bytes - hash of the block where this transaction was in. null when its pending.
+    , txBlockNumber      :: !(Maybe Quantity)
+    -- ^ QUANTITY - block number where this transaction was in. null when its pending.
+    , txTransactionIndex :: !(Maybe Quantity)
+    -- ^ QUANTITY - integer of the transactions index position in the block. null when its pending.
+    , txFrom             :: !Address
+    -- ^ DATA, 20 Bytes - address of the sender.
+    , txTo               :: !(Maybe Address)
+    -- ^ DATA, 20 Bytes - address of the receiver. null when its a contract creation transaction.
+    , txValue            :: !Quantity
+    -- ^ QUANTITY - value transferred in Wei.
+    , txGasPrice         :: !Quantity
+    -- ^ QUANTITY - gas price provided by the sender in Wei.
+    , txGas              :: !Quantity
+    -- ^ QUANTITY - gas provided by the sender.
+    , txInput            :: !HexString
+    -- ^ DATA - the data send along with the transaction.
+    }
+    deriving (Eq, Show, Generic)
 
 $(deriveJSON (defaultOptions
     { fieldLabelModifier = toLowerFirst . drop 2 }) ''Transaction)
 
 -- | Block information.
 data Block = Block
-  { blockNumber           :: !(Maybe Quantity)
-  -- ^ QUANTITY - the block number. null when its pending block.
-  , blockHash             :: !(Maybe HexString)
-  -- ^ DATA, 32 Bytes - hash of the block. null when its pending block.
-  , blockParentHash       :: !HexString
-  -- ^ DATA, 32 Bytes - hash of the parent block.
-  , blockNonce            :: !(Maybe HexString)
-  -- ^ DATA, 8 Bytes - hash of the generated proof-of-work. null when its pending block.
-  , blockSha3Uncles       :: !HexString
-  -- ^ DATA, 32 Bytes - SHA3 of the uncles data in the block.
-  , blockLogsBloom        :: !(Maybe HexString)
-  -- ^ DATA, 256 Bytes - the bloom filter for the logs of the block. null when its pending block.
-  , blockTransactionsRoot :: !HexString
-  -- ^ DATA, 32 Bytes - the root of the transaction trie of the block.
-  , blockStateRoot        :: !HexString
-  -- ^ DATA, 32 Bytes - the root of the final state trie of the block.
-  , blockReceiptRoot      :: !(Maybe HexString)
-  -- ^ DATA, 32 Bytes - the root of the receipts trie of the block.
-  , blockMiner            :: !Address
-  -- ^ DATA, 20 Bytes - the address of the beneficiary to whom the mining rewards were given.
-  , blockDifficulty       :: !Quantity
-  -- ^ QUANTITY - integer of the difficulty for this block.
-  , blockTotalDifficulty  :: !Quantity
-  -- ^ QUANTITY - integer of the total difficulty of the chain until this block.
-  , blockExtraData        :: !HexString
-  -- ^ DATA - the "extra data" field of this block.
-  , blockSize             :: !Quantity
-  -- ^ QUANTITY - integer the size of this block in bytes.
-  , blockGasLimit         :: !Quantity
-  -- ^ QUANTITY - the maximum gas allowed in this block.
-  , blockGasUsed          :: !Quantity
-  -- ^ QUANTITY - the total used gas by all transactions in this block.
-  , blockTimestamp        :: !Quantity
-  -- ^ QUANTITY - the unix timestamp for when the block was collated.
-  , blockTransactions     :: ![Transaction]
-  -- ^ Array of transaction objects.
-  , blockUncles           :: ![HexString]
-  -- ^ Array - Array of uncle hashes.
-  } deriving (Show, Generic)
+    { blockNumber           :: !(Maybe Quantity)
+    -- ^ QUANTITY - the block number. null when its pending block.
+    , blockHash             :: !(Maybe HexString)
+    -- ^ DATA, 32 Bytes - hash of the block. null when its pending block.
+    , blockParentHash       :: !HexString
+    -- ^ DATA, 32 Bytes - hash of the parent block.
+    , blockNonce            :: !(Maybe HexString)
+    -- ^ DATA, 8 Bytes - hash of the generated proof-of-work. null when its pending block.
+    , blockSha3Uncles       :: !HexString
+    -- ^ DATA, 32 Bytes - SHA3 of the uncles data in the block.
+    , blockLogsBloom        :: !(Maybe HexString)
+    -- ^ DATA, 256 Bytes - the bloom filter for the logs of the block. null when its pending block.
+    , blockTransactionsRoot :: !HexString
+    -- ^ DATA, 32 Bytes - the root of the transaction trie of the block.
+    , blockStateRoot        :: !HexString
+    -- ^ DATA, 32 Bytes - the root of the final state trie of the block.
+    , blockReceiptRoot      :: !(Maybe HexString)
+    -- ^ DATA, 32 Bytes - the root of the receipts trie of the block.
+    , blockMiner            :: !Address
+    -- ^ DATA, 20 Bytes - the address of the beneficiary to whom the mining rewards were given.
+    , blockDifficulty       :: !Quantity
+    -- ^ QUANTITY - integer of the difficulty for this block.
+    , blockTotalDifficulty  :: !Quantity
+    -- ^ QUANTITY - integer of the total difficulty of the chain until this block.
+    , blockExtraData        :: !HexString
+    -- ^ DATA - the "extra data" field of this block.
+    , blockSize             :: !Quantity
+    -- ^ QUANTITY - integer the size of this block in bytes.
+    , blockGasLimit         :: !Quantity
+    -- ^ QUANTITY - the maximum gas allowed in this block.
+    , blockGasUsed          :: !Quantity
+    -- ^ QUANTITY - the total used gas by all transactions in this block.
+    , blockTimestamp        :: !Quantity
+    -- ^ QUANTITY - the unix timestamp for when the block was collated.
+    , blockTransactions     :: ![Transaction]
+    -- ^ Array of transaction objects.
+    , blockUncles           :: ![HexString]
+    -- ^ Array - Array of uncle hashes.
+    }
+    deriving (Show, Generic)
 
 $(deriveJSON (defaultOptions
     { fieldLabelModifier = toLowerFirst . drop 5 }) ''Block)
diff --git a/src/Network/Ethereum/Contract/Event/MultiFilter.hs b/src/Network/Ethereum/Contract/Event/MultiFilter.hs
--- a/src/Network/Ethereum/Contract/Event/MultiFilter.hs
+++ b/src/Network/Ethereum/Contract/Event/MultiFilter.hs
@@ -60,7 +60,6 @@
 import           Data.Machine.Plan                      (PlanT, stop, yield)
 import           Data.Maybe                             (catMaybes, fromJust,
                                                          listToMaybe)
-import           Data.Monoid                            ((<>))
 import           Data.Tagged                            (Tagged (..))
 import           Data.Vinyl                             (Rec ((:&), RNil),
                                                          RecApplicative)
diff --git a/src/Network/Ethereum/Contract/TH.hs b/src/Network/Ethereum/Contract/TH.hs
--- a/src/Network/Ethereum/Contract/TH.hs
+++ b/src/Network/Ethereum/Contract/TH.hs
@@ -50,7 +50,6 @@
 import qualified Data.Char                        as Char
 import           Data.Default                     (Default (..))
 import           Data.List                        (group, sort, uncons)
-import           Data.Monoid                      ((<>))
 import           Data.Tagged                      (Tagged)
 import           Data.Text                        (Text)
 import qualified Data.Text                        as T
@@ -74,7 +73,9 @@
                                                    EventArg (..),
                                                    FunctionArg (..),
                                                    SolidityType (..), eventId,
-                                                   methodId, parseSolidityFunctionArgType, parseSolidityEventArgType)
+                                                   methodId,
+                                                   parseSolidityEventArgType,
+                                                   parseSolidityFunctionArgType)
 import           Network.Ethereum.Account.Class   (Account (..))
 import           Network.Ethereum.Api.Types       (DefaultBlock (..),
                                                    Filter (..), TxReceipt)
diff --git a/src/Network/Ethereum/Ens.hs b/src/Network/Ethereum/Ens.hs
--- a/src/Network/Ethereum/Ens.hs
+++ b/src/Network/Ethereum/Ens.hs
@@ -24,7 +24,6 @@
 import           Data.ByteArray.Sized                (unsafeFromByteArrayAccess)
 import           Data.ByteString                     (ByteString)
 import           Data.ByteString.Char8               (split)
-import           Data.Monoid                         ((<>))
 import           Lens.Micro                          ((.~))
 
 import           Data.Solidity.Prim                  (Address, BytesN)
diff --git a/src/Network/Polkadot/Api/Childstate.hs b/src/Network/Polkadot/Api/Childstate.hs
--- a/src/Network/Polkadot/Api/Childstate.hs
+++ b/src/Network/Polkadot/Api/Childstate.hs
@@ -15,8 +15,6 @@
 
 module Network.Polkadot.Api.Childstate where
 
-import           Data.Text                  (Text)
-
 import           Data.ByteArray.HexString   (HexString)
 import           Network.JsonRpc.TinyClient (JsonRpc (..))
 
diff --git a/src/Network/Polkadot/Api/Grandpa.hs b/src/Network/Polkadot/Api/Grandpa.hs
--- a/src/Network/Polkadot/Api/Grandpa.hs
+++ b/src/Network/Polkadot/Api/Grandpa.hs
@@ -16,7 +16,6 @@
 module Network.Polkadot.Api.Grandpa where
 
 import           Data.Aeson                 (Object)
-import           Data.Text                  (Text)
 
 import           Network.JsonRpc.TinyClient (JsonRpc (..))
 
diff --git a/unit/Codec/Scale/Test/CoreSpec.hs b/unit/Codec/Scale/Test/CoreSpec.hs
new file mode 100644
--- /dev/null
+++ b/unit/Codec/Scale/Test/CoreSpec.hs
@@ -0,0 +1,254 @@
+{-# LANGUAGE DeriveAnyClass      #-}
+{-# LANGUAGE DeriveGeneric       #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+-- |
+-- Module      :  Codec.Scale.Test.CoreSpec
+-- Copyright   :  Alexander Krupenkin 2016
+-- License     :  BSD3
+--
+-- Maintainer  :  mail@akru.me
+-- Stability   :  experimental
+-- Portability :  unportable
+--
+-- Ported to Haskell rust test spec:
+-- https://github.com/paritytech/parity-scale-codec/blob/master/tests/single_field_struct_encoding.rs
+--
+
+module Codec.Scale.Test.CoreSpec where
+
+import           Control.Monad         (forM_)
+import           Data.Bit              (castFromWords8)
+import           Data.Bits             (bit)
+import           Data.ByteString       (ByteString)
+import qualified Data.ByteString       as BS (length, unpack)
+import           Data.Int              (Int16, Int32, Int64, Int8)
+import           Data.Vector.Unboxed   (Vector)
+import qualified Data.Vector.Unboxed   as V (fromList)
+import           Data.Word             (Word16, Word32, Word64, Word8)
+import           Generics.SOP          (Generic)
+import qualified GHC.Generics          as GHC (Generic)
+import           Test.Hspec
+import           Test.Hspec.QuickCheck
+
+import           Codec.Scale
+
+data Unit = Unit
+    deriving (Eq, Show, GHC.Generic, Generic, Encode, Decode)
+
+data Indexed = Indexed Word32 Word64
+    deriving (Eq, Show, GHC.Generic, Generic, Encode, Decode)
+
+data Struct a b c = Struct
+    { _a :: a
+    , _b :: b
+    , _c :: c
+    }
+    deriving (Eq, Show, GHC.Generic, Generic, Encode, Decode)
+
+data StructWithPhantom a = StructWithPhantom
+    { a1 :: Word32
+    , b1 :: Word64
+    }
+    deriving (Eq, Show, GHC.Generic, Generic, Encode, Decode)
+
+type TestType = Struct Word32 Word64 (Vector Word8);
+
+data EnumType = A
+    | B Word32 Word64
+    | C
+    { a2 :: Word32
+    , b2 :: Word64
+    }
+    deriving (Eq, Show, GHC.Generic, Generic, Encode, Decode)
+
+data TestHasCompact a = TestHasCompact
+    { bar1 :: Compact a
+    }
+    deriving (Eq, Show, GHC.Generic, Generic, Encode, Decode)
+
+data TestHasCompactEnum a = Unnamed (Compact a)
+    | Named
+    { bar2 :: Compact a
+    }
+    | UnnamedCompact (Compact a)
+    | NamedCompact
+    { bar3 :: Compact a
+    }
+    deriving (Eq, Show, GHC.Generic, Generic, Encode, Decode)
+
+data TestGenericEnum = UnnamedGenericEnum (Compact Integer) (Vector Word16)
+    | NamedGenericEnum
+    { bar5 :: Compact Word64
+    , bar6 :: Word32
+    }
+    deriving (Eq, Show, GHC.Generic, Generic)
+
+data RecursiveVariant1 a = RecursiveVariant1
+    { payload1 :: a
+    , other1   :: [RecursiveVariant1 a]
+    }
+    deriving (Eq, Show, GHC.Generic, Generic, Encode, Decode)
+
+data RecursiveVariant2 a b n = RecursiveVariant2
+    { payload2 :: n
+    , other2   :: [Struct a b (RecursiveVariant1 n)]
+    }
+    deriving (Eq, Show, GHC.Generic, Generic, Encode, Decode)
+
+spec :: Spec
+spec = parallel $ do
+    describe "Regular types" $ do
+        prop "Bool" $ \(v :: Bool) -> decode (encode v :: ByteString) == Right v
+
+        prop "Option<Bool>" $ \(v :: Maybe Bool) -> decode (encode v :: ByteString) == Right v
+
+        prop "Result<Bool, Vector<u8>>" $ \v vec -> do
+            let success = Right v :: Either (Vector Word8) Bool
+                failure = Left (V.fromList vec) :: Either (Vector Word8) Bool
+            decode (encode success :: ByteString) == Right success
+                && decode (encode failure :: ByteString) == Right failure
+
+        prop "u64" $ \(v :: Word64) -> decode (encode v :: ByteString) == Right v
+        prop "u32" $ \(v :: Word32) -> decode (encode v :: ByteString) == Right v
+        prop "u16" $ \(v :: Word16) -> decode (encode v :: ByteString) == Right v
+        prop "u8" $ \(v :: Word8) -> decode (encode v :: ByteString) == Right v
+
+        prop "i64" $ \(v :: Int64) -> decode (encode v :: ByteString) == Right v
+        prop "i32" $ \(v :: Int32) -> decode (encode v :: ByteString) == Right v
+        prop "i16" $ \(v :: Int16) -> decode (encode v :: ByteString) == Right v
+        prop "i8" $ \(v :: Int8) -> decode (encode v :: ByteString) == Right v
+
+        prop "Compact<integer>" $ \(v :: Integer) -> decode (encode (Compact $ abs v) :: ByteString) == Right (Compact $ abs v)
+        prop "Compact<u64>" $ \(v :: Word64) -> decode (encode (Compact v) :: ByteString) == Right (Compact v)
+        prop "Compact<u32>" $ \(v :: Word32) -> decode (encode (Compact v) :: ByteString) == Right (Compact v)
+        prop "Compact<u16>" $ \(v :: Word16) -> decode (encode (Compact v) :: ByteString) == Right (Compact v)
+        prop "Compact<u8>" $ \(v :: Word8) -> decode (encode (Compact v) :: ByteString) == Right (Compact v)
+
+        prop "Vector<u64>" $ \(v :: [Word64]) -> decode (encode (V.fromList v) :: ByteString) == Right v
+        prop "Vector<u32>" $ \(v :: [Word32]) -> decode (encode (V.fromList v) :: ByteString) == Right v
+        prop "Vector<u16>" $ \(v :: [Word16]) -> decode (encode (V.fromList v) :: ByteString) == Right v
+        prop "Vector<u8>" $ \(v :: [Word8]) -> decode (encode (V.fromList v) :: ByteString) == Right v
+
+        prop "BitVec" $ \(v :: [Word8]) -> decode (encode $ castFromWords8 $ V.fromList v :: ByteString) == Right v
+
+        prop "List<u64>" $ \(v :: [Word64]) -> decode (encode v :: ByteString) == Right v
+        prop "List<u32>" $ \(v :: [Word32]) -> decode (encode v :: ByteString) == Right v
+        prop "List<u16>" $ \(v :: [Word16]) -> decode (encode v :: ByteString) == Right v
+        prop "List<u8>" $ \(v :: [Word8]) -> decode (encode v :: ByteString) == Right v
+
+    describe "Generic types" $ do
+        prop "unamed_enum" $ \v vec ->
+            let e = UnnamedGenericEnum (Compact $ abs v) (V.fromList vec)
+             in decode' (encode' e :: ByteString) == Right e
+        prop "named_struct_enum" $ \a b ->
+            let e = NamedGenericEnum (Compact a) b
+             in decode' (encode' e :: ByteString) == Right e
+
+    describe "Recursive types" $ do
+        prop "variant_1" $ \(n :: Word32) ->
+            let v = RecursiveVariant1 n [RecursiveVariant1 (n+1) []]
+             in decode (encode v :: ByteString) == Right v
+
+        prop "variant_2" $ \(a :: Word8) (b :: Word16) (n :: Word32) ->
+            let v = RecursiveVariant2 n [Struct a b (RecursiveVariant1 (n+1) [])]
+             in decode (encode v :: ByteString) == Right v
+
+    describe "SCALE Rust core tests" $ do
+        it "option_excheption_works" $ do
+            encode (Nothing :: Maybe Bool) `shouldBe` ("\0" :: ByteString)
+            encode (Just False) `shouldBe` ("\x01" :: ByteString)
+            encode (Just True) `shouldBe` ("\x02" :: ByteString)
+
+        it "should_work_for_simple_enum" $ do
+            -- Index modificator isn't support yet, skip codec test for A
+            let sb = B 1 2
+                sc = C 1 2
+                encoded_b = "\x01\x01\0\0\0\x02\0\0\0\0\0\0\0" :: ByteString
+                encoded_c = "\x02\x01\0\0\0\x02\0\0\0\0\0\0\0" :: ByteString
+
+            encode sc `shouldBe` encoded_c
+            encode sb `shouldBe` encoded_b
+
+            decode encoded_b `shouldBe` Right sb
+            decode encoded_c `shouldBe` Right sc
+            decode ("\x0a" :: ByteString) `shouldBe` (Left "Failed reading: wrong prefix during enum decoding\nEmpty call stack\n" :: Either String EnumType)
+
+        it "should_derive_encode" $ do
+            let v :: TestType
+                v = Struct 15 9 (V.fromList $ BS.unpack "Hello world")
+                v_encoded :: ByteString
+                v_encoded = "\x0f\0\0\0\x09\0\0\0\0\0\0\0\x2cHello world"
+            encode v `shouldBe` v_encoded
+            Right v `shouldBe` decode v_encoded
+
+        it "should_work_for_unit" $ do
+            encode Unit `shouldBe` ("" :: ByteString)
+            decode ("" :: ByteString) `shouldBe` Right Unit
+
+        it "should_work_for_indexed" $ do
+            let v = Indexed 1 2
+                v_encoded :: ByteString
+                v_encoded = "\x01\0\0\0\x02\0\0\0\0\0\0\0"
+            encode v `shouldBe` v_encoded
+            Right v `shouldBe` decode v_encoded
+
+        it "correct_error_for_indexed_0" $ do
+            let wrong = "\x08" :: ByteString
+            decode wrong `shouldBe` (Left "too few bytes\nFrom:\tdemandInput\n\n" :: Either String Indexed)
+
+        it "correct_error_for_indexed_1" $ do
+            let wrong = "\0\0\0\0\x01" :: ByteString
+            decode wrong `shouldBe` (Left "too few bytes\nFrom:\tdemandInput\n\n" :: Either String Indexed)
+
+        it "correct_error_for_enumtype" $ do
+            let wrong = "\x01" :: ByteString
+            decode wrong `shouldBe` (Left "too few bytes\nFrom:\tdemandInput\n\n" :: Either String EnumType)
+
+        it "correct_error_for_named_struct_1" $ do
+            let wrong = "\x01" :: ByteString
+            decode wrong `shouldBe` (Left "too few bytes\nFrom:\tdemandInput\n\n" :: Either String TestType)
+
+        it "correct_error_for_named_struct_2" $ do
+            let wrong = "\0\0\0\0\x01" :: ByteString
+            decode wrong `shouldBe` (Left "too few bytes\nFrom:\tdemandInput\n\n" :: Either String TestType)
+
+        let u64_TEST_COMPACT_VALUES :: [(Word64, Int)]
+            u64_TEST_COMPACT_VALUES =
+                [ (0, 1), (63, 1), (64, 2), (16383, 2)
+                , (16384, 4), (1073741823, 4), (1073741824, 5)
+                , (bit 32 - 1, 5), (bit 32, 6), (bit 40, 7)
+                , (bit 48, 8), (bit 56 - 1, 8), (bit 56, 9)
+                , (maxBound, 9)
+                ]
+
+        it "compact_works" $ forM_ u64_TEST_COMPACT_VALUES $ \(n, l) -> do
+            let encoded = encode (TestHasCompact $ Compact n)
+            BS.length encoded `shouldBe` l
+            decode encoded `shouldBe` Right (Compact n)
+
+        let u64_TEST_COMPACT_VALUES_FOR_ENUM :: [(Word64, Int)]
+            u64_TEST_COMPACT_VALUES_FOR_ENUM =
+                [ (0, 2), (63, 2), (64, 3), (16383, 3), (16384, 5)
+                , (1073741823, 5), (1073741824, 6), (bit 32 - 1, 6)
+                , (bit 32, 7), (bit 40, 8), (bit 48, 9), (bit 56 - 1, 9)
+                , (bit 56, 10), (maxBound, 10)
+                ]
+
+        it "enum_compact_works" $ forM_ u64_TEST_COMPACT_VALUES_FOR_ENUM $ \(x, l) -> do
+            let u = encode $ Unnamed (Compact x)
+            BS.length u `shouldBe` l
+            decode u `shouldBe` Right (Unnamed $ Compact x)
+
+            let n = encode $ Named (Compact x)
+            BS.length n `shouldBe` l
+            decode n `shouldBe` Right (Named $ Compact x)
+
+            let uc = encode $ UnnamedCompact (Compact x)
+            BS.length uc `shouldBe` l
+            decode uc `shouldBe` Right (UnnamedCompact $ Compact x)
+
+            let nc = encode $ NamedCompact (Compact x)
+            BS.length nc `shouldBe` l
+            decode nc `shouldBe` Right (NamedCompact $ Compact x)
diff --git a/unit/Codec/Scale/Test/SingleFieldStructSpec.hs b/unit/Codec/Scale/Test/SingleFieldStructSpec.hs
new file mode 100644
--- /dev/null
+++ b/unit/Codec/Scale/Test/SingleFieldStructSpec.hs
@@ -0,0 +1,106 @@
+{-# LANGUAGE DeriveGeneric              #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE OverloadedStrings          #-}
+
+-- |
+-- Module      :  Codec.Scale.Test.SingleFieldStructSpec
+-- Copyright   :  Alexander Krupenkin 2016
+-- License     :  BSD3
+--
+-- Maintainer  :  mail@akru.me
+-- Stability   :  experimental
+-- Portability :  unportable
+--
+-- Ported to Haskell rust test spec:
+-- https://github.com/paritytech/parity-scale-codec/blob/master/tests/single_field_struct_encoding.rs
+--
+
+module Codec.Scale.Test.SingleFieldStructSpec where
+
+import           Data.ByteString  as BS (pack)
+import           Data.Default     (def)
+import           Data.Word        (Word32, Word64)
+import           Generics.SOP     (Generic)
+import qualified GHC.Generics     as GHC (Generic)
+import           Test.Hspec
+
+import           Codec.Scale
+import           Codec.Scale.Skip
+
+newtype S = S { x1 :: Word32 }
+    deriving (Eq, Ord, Show, Encode, Decode)
+
+data SSkip = SSkip
+    { s1 :: Skip Word32
+    , x2 :: Word32
+    , s2 :: Skip Word32
+    }
+    deriving (Eq, Ord, Show, GHC.Generic)
+
+instance Generic SSkip
+instance Encode SSkip
+instance Decode SSkip
+
+newtype Sc = Sc { x3 :: Compact Word32 }
+    deriving (Eq, Ord, Show, Encode, Decode)
+
+newtype U = U Word32
+    deriving (Eq, Ord, Show, Enum, Num, Real, Integral, Encode, Decode)
+
+newtype U2 = U2 { a :: Word64 }
+    deriving (Eq, Ord, Show, Encode, Decode)
+
+data USkip = USkip (Skip Word32) Word32 (Skip Word32)
+    deriving (Eq, Ord, Show, GHC.Generic)
+
+instance Generic USkip
+instance Encode USkip
+instance Decode USkip
+
+newtype Uc = Uc (Compact Word32)
+    deriving (Eq, Ord, Show, Encode, Decode)
+
+newtype Ucas = Ucas (Compact U)
+    deriving (Eq, Ord, Show, Encode, Decode)
+
+spec :: Spec
+spec = parallel $ do
+    describe "Single field struct encoding" $ do
+        let x = 3
+            s = S x
+            s_skip = SSkip def x def
+            sc = Sc (Compact x)
+            u = U x
+            u_skip = USkip def x def
+            uc = Uc (Compact x)
+            ucom = Compact u
+            ucas = Ucas (Compact u)
+
+            s_encoded = BS.pack [3, 0, 0, 0]
+            s_skip_encoded = BS.pack [3, 0, 0, 0]
+            sc_encoded = BS.pack [12]
+            u_encoded = BS.pack [3, 0, 0, 0]
+            u_skip_encoded = BS.pack [3, 0, 0, 0]
+            uc_encoded = BS.pack [12]
+            ucom_encoded = BS.pack [12]
+            ucas_encoded = BS.pack [12]
+
+        it "encoding" $ do
+            encode s `shouldBe` s_encoded
+            encode s_skip `shouldBe` s_skip_encoded
+            encode sc `shouldBe` sc_encoded
+            encode u `shouldBe` u_encoded
+            encode u_skip `shouldBe` u_skip_encoded
+            encode uc `shouldBe` uc_encoded
+            encode ucom `shouldBe` ucom_encoded
+            encode ucas `shouldBe` ucas_encoded
+
+        it "decoding" $ do
+            Right s `shouldBe` decode s_encoded
+            Right s_skip `shouldBe` decode s_skip_encoded
+            Right sc `shouldBe` decode sc_encoded
+            Right u `shouldBe`  decode u_encoded
+            Right u_skip `shouldBe` decode u_skip_encoded
+            Right uc `shouldBe` decode uc_encoded
+            Right ucom `shouldBe` decode ucom_encoded
+            Right ucas `shouldBe` decode ucas_encoded
diff --git a/unit/Codec/Scale/Test/SkipSpec.hs b/unit/Codec/Scale/Test/SkipSpec.hs
new file mode 100644
--- /dev/null
+++ b/unit/Codec/Scale/Test/SkipSpec.hs
@@ -0,0 +1,81 @@
+{-# LANGUAGE DeriveAnyClass    #-}
+{-# LANGUAGE DeriveGeneric     #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+-- |
+-- Module      :  Codec.Scale.Test.SkipSpec
+-- Copyright   :  Alexander Krupenkin 2016
+-- License     :  BSD3
+--
+-- Maintainer  :  mail@akru.me
+-- Stability   :  experimental
+-- Portability :  unportable
+--
+-- Ported to Haskell rust test spec:
+-- https://github.com/paritytech/parity-scale-codec/blob/master/tests/skip.rs
+--
+
+module Codec.Scale.Test.SkipSpec where
+
+import           Data.Default              (Default)
+import           Data.Word                 (Word32)
+import           Generics.SOP              (Generic)
+import qualified GHC.Generics              as GHC (Generic)
+import           Test.Hspec
+
+import           Codec.Scale
+import           Codec.Scale.SingletonEnum
+import           Codec.Scale.Skip
+import           Data.ByteArray.HexString
+
+data UncodecType = UncodecType
+    deriving (Eq, Ord, Show, GHC.Generic, Default)
+
+-- Implementing A constructor is impossible
+data EnumType = B
+    { _b1 :: Skip UncodecType
+    , b2  :: Word32
+    }
+    | C (Skip UncodecType) Word32
+    deriving (Eq, Ord, Show, GHC.Generic, Generic, Encode, Decode)
+
+
+data StructNamed = StructNamed
+    { a :: Skip UncodecType
+    , b :: Word32
+    }
+    deriving (Eq, Ord, Show, GHC.Generic, Generic, Encode, Decode)
+
+data StructUnnamed = StructUnnamed (Skip UncodecType) Word32
+    deriving (Eq, Ord, Show, GHC.Generic, Generic, Encode, Decode)
+
+data NamedStruct = NamedStruct
+    { some_named :: Word32
+    , ignore     :: Skip (Maybe Word32)
+    }
+    deriving (Eq, Ord, Show, GHC.Generic, Generic, Encode, Decode)
+
+spec :: Spec
+spec = parallel $ do
+    describe "Type encoding modificators" $ do
+        it "enum_struct_test" $ do
+            let eb = B { _b1 = Skip UncodecType, b2 = 1 }
+                ec = C (Skip UncodecType) 1
+                sn = StructNamed { a = Skip UncodecType, b = 1 }
+                su = StructUnnamed (Skip UncodecType) 1
+
+            let eb_encoded = encode eb :: HexString
+            let ec_encoded = encode ec :: HexString
+            let sn_encoded = encode sn :: HexString
+            let su_encoded = encode su :: HexString
+
+            decode eb_encoded `shouldBe` Right eb
+            decode ec_encoded `shouldBe` Right ec
+            decode sn_encoded `shouldBe` Right sn
+            decode su_encoded `shouldBe` Right su
+
+        it "skip_enum_struct_inner_variant" $ do
+            let struct = NamedStruct { some_named = 1, ignore = Skip (Just 1) }
+                single = SingletonEnum struct
+                encoded = "0x0001000000" :: HexString
+            encode single `shouldBe` encoded
diff --git a/web3.cabal b/web3.cabal
--- a/web3.cabal
+++ b/web3.cabal
@@ -1,556 +1,608 @@
-cabal-version: 2.2
-
--- This file has been generated from package.yaml by hpack version 0.33.0.
---
--- see: https://github.com/sol/hpack
---
--- hash: 916c1e312da75f2dfe78e0e6a6613adc7b6a4e68a1da8d57e82be1facc937203
-
-name:           web3
-version:        0.9.0.0
-synopsis:       Web3 API for Haskell.
-description:    Client library for Third Generation of Web.
-category:       Network
-homepage:       https://github.com/airalab/hs-web3#readme
-bug-reports:    https://github.com/airalab/hs-web3/issues
-author:         Alexander Krupenkin
-maintainer:     mail@akru.me
-copyright:      (c) Alexander Krupenkin 2016
-license:        BSD-3-Clause
-license-file:   LICENSE
-build-type:     Simple
-extra-source-files:
-    README.md
-    CHANGELOG.md
-    stack.yaml
-    examples/token/ERC20.hs
-    examples/token/ERC20.json
-    examples/token/Main.hs
-    examples/polkadot/Main.hs
-    test/contracts/Registry.json
-    test/contracts/SimpleStorage.json
-    test/contracts/ComplexStorage.json
-    test/contracts/Linearization.json
-
-source-repository head
-  type: git
-  location: https://github.com/airalab/hs-web3
-
-flag compiler
-  description: Enable Solidity compiler
-  manual: True
-  default: False
-
-flag debug
-  description: Enable debug compiler options
-  manual: True
-  default: False
-
-library
-  exposed-modules:
-      Crypto.Ecdsa.Signature
-      Crypto.Ecdsa.Utils
-      Crypto.Ethereum
-      Crypto.Ethereum.Keyfile
-      Crypto.Ethereum.Signature
-      Crypto.Ethereum.Utils
-      Crypto.Random.HmacDrbg
-      Data.ByteArray.HexString
-      Data.Solidity.Abi
-      Data.Solidity.Abi.Codec
-      Data.Solidity.Abi.Generic
-      Data.Solidity.Event
-      Data.Solidity.Event.Internal
-      Data.Solidity.Prim
-      Data.Solidity.Prim.Address
-      Data.Solidity.Prim.Bool
-      Data.Solidity.Prim.Bytes
-      Data.Solidity.Prim.Int
-      Data.Solidity.Prim.List
-      Data.Solidity.Prim.String
-      Data.Solidity.Prim.Tagged
-      Data.Solidity.Prim.Tuple
-      Data.Solidity.Prim.Tuple.TH
-      Data.String.Extra
-      Language.Solidity.Abi
-      Network.Ethereum
-      Network.Ethereum.Account
-      Network.Ethereum.Account.Class
-      Network.Ethereum.Account.Default
-      Network.Ethereum.Account.Internal
-      Network.Ethereum.Account.LocalKey
-      Network.Ethereum.Account.Personal
-      Network.Ethereum.Account.Safe
-      Network.Ethereum.Api.Eth
-      Network.Ethereum.Api.Net
-      Network.Ethereum.Api.Personal
-      Network.Ethereum.Api.Types
-      Network.Ethereum.Api.Web3
-      Network.Ethereum.Chain
-      Network.Ethereum.Contract
-      Network.Ethereum.Contract.Event
-      Network.Ethereum.Contract.Event.Common
-      Network.Ethereum.Contract.Event.MultiFilter
-      Network.Ethereum.Contract.Event.SingleFilter
-      Network.Ethereum.Contract.Method
-      Network.Ethereum.Contract.TH
-      Network.Ethereum.Ens
-      Network.Ethereum.Ens.PublicResolver
-      Network.Ethereum.Ens.Registry
-      Network.Ethereum.Transaction
-      Network.Ethereum.Unit
-      Network.Ipfs.Api.Bitswap
-      Network.Ipfs.Api.Block
-      Network.Ipfs.Api.Bootstrap
-      Network.Ipfs.Api.Cid
-      Network.Ipfs.Api.Config
-      Network.Ipfs.Api.Core
-      Network.Ipfs.Api.Dag
-      Network.Ipfs.Api.Dht
-      Network.Ipfs.Api.Files
-      Network.Ipfs.Api.Internal
-      Network.Ipfs.Api.Internal.Call
-      Network.Ipfs.Api.Internal.Stream
-      Network.Ipfs.Api.Key
-      Network.Ipfs.Api.Log
-      Network.Ipfs.Api.Object
-      Network.Ipfs.Api.Pin
-      Network.Ipfs.Api.Pubsub
-      Network.Ipfs.Api.Repo
-      Network.Ipfs.Api.Stats
-      Network.Ipfs.Api.Swarm
-      Network.Ipfs.Api.Types
-      Network.Ipfs.Api.Types.Stream
-      Network.Ipfs.Client
-      Network.JsonRpc.TinyClient
-      Network.Polkadot.Api.Account
-      Network.Polkadot.Api.Author
-      Network.Polkadot.Api.Babe
-      Network.Polkadot.Api.Chain
-      Network.Polkadot.Api.Childstate
-      Network.Polkadot.Api.Contracts
-      Network.Polkadot.Api.Engine
-      Network.Polkadot.Api.Grandpa
-      Network.Polkadot.Api.Offchain
-      Network.Polkadot.Api.Payment
-      Network.Polkadot.Api.Rpc
-      Network.Polkadot.Api.State
-      Network.Polkadot.Api.System
-      Network.Polkadot.Api.Types
-      Network.Web3
-      Network.Web3.Provider
-  other-modules:
-      Paths_web3
-  autogen-modules:
-      Paths_web3
-  hs-source-dirs:
-      src
-  ghc-options: -funbox-strict-fields -Wduplicate-exports -Whi-shadowing -Widentities -Woverlapping-patterns -Wpartial-type-signatures -Wunrecognised-pragmas -Wtyped-holes -Wincomplete-patterns -Wincomplete-uni-patterns -Wmissing-fields -Wmissing-methods -Wmissing-exported-signatures -Wmissing-monadfail-instances -Wmissing-signatures -Wname-shadowing -Wunused-binds -Wunused-top-binds -Wunused-local-binds -Wunused-pattern-binds -Wunused-imports -Wunused-matches -Wunused-foralls -Wtabs
-  build-depends:
-      OneTuple >=0.2.1 && <0.3
-    , aeson >=1.2.2.0 && <1.5
-    , async >=2.1.1.1 && <2.3
-    , attoparsec >=0.13.2.1 && <0.14
-    , base >4.10 && <4.14
-    , base58string >=0.10.0 && <0.11
-    , basement >=0.0.4 && <0.1
-    , bytestring >=0.10.8.1 && <0.11
-    , cereal >=0.5.4.0 && <0.6
-    , cryptonite >=0.23 && <0.27
-    , data-default >=0.7.1.1 && <0.8
-    , errors >=2.2 && <2.4
-    , exceptions >=0.8.3 && <0.11
-    , generics-sop >=0.3.1.0 && <0.6
-    , hspec >=2.4 && <2.8
-    , http-client >=0.5.7.1 && <0.7
-    , http-client-tls >=0.3.5.1 && <0.4
-    , http-media >=0.7 && <0.8.1
-    , http-types >=0.12 && <0.14
-    , machines >=0.6.3 && <0.8
-    , memory >=0.14.11 && <0.16
-    , microlens >=0.4.8.1 && <0.5
-    , microlens-aeson >=2.2.0.2 && <2.4
-    , microlens-mtl >=0.1.11.0 && <0.3
-    , microlens-th >=0.4.1.1 && <0.5
-    , mtl >=2.2.1 && <2.3
-    , network >=2.6 && <3.2
-    , parsec >=3.1.11 && <3.2
-    , relapse >=1.0.0.0 && <2.0
-    , servant >=0.13 && <0.17
-    , servant-client >=0.13 && <0.17
-    , tagged >=0.8.5 && <0.9
-    , tar >=0.5 && <0.6
-    , template-haskell >=2.12 && <2.16
-    , text >=1.2.2.2 && <1.3
-    , transformers >=0.5.2.0 && <0.6
-    , unordered-containers >=0.2 && <0.3
-    , uuid-types >=1.0.3 && <1.1
-    , vinyl >=0.5.3 && <0.13
-    , websockets >=0.11 && <0.13
-  if flag(debug)
-    ghc-options: -ddump-splices
-  if flag(compiler)
-    other-modules:
-        Language.Solidity.Compiler
-        Language.Solidity.Compiler.Foreign
-    hs-source-dirs:
-        compiler
-    cpp-options: -DSOLIDITY_COMPILER
-    include-dirs:
-        ./compiler/cbits
-    c-sources:
-        ./compiler/cbits/solidity_lite.cpp
-    extra-libraries:
-        solidity
-    build-depends:
-        containers
-  default-language: Haskell2010
-
-test-suite live
-  type: exitcode-stdio-1.0
-  main-is: Spec.hs
-  other-modules:
-      Network.Ethereum.Test.ComplexStorageSpec
-      Network.Ethereum.Test.ERC20Spec
-      Network.Ethereum.Test.LinearizationSpec
-      Network.Ethereum.Test.LocalAccountSpec
-      Network.Ethereum.Test.RegistrySpec
-      Network.Ethereum.Test.SimpleStorageSpec
-      Network.Ethereum.Test.Utils
-      Network.Ipfs.Api.Test.Key
-      Crypto.Ecdsa.Signature
-      Crypto.Ecdsa.Utils
-      Crypto.Ethereum
-      Crypto.Ethereum.Keyfile
-      Crypto.Ethereum.Signature
-      Crypto.Ethereum.Utils
-      Crypto.Random.HmacDrbg
-      Data.ByteArray.HexString
-      Data.Solidity.Abi
-      Data.Solidity.Abi.Codec
-      Data.Solidity.Abi.Generic
-      Data.Solidity.Event
-      Data.Solidity.Event.Internal
-      Data.Solidity.Prim
-      Data.Solidity.Prim.Address
-      Data.Solidity.Prim.Bool
-      Data.Solidity.Prim.Bytes
-      Data.Solidity.Prim.Int
-      Data.Solidity.Prim.List
-      Data.Solidity.Prim.String
-      Data.Solidity.Prim.Tagged
-      Data.Solidity.Prim.Tuple
-      Data.Solidity.Prim.Tuple.TH
-      Data.String.Extra
-      Language.Solidity.Abi
-      Network.Ethereum
-      Network.Ethereum.Account
-      Network.Ethereum.Account.Class
-      Network.Ethereum.Account.Default
-      Network.Ethereum.Account.Internal
-      Network.Ethereum.Account.LocalKey
-      Network.Ethereum.Account.Personal
-      Network.Ethereum.Account.Safe
-      Network.Ethereum.Api.Eth
-      Network.Ethereum.Api.Net
-      Network.Ethereum.Api.Personal
-      Network.Ethereum.Api.Types
-      Network.Ethereum.Api.Web3
-      Network.Ethereum.Chain
-      Network.Ethereum.Contract
-      Network.Ethereum.Contract.Event
-      Network.Ethereum.Contract.Event.Common
-      Network.Ethereum.Contract.Event.MultiFilter
-      Network.Ethereum.Contract.Event.SingleFilter
-      Network.Ethereum.Contract.Method
-      Network.Ethereum.Contract.TH
-      Network.Ethereum.Ens
-      Network.Ethereum.Ens.PublicResolver
-      Network.Ethereum.Ens.Registry
-      Network.Ethereum.Transaction
-      Network.Ethereum.Unit
-      Network.Ipfs.Api.Bitswap
-      Network.Ipfs.Api.Block
-      Network.Ipfs.Api.Bootstrap
-      Network.Ipfs.Api.Cid
-      Network.Ipfs.Api.Config
-      Network.Ipfs.Api.Core
-      Network.Ipfs.Api.Dag
-      Network.Ipfs.Api.Dht
-      Network.Ipfs.Api.Files
-      Network.Ipfs.Api.Internal
-      Network.Ipfs.Api.Internal.Call
-      Network.Ipfs.Api.Internal.Stream
-      Network.Ipfs.Api.Key
-      Network.Ipfs.Api.Log
-      Network.Ipfs.Api.Object
-      Network.Ipfs.Api.Pin
-      Network.Ipfs.Api.Pubsub
-      Network.Ipfs.Api.Repo
-      Network.Ipfs.Api.Stats
-      Network.Ipfs.Api.Swarm
-      Network.Ipfs.Api.Types
-      Network.Ipfs.Api.Types.Stream
-      Network.Ipfs.Client
-      Network.JsonRpc.TinyClient
-      Network.Polkadot.Api.Account
-      Network.Polkadot.Api.Author
-      Network.Polkadot.Api.Babe
-      Network.Polkadot.Api.Chain
-      Network.Polkadot.Api.Childstate
-      Network.Polkadot.Api.Contracts
-      Network.Polkadot.Api.Engine
-      Network.Polkadot.Api.Grandpa
-      Network.Polkadot.Api.Offchain
-      Network.Polkadot.Api.Payment
-      Network.Polkadot.Api.Rpc
-      Network.Polkadot.Api.State
-      Network.Polkadot.Api.System
-      Network.Polkadot.Api.Types
-      Network.Web3
-      Network.Web3.Provider
-      Paths_web3
-  hs-source-dirs:
-      test
-      src
-  ghc-options: -funbox-strict-fields -Wduplicate-exports -Whi-shadowing -Widentities -Woverlapping-patterns -Wpartial-type-signatures -Wunrecognised-pragmas -Wtyped-holes -Wincomplete-patterns -Wincomplete-uni-patterns -Wmissing-fields -Wmissing-methods -Wmissing-exported-signatures -Wmissing-monadfail-instances -Wmissing-signatures -Wname-shadowing -Wunused-binds -Wunused-top-binds -Wunused-local-binds -Wunused-pattern-binds -Wunused-imports -Wunused-matches -Wunused-foralls -Wtabs -threaded -rtsopts -with-rtsopts=-N
-  build-depends:
-      OneTuple >=0.2.1 && <0.3
-    , aeson >=1.2.2.0 && <1.5
-    , async >=2.1.1.1 && <2.3
-    , attoparsec >=0.13.2.1 && <0.14
-    , base >4.10 && <4.14
-    , base58string >=0.10.0 && <0.11
-    , basement >=0.0.4 && <0.1
-    , bytestring >=0.10.8.1 && <0.11
-    , cereal >=0.5.4.0 && <0.6
-    , cryptonite >=0.23 && <0.27
-    , data-default >=0.7.1.1 && <0.8
-    , errors >=2.2 && <2.4
-    , exceptions >=0.8.3 && <0.11
-    , generics-sop >=0.3.1.0 && <0.6
-    , hspec >=2.4.4 && <2.8
-    , hspec-contrib >=0.4.0 && <0.6
-    , hspec-discover >=2.4.4 && <2.8
-    , hspec-expectations >=0.8.2 && <0.9
-    , http-client >=0.5.7.1 && <0.7
-    , http-client-tls >=0.3.5.1 && <0.4
-    , http-media >=0.7 && <0.8.1
-    , http-types >=0.12 && <0.14
-    , machines >=0.6.3 && <0.8
-    , memory >=0.14.11 && <0.16
-    , microlens >=0.4.8.1 && <0.5
-    , microlens-aeson >=2.2.0.2 && <2.4
-    , microlens-mtl >=0.1.11.0 && <0.3
-    , microlens-th >=0.4.1.1 && <0.5
-    , mtl >=2.2.1 && <2.3
-    , network >=2.6 && <3.2
-    , parsec >=3.1.11 && <3.2
-    , random >=1.1 && <1.2
-    , relapse >=1.0.0.0 && <2.0
-    , servant >=0.13 && <0.17
-    , servant-client >=0.13 && <0.17
-    , split >=0.2.3 && <0.3
-    , stm >=2.4.4 && <2.6
-    , tagged >=0.8.5 && <0.9
-    , tar >=0.5 && <0.6
-    , template-haskell >=2.12 && <2.16
-    , text >=1.2.2.2 && <1.3
-    , time >=1.6.0 && <1.11
-    , transformers >=0.5.2.0 && <0.6
-    , unordered-containers >=0.2 && <0.3
-    , uuid-types >=1.0.3 && <1.1
-    , vinyl >=0.5.3 && <0.13
-    , websockets >=0.11 && <0.13
-  if flag(debug)
-    ghc-options: -ddump-splices
-  if flag(compiler)
-    other-modules:
-        Language.Solidity.Compiler
-        Language.Solidity.Compiler.Foreign
-    hs-source-dirs:
-        compiler
-    cpp-options: -DSOLIDITY_COMPILER
-    include-dirs:
-        ./compiler/cbits
-    c-sources:
-        ./compiler/cbits/solidity_lite.cpp
-    extra-libraries:
-        solidity
-    build-depends:
-        containers
-  default-language: Haskell2010
-
-test-suite unit
-  type: exitcode-stdio-1.0
-  main-is: Spec.hs
-  other-modules:
-      Crypto.Ethereum.Test.KeyfileSpec
-      Crypto.Ethereum.Test.SignatureSpec
-      Crypto.Random.Test.HmacDrbgSpec
-      Data.Solidity.Test.AddressSpec
-      Data.Solidity.Test.EncodingSpec
-      Data.Solidity.Test.IntSpec
-      Language.Solidity.Test.AbiSpec
-      Language.Solidity.Test.CompilerSpec
-      Network.Ethereum.Contract.Test.THSpec
-      Network.Ethereum.Web3.Test.EventSpec
-      Network.Ethereum.Web3.Test.MethodDumpSpec
-      Crypto.Ecdsa.Signature
-      Crypto.Ecdsa.Utils
-      Crypto.Ethereum
-      Crypto.Ethereum.Keyfile
-      Crypto.Ethereum.Signature
-      Crypto.Ethereum.Utils
-      Crypto.Random.HmacDrbg
-      Data.ByteArray.HexString
-      Data.Solidity.Abi
-      Data.Solidity.Abi.Codec
-      Data.Solidity.Abi.Generic
-      Data.Solidity.Event
-      Data.Solidity.Event.Internal
-      Data.Solidity.Prim
-      Data.Solidity.Prim.Address
-      Data.Solidity.Prim.Bool
-      Data.Solidity.Prim.Bytes
-      Data.Solidity.Prim.Int
-      Data.Solidity.Prim.List
-      Data.Solidity.Prim.String
-      Data.Solidity.Prim.Tagged
-      Data.Solidity.Prim.Tuple
-      Data.Solidity.Prim.Tuple.TH
-      Data.String.Extra
-      Language.Solidity.Abi
-      Network.Ethereum
-      Network.Ethereum.Account
-      Network.Ethereum.Account.Class
-      Network.Ethereum.Account.Default
-      Network.Ethereum.Account.Internal
-      Network.Ethereum.Account.LocalKey
-      Network.Ethereum.Account.Personal
-      Network.Ethereum.Account.Safe
-      Network.Ethereum.Api.Eth
-      Network.Ethereum.Api.Net
-      Network.Ethereum.Api.Personal
-      Network.Ethereum.Api.Types
-      Network.Ethereum.Api.Web3
-      Network.Ethereum.Chain
-      Network.Ethereum.Contract
-      Network.Ethereum.Contract.Event
-      Network.Ethereum.Contract.Event.Common
-      Network.Ethereum.Contract.Event.MultiFilter
-      Network.Ethereum.Contract.Event.SingleFilter
-      Network.Ethereum.Contract.Method
-      Network.Ethereum.Contract.TH
-      Network.Ethereum.Ens
-      Network.Ethereum.Ens.PublicResolver
-      Network.Ethereum.Ens.Registry
-      Network.Ethereum.Transaction
-      Network.Ethereum.Unit
-      Network.Ipfs.Api.Bitswap
-      Network.Ipfs.Api.Block
-      Network.Ipfs.Api.Bootstrap
-      Network.Ipfs.Api.Cid
-      Network.Ipfs.Api.Config
-      Network.Ipfs.Api.Core
-      Network.Ipfs.Api.Dag
-      Network.Ipfs.Api.Dht
-      Network.Ipfs.Api.Files
-      Network.Ipfs.Api.Internal
-      Network.Ipfs.Api.Internal.Call
-      Network.Ipfs.Api.Internal.Stream
-      Network.Ipfs.Api.Key
-      Network.Ipfs.Api.Log
-      Network.Ipfs.Api.Object
-      Network.Ipfs.Api.Pin
-      Network.Ipfs.Api.Pubsub
-      Network.Ipfs.Api.Repo
-      Network.Ipfs.Api.Stats
-      Network.Ipfs.Api.Swarm
-      Network.Ipfs.Api.Types
-      Network.Ipfs.Api.Types.Stream
-      Network.Ipfs.Client
-      Network.JsonRpc.TinyClient
-      Network.Polkadot.Api.Account
-      Network.Polkadot.Api.Author
-      Network.Polkadot.Api.Babe
-      Network.Polkadot.Api.Chain
-      Network.Polkadot.Api.Childstate
-      Network.Polkadot.Api.Contracts
-      Network.Polkadot.Api.Engine
-      Network.Polkadot.Api.Grandpa
-      Network.Polkadot.Api.Offchain
-      Network.Polkadot.Api.Payment
-      Network.Polkadot.Api.Rpc
-      Network.Polkadot.Api.State
-      Network.Polkadot.Api.System
-      Network.Polkadot.Api.Types
-      Network.Web3
-      Network.Web3.Provider
-      Paths_web3
-  hs-source-dirs:
-      unit
-      src
-  ghc-options: -funbox-strict-fields -Wduplicate-exports -Whi-shadowing -Widentities -Woverlapping-patterns -Wpartial-type-signatures -Wunrecognised-pragmas -Wtyped-holes -Wincomplete-patterns -Wincomplete-uni-patterns -Wmissing-fields -Wmissing-methods -Wmissing-exported-signatures -Wmissing-monadfail-instances -Wmissing-signatures -Wname-shadowing -Wunused-binds -Wunused-top-binds -Wunused-local-binds -Wunused-pattern-binds -Wunused-imports -Wunused-matches -Wunused-foralls -Wtabs -threaded -rtsopts -with-rtsopts=-N
-  build-depends:
-      OneTuple >=0.2.1 && <0.3
-    , aeson >=1.2.2.0 && <1.5
-    , async >=2.1.1.1 && <2.3
-    , attoparsec >=0.13.2.1 && <0.14
-    , base >4.10 && <4.14
-    , base58string >=0.10.0 && <0.11
-    , basement >=0.0.4 && <0.1
-    , bytestring >=0.10.8.1 && <0.11
-    , cereal >=0.5.4.0 && <0.6
-    , cryptonite >=0.23 && <0.27
-    , data-default >=0.7.1.1 && <0.8
-    , errors >=2.2 && <2.4
-    , exceptions >=0.8.3 && <0.11
-    , generics-sop >=0.3.1.0 && <0.6
-    , hspec >=2.4.4 && <2.8
-    , hspec-contrib >=0.4.0 && <0.6
-    , hspec-discover >=2.4.4 && <2.8
-    , hspec-expectations >=0.8.2 && <0.9
-    , http-client >=0.5.7.1 && <0.7
-    , http-client-tls >=0.3.5.1 && <0.4
-    , http-media >=0.7 && <0.8.1
-    , http-types >=0.12 && <0.14
-    , machines >=0.6.3 && <0.8
-    , memory >=0.14.11 && <0.16
-    , microlens >=0.4.8.1 && <0.5
-    , microlens-aeson >=2.2.0.2 && <2.4
-    , microlens-mtl >=0.1.11.0 && <0.3
-    , microlens-th >=0.4.1.1 && <0.5
-    , mtl >=2.2.1 && <2.3
-    , network >=2.6 && <3.2
-    , parsec >=3.1.11 && <3.2
-    , relapse >=1.0.0.0 && <2.0
-    , servant >=0.13 && <0.17
-    , servant-client >=0.13 && <0.17
-    , tagged >=0.8.5 && <0.9
-    , tar >=0.5 && <0.6
-    , template-haskell >=2.12 && <2.16
-    , text >=1.2.2.2 && <1.3
-    , transformers >=0.5.2.0 && <0.6
-    , unordered-containers >=0.2 && <0.3
-    , uuid-types >=1.0.3 && <1.1
-    , vinyl >=0.5.3 && <0.13
-    , websockets >=0.11 && <0.13
-  if flag(debug)
-    ghc-options: -ddump-splices
-  if flag(compiler)
-    other-modules:
-        Language.Solidity.Compiler
-        Language.Solidity.Compiler.Foreign
-    hs-source-dirs:
-        compiler
-    cpp-options: -DSOLIDITY_COMPILER
-    include-dirs:
-        ./compiler/cbits
-    c-sources:
-        ./compiler/cbits/solidity_lite.cpp
-    extra-libraries:
-        solidity
-    build-depends:
-        containers
-  default-language: Haskell2010
+cabal-version:      2.2
+name:               web3
+version:            0.9.1.0
+license:            BSD-3-Clause
+license-file:       LICENSE
+copyright:          (c) Alexander Krupenkin 2016
+maintainer:         mail@akru.me
+author:             Alexander Krupenkin
+homepage:           https://github.com/airalab/hs-web3#readme
+bug-reports:        https://github.com/airalab/hs-web3/issues
+synopsis:           Web3 API for Haskell.
+description:        Client library for Third Generation of Web.
+category:           Network
+build-type:         Simple
+extra-source-files:
+    README.md
+    CHANGELOG.md
+    stack.yaml
+    examples/token/ERC20.hs
+    examples/token/ERC20.json
+    examples/token/Main.hs
+    examples/token/stack.yaml
+    examples/token/package.yaml
+    examples/polkadot/Main.hs
+    examples/polkadot/stack.yaml
+    examples/polkadot/package.yaml
+    examples/scale/Main.hs
+    examples/scale/stack.yaml
+    examples/scale/package.yaml
+    test/contracts/Registry.json
+    test/contracts/SimpleStorage.json
+    test/contracts/ComplexStorage.json
+    test/contracts/Linearization.json
+
+source-repository head
+    type:     git
+    location: https://github.com/airalab/hs-web3
+
+flag compiler
+    description: Enable Solidity compiler
+    default:     False
+    manual:      True
+
+flag debug
+    description: Enable debug compiler options
+    default:     False
+    manual:      True
+
+library
+    exposed-modules:
+        Codec.Scale
+        Codec.Scale.Class
+        Codec.Scale.Compact
+        Codec.Scale.Core
+        Codec.Scale.Generic
+        Codec.Scale.SingletonEnum
+        Codec.Scale.Skip
+        Codec.Scale.TH
+        Crypto.Ecdsa.Signature
+        Crypto.Ecdsa.Utils
+        Crypto.Ethereum
+        Crypto.Ethereum.Keyfile
+        Crypto.Ethereum.Signature
+        Crypto.Ethereum.Utils
+        Crypto.Random.HmacDrbg
+        Data.ByteArray.HexString
+        Data.Solidity.Abi
+        Data.Solidity.Abi.Codec
+        Data.Solidity.Abi.Generic
+        Data.Solidity.Event
+        Data.Solidity.Event.Internal
+        Data.Solidity.Prim
+        Data.Solidity.Prim.Address
+        Data.Solidity.Prim.Bool
+        Data.Solidity.Prim.Bytes
+        Data.Solidity.Prim.Int
+        Data.Solidity.Prim.List
+        Data.Solidity.Prim.String
+        Data.Solidity.Prim.Tagged
+        Data.Solidity.Prim.Tuple
+        Data.Solidity.Prim.Tuple.TH
+        Data.String.Extra
+        Language.Solidity.Abi
+        Network.Ethereum
+        Network.Ethereum.Account
+        Network.Ethereum.Account.Class
+        Network.Ethereum.Account.Default
+        Network.Ethereum.Account.Internal
+        Network.Ethereum.Account.LocalKey
+        Network.Ethereum.Account.Personal
+        Network.Ethereum.Account.Safe
+        Network.Ethereum.Api.Eth
+        Network.Ethereum.Api.Net
+        Network.Ethereum.Api.Personal
+        Network.Ethereum.Api.Types
+        Network.Ethereum.Api.Web3
+        Network.Ethereum.Chain
+        Network.Ethereum.Contract
+        Network.Ethereum.Contract.Event
+        Network.Ethereum.Contract.Event.Common
+        Network.Ethereum.Contract.Event.MultiFilter
+        Network.Ethereum.Contract.Event.SingleFilter
+        Network.Ethereum.Contract.Method
+        Network.Ethereum.Contract.TH
+        Network.Ethereum.Ens
+        Network.Ethereum.Ens.PublicResolver
+        Network.Ethereum.Ens.Registry
+        Network.Ethereum.Transaction
+        Network.Ethereum.Unit
+        Network.Ipfs.Api.Bitswap
+        Network.Ipfs.Api.Block
+        Network.Ipfs.Api.Bootstrap
+        Network.Ipfs.Api.Cid
+        Network.Ipfs.Api.Config
+        Network.Ipfs.Api.Core
+        Network.Ipfs.Api.Dag
+        Network.Ipfs.Api.Dht
+        Network.Ipfs.Api.Files
+        Network.Ipfs.Api.Internal
+        Network.Ipfs.Api.Internal.Call
+        Network.Ipfs.Api.Internal.Stream
+        Network.Ipfs.Api.Key
+        Network.Ipfs.Api.Log
+        Network.Ipfs.Api.Object
+        Network.Ipfs.Api.Pin
+        Network.Ipfs.Api.Pubsub
+        Network.Ipfs.Api.Repo
+        Network.Ipfs.Api.Stats
+        Network.Ipfs.Api.Swarm
+        Network.Ipfs.Api.Types
+        Network.Ipfs.Api.Types.Stream
+        Network.Ipfs.Client
+        Network.JsonRpc.TinyClient
+        Network.Polkadot.Api.Account
+        Network.Polkadot.Api.Author
+        Network.Polkadot.Api.Babe
+        Network.Polkadot.Api.Chain
+        Network.Polkadot.Api.Childstate
+        Network.Polkadot.Api.Contracts
+        Network.Polkadot.Api.Engine
+        Network.Polkadot.Api.Grandpa
+        Network.Polkadot.Api.Offchain
+        Network.Polkadot.Api.Payment
+        Network.Polkadot.Api.Rpc
+        Network.Polkadot.Api.State
+        Network.Polkadot.Api.System
+        Network.Polkadot.Api.Types
+        Network.Web3
+        Network.Web3.Provider
+
+    hs-source-dirs:   src
+    other-modules:    Paths_web3
+    autogen-modules:  Paths_web3
+    default-language: Haskell2010
+    ghc-options:
+        -funbox-strict-fields -Wduplicate-exports -Whi-shadowing
+        -Widentities -Woverlapping-patterns -Wpartial-type-signatures
+        -Wunrecognised-pragmas -Wtyped-holes -Wincomplete-patterns
+        -Wincomplete-uni-patterns -Wmissing-fields -Wmissing-methods
+        -Wmissing-exported-signatures -Wmissing-monadfail-instances
+        -Wmissing-signatures -Wname-shadowing -Wunused-binds
+        -Wunused-top-binds -Wunused-local-binds -Wunused-pattern-binds
+        -Wunused-imports -Wunused-matches -Wunused-foralls -Wtabs
+
+    build-depends:
+        OneTuple >=0.2.1 && <0.3,
+        aeson >=1.2.2.0 && <1.5,
+        async >=2.1.1.1 && <2.3,
+        attoparsec >=0.13.2.1 && <0.14,
+        base >4.11 && <4.14,
+        base58string >=0.10.0 && <0.11,
+        basement >=0.0.4 && <0.1,
+        bitvec >=1.0.0 && <2.0,
+        bytestring >=0.10.8.1 && <0.11,
+        cereal >=0.5.4.0 && <0.6,
+        cryptonite >=0.23 && <0.27,
+        data-default >=0.7.1.1 && <0.8,
+        errors >=2.2 && <2.4,
+        exceptions >=0.8.3 && <0.11,
+        generics-sop >=0.3.1.0 && <0.6,
+        hspec >=2.4 && <2.8,
+        http-client >=0.5.7.1 && <0.7,
+        http-client-tls >=0.3.5.1 && <0.4,
+        http-media >=0.7 && <0.8.1,
+        http-types >=0.12 && <0.14,
+        machines >=0.6.3 && <0.8,
+        memory >=0.14.11 && <0.16,
+        microlens >=0.4.8.1 && <0.5,
+        microlens-aeson >=2.2.0.2 && <2.4,
+        microlens-mtl >=0.1.11.0 && <0.3,
+        microlens-th >=0.4.1.1 && <0.5,
+        mtl >=2.2.1 && <2.3,
+        network >=2.6 && <3.2,
+        parsec >=3.1.11 && <3.2,
+        relapse >=1.0.0.0 && <2.0,
+        servant >=0.13 && <0.17,
+        servant-client >=0.13 && <0.17,
+        tagged >=0.8.5 && <0.9,
+        tar ==0.5.*,
+        template-haskell >=2.12 && <2.16,
+        text >=1.2.2.2 && <1.3,
+        transformers >=0.5.2.0 && <0.6,
+        unordered-containers ==0.2.*,
+        uuid-types >=1.0.3 && <1.1,
+        vector ==0.12.*,
+        vinyl >=0.5.3 && <0.13,
+        websockets >=0.11 && <0.13
+
+    if flag(debug)
+        ghc-options: -ddump-splices
+
+    if flag(compiler)
+        cpp-options:     -DSOLIDITY_COMPILER
+        c-sources:       ./compiler/cbits/solidity_lite.cpp
+        hs-source-dirs:  compiler
+        other-modules:
+            Language.Solidity.Compiler
+            Language.Solidity.Compiler.Foreign
+
+        extra-libraries: solidity
+        include-dirs:    ./compiler/cbits
+        build-depends:   containers >=0.6.2.1 && <0.7
+
+test-suite live
+    type:             exitcode-stdio-1.0
+    main-is:          Spec.hs
+    hs-source-dirs:   test src
+    other-modules:
+        Network.Ethereum.Test.ComplexStorageSpec
+        Network.Ethereum.Test.ERC20Spec
+        Network.Ethereum.Test.LinearizationSpec
+        Network.Ethereum.Test.LocalAccountSpec
+        Network.Ethereum.Test.RegistrySpec
+        Network.Ethereum.Test.SimpleStorageSpec
+        Network.Ethereum.Test.Utils
+        Network.Ipfs.Api.Test.Key
+        Codec.Scale
+        Codec.Scale.Class
+        Codec.Scale.Compact
+        Codec.Scale.Core
+        Codec.Scale.Generic
+        Codec.Scale.SingletonEnum
+        Codec.Scale.Skip
+        Codec.Scale.TH
+        Crypto.Ecdsa.Signature
+        Crypto.Ecdsa.Utils
+        Crypto.Ethereum
+        Crypto.Ethereum.Keyfile
+        Crypto.Ethereum.Signature
+        Crypto.Ethereum.Utils
+        Crypto.Random.HmacDrbg
+        Data.ByteArray.HexString
+        Data.Solidity.Abi
+        Data.Solidity.Abi.Codec
+        Data.Solidity.Abi.Generic
+        Data.Solidity.Event
+        Data.Solidity.Event.Internal
+        Data.Solidity.Prim
+        Data.Solidity.Prim.Address
+        Data.Solidity.Prim.Bool
+        Data.Solidity.Prim.Bytes
+        Data.Solidity.Prim.Int
+        Data.Solidity.Prim.List
+        Data.Solidity.Prim.String
+        Data.Solidity.Prim.Tagged
+        Data.Solidity.Prim.Tuple
+        Data.Solidity.Prim.Tuple.TH
+        Data.String.Extra
+        Language.Solidity.Abi
+        Network.Ethereum
+        Network.Ethereum.Account
+        Network.Ethereum.Account.Class
+        Network.Ethereum.Account.Default
+        Network.Ethereum.Account.Internal
+        Network.Ethereum.Account.LocalKey
+        Network.Ethereum.Account.Personal
+        Network.Ethereum.Account.Safe
+        Network.Ethereum.Api.Eth
+        Network.Ethereum.Api.Net
+        Network.Ethereum.Api.Personal
+        Network.Ethereum.Api.Types
+        Network.Ethereum.Api.Web3
+        Network.Ethereum.Chain
+        Network.Ethereum.Contract
+        Network.Ethereum.Contract.Event
+        Network.Ethereum.Contract.Event.Common
+        Network.Ethereum.Contract.Event.MultiFilter
+        Network.Ethereum.Contract.Event.SingleFilter
+        Network.Ethereum.Contract.Method
+        Network.Ethereum.Contract.TH
+        Network.Ethereum.Ens
+        Network.Ethereum.Ens.PublicResolver
+        Network.Ethereum.Ens.Registry
+        Network.Ethereum.Transaction
+        Network.Ethereum.Unit
+        Network.Ipfs.Api.Bitswap
+        Network.Ipfs.Api.Block
+        Network.Ipfs.Api.Bootstrap
+        Network.Ipfs.Api.Cid
+        Network.Ipfs.Api.Config
+        Network.Ipfs.Api.Core
+        Network.Ipfs.Api.Dag
+        Network.Ipfs.Api.Dht
+        Network.Ipfs.Api.Files
+        Network.Ipfs.Api.Internal
+        Network.Ipfs.Api.Internal.Call
+        Network.Ipfs.Api.Internal.Stream
+        Network.Ipfs.Api.Key
+        Network.Ipfs.Api.Log
+        Network.Ipfs.Api.Object
+        Network.Ipfs.Api.Pin
+        Network.Ipfs.Api.Pubsub
+        Network.Ipfs.Api.Repo
+        Network.Ipfs.Api.Stats
+        Network.Ipfs.Api.Swarm
+        Network.Ipfs.Api.Types
+        Network.Ipfs.Api.Types.Stream
+        Network.Ipfs.Client
+        Network.JsonRpc.TinyClient
+        Network.Polkadot.Api.Account
+        Network.Polkadot.Api.Author
+        Network.Polkadot.Api.Babe
+        Network.Polkadot.Api.Chain
+        Network.Polkadot.Api.Childstate
+        Network.Polkadot.Api.Contracts
+        Network.Polkadot.Api.Engine
+        Network.Polkadot.Api.Grandpa
+        Network.Polkadot.Api.Offchain
+        Network.Polkadot.Api.Payment
+        Network.Polkadot.Api.Rpc
+        Network.Polkadot.Api.State
+        Network.Polkadot.Api.System
+        Network.Polkadot.Api.Types
+        Network.Web3
+        Network.Web3.Provider
+        Paths_web3
+
+    default-language: Haskell2010
+    ghc-options:
+        -funbox-strict-fields -Wduplicate-exports -Whi-shadowing
+        -Widentities -Woverlapping-patterns -Wpartial-type-signatures
+        -Wunrecognised-pragmas -Wtyped-holes -Wincomplete-patterns
+        -Wincomplete-uni-patterns -Wmissing-fields -Wmissing-methods
+        -Wmissing-exported-signatures -Wmissing-monadfail-instances
+        -Wmissing-signatures -Wname-shadowing -Wunused-binds
+        -Wunused-top-binds -Wunused-local-binds -Wunused-pattern-binds
+        -Wunused-imports -Wunused-matches -Wunused-foralls -Wtabs -threaded
+        -rtsopts -with-rtsopts=-N
+
+    build-depends:
+        OneTuple >=0.2.1 && <0.3,
+        aeson >=1.2.2.0 && <1.5,
+        async >=2.1.1.1 && <2.3,
+        attoparsec >=0.13.2.1 && <0.14,
+        base >4.11 && <4.14,
+        base58string >=0.10.0 && <0.11,
+        basement >=0.0.4 && <0.1,
+        bitvec >=1.0.0 && <2.0,
+        bytestring >=0.10.8.1 && <0.11,
+        cereal >=0.5.4.0 && <0.6,
+        cryptonite >=0.23 && <0.27,
+        data-default >=0.7.1.1 && <0.8,
+        errors >=2.2 && <2.4,
+        exceptions >=0.8.3 && <0.11,
+        generics-sop >=0.3.1.0 && <0.6,
+        hspec >=2.4.4 && <2.8,
+        hspec-contrib >=0.4.0 && <0.6,
+        hspec-discover >=2.4.4 && <2.8,
+        hspec-expectations >=0.8.2 && <0.9,
+        http-client >=0.5.7.1 && <0.7,
+        http-client-tls >=0.3.5.1 && <0.4,
+        http-media >=0.7 && <0.8.1,
+        http-types >=0.12 && <0.14,
+        machines >=0.6.3 && <0.8,
+        memory >=0.14.11 && <0.16,
+        microlens >=0.4.8.1 && <0.5,
+        microlens-aeson >=2.2.0.2 && <2.4,
+        microlens-mtl >=0.1.11.0 && <0.3,
+        microlens-th >=0.4.1.1 && <0.5,
+        mtl >=2.2.1 && <2.3,
+        network >=2.6 && <3.2,
+        parsec >=3.1.11 && <3.2,
+        random ==1.1.*,
+        relapse >=1.0.0.0 && <2.0,
+        servant >=0.13 && <0.17,
+        servant-client >=0.13 && <0.17,
+        split >=0.2.3 && <0.3,
+        stm >=2.4.4 && <2.6,
+        tagged >=0.8.5 && <0.9,
+        tar ==0.5.*,
+        template-haskell >=2.12 && <2.16,
+        text >=1.2.2.2 && <1.3,
+        time >=1.6.0 && <1.11,
+        transformers >=0.5.2.0 && <0.6,
+        unordered-containers ==0.2.*,
+        uuid-types >=1.0.3 && <1.1,
+        vector ==0.12.*,
+        vinyl >=0.5.3 && <0.13,
+        websockets >=0.11 && <0.13
+
+    if flag(debug)
+        ghc-options: -ddump-splices
+
+    if flag(compiler)
+        cpp-options:     -DSOLIDITY_COMPILER
+        c-sources:       ./compiler/cbits/solidity_lite.cpp
+        hs-source-dirs:  compiler
+        other-modules:
+            Language.Solidity.Compiler
+            Language.Solidity.Compiler.Foreign
+
+        extra-libraries: solidity
+        include-dirs:    ./compiler/cbits
+        build-depends:   containers >=0.6.2.1 && <0.7
+
+test-suite unit
+    type:             exitcode-stdio-1.0
+    main-is:          Spec.hs
+    hs-source-dirs:   unit src
+    other-modules:
+        Codec.Scale.Test.CoreSpec
+        Codec.Scale.Test.SingleFieldStructSpec
+        Codec.Scale.Test.SkipSpec
+        Crypto.Ethereum.Test.KeyfileSpec
+        Crypto.Ethereum.Test.SignatureSpec
+        Crypto.Random.Test.HmacDrbgSpec
+        Data.Solidity.Test.AddressSpec
+        Data.Solidity.Test.EncodingSpec
+        Data.Solidity.Test.IntSpec
+        Language.Solidity.Test.AbiSpec
+        Language.Solidity.Test.CompilerSpec
+        Network.Ethereum.Contract.Test.THSpec
+        Network.Ethereum.Web3.Test.EventSpec
+        Network.Ethereum.Web3.Test.MethodDumpSpec
+        Codec.Scale
+        Codec.Scale.Class
+        Codec.Scale.Compact
+        Codec.Scale.Core
+        Codec.Scale.Generic
+        Codec.Scale.SingletonEnum
+        Codec.Scale.Skip
+        Codec.Scale.TH
+        Crypto.Ecdsa.Signature
+        Crypto.Ecdsa.Utils
+        Crypto.Ethereum
+        Crypto.Ethereum.Keyfile
+        Crypto.Ethereum.Signature
+        Crypto.Ethereum.Utils
+        Crypto.Random.HmacDrbg
+        Data.ByteArray.HexString
+        Data.Solidity.Abi
+        Data.Solidity.Abi.Codec
+        Data.Solidity.Abi.Generic
+        Data.Solidity.Event
+        Data.Solidity.Event.Internal
+        Data.Solidity.Prim
+        Data.Solidity.Prim.Address
+        Data.Solidity.Prim.Bool
+        Data.Solidity.Prim.Bytes
+        Data.Solidity.Prim.Int
+        Data.Solidity.Prim.List
+        Data.Solidity.Prim.String
+        Data.Solidity.Prim.Tagged
+        Data.Solidity.Prim.Tuple
+        Data.Solidity.Prim.Tuple.TH
+        Data.String.Extra
+        Language.Solidity.Abi
+        Network.Ethereum
+        Network.Ethereum.Account
+        Network.Ethereum.Account.Class
+        Network.Ethereum.Account.Default
+        Network.Ethereum.Account.Internal
+        Network.Ethereum.Account.LocalKey
+        Network.Ethereum.Account.Personal
+        Network.Ethereum.Account.Safe
+        Network.Ethereum.Api.Eth
+        Network.Ethereum.Api.Net
+        Network.Ethereum.Api.Personal
+        Network.Ethereum.Api.Types
+        Network.Ethereum.Api.Web3
+        Network.Ethereum.Chain
+        Network.Ethereum.Contract
+        Network.Ethereum.Contract.Event
+        Network.Ethereum.Contract.Event.Common
+        Network.Ethereum.Contract.Event.MultiFilter
+        Network.Ethereum.Contract.Event.SingleFilter
+        Network.Ethereum.Contract.Method
+        Network.Ethereum.Contract.TH
+        Network.Ethereum.Ens
+        Network.Ethereum.Ens.PublicResolver
+        Network.Ethereum.Ens.Registry
+        Network.Ethereum.Transaction
+        Network.Ethereum.Unit
+        Network.Ipfs.Api.Bitswap
+        Network.Ipfs.Api.Block
+        Network.Ipfs.Api.Bootstrap
+        Network.Ipfs.Api.Cid
+        Network.Ipfs.Api.Config
+        Network.Ipfs.Api.Core
+        Network.Ipfs.Api.Dag
+        Network.Ipfs.Api.Dht
+        Network.Ipfs.Api.Files
+        Network.Ipfs.Api.Internal
+        Network.Ipfs.Api.Internal.Call
+        Network.Ipfs.Api.Internal.Stream
+        Network.Ipfs.Api.Key
+        Network.Ipfs.Api.Log
+        Network.Ipfs.Api.Object
+        Network.Ipfs.Api.Pin
+        Network.Ipfs.Api.Pubsub
+        Network.Ipfs.Api.Repo
+        Network.Ipfs.Api.Stats
+        Network.Ipfs.Api.Swarm
+        Network.Ipfs.Api.Types
+        Network.Ipfs.Api.Types.Stream
+        Network.Ipfs.Client
+        Network.JsonRpc.TinyClient
+        Network.Polkadot.Api.Account
+        Network.Polkadot.Api.Author
+        Network.Polkadot.Api.Babe
+        Network.Polkadot.Api.Chain
+        Network.Polkadot.Api.Childstate
+        Network.Polkadot.Api.Contracts
+        Network.Polkadot.Api.Engine
+        Network.Polkadot.Api.Grandpa
+        Network.Polkadot.Api.Offchain
+        Network.Polkadot.Api.Payment
+        Network.Polkadot.Api.Rpc
+        Network.Polkadot.Api.State
+        Network.Polkadot.Api.System
+        Network.Polkadot.Api.Types
+        Network.Web3
+        Network.Web3.Provider
+        Paths_web3
+
+    default-language: Haskell2010
+    ghc-options:
+        -funbox-strict-fields -Wduplicate-exports -Whi-shadowing
+        -Widentities -Woverlapping-patterns -Wpartial-type-signatures
+        -Wunrecognised-pragmas -Wtyped-holes -Wincomplete-patterns
+        -Wincomplete-uni-patterns -Wmissing-fields -Wmissing-methods
+        -Wmissing-exported-signatures -Wmissing-monadfail-instances
+        -Wmissing-signatures -Wname-shadowing -Wunused-binds
+        -Wunused-top-binds -Wunused-local-binds -Wunused-pattern-binds
+        -Wunused-imports -Wunused-matches -Wunused-foralls -Wtabs -threaded
+        -rtsopts -with-rtsopts=-N
+
+    build-depends:
+        OneTuple >=0.2.1 && <0.3,
+        aeson >=1.2.2.0 && <1.5,
+        async >=2.1.1.1 && <2.3,
+        attoparsec >=0.13.2.1 && <0.14,
+        base >4.11 && <4.14,
+        base58string >=0.10.0 && <0.11,
+        basement >=0.0.4 && <0.1,
+        bitvec >=1.0.0 && <2.0,
+        bytestring >=0.10.8.1 && <0.11,
+        cereal >=0.5.4.0 && <0.6,
+        cryptonite >=0.23 && <0.27,
+        data-default >=0.7.1.1 && <0.8,
+        errors >=2.2 && <2.4,
+        exceptions >=0.8.3 && <0.11,
+        generics-sop >=0.3.1.0 && <0.6,
+        hspec >=2.4.4 && <2.8,
+        hspec-contrib >=0.4.0 && <0.6,
+        hspec-discover >=2.4.4 && <2.8,
+        hspec-expectations >=0.8.2 && <0.9,
+        http-client >=0.5.7.1 && <0.7,
+        http-client-tls >=0.3.5.1 && <0.4,
+        http-media >=0.7 && <0.8.1,
+        http-types >=0.12 && <0.14,
+        machines >=0.6.3 && <0.8,
+        memory >=0.14.11 && <0.16,
+        microlens >=0.4.8.1 && <0.5,
+        microlens-aeson >=2.2.0.2 && <2.4,
+        microlens-mtl >=0.1.11.0 && <0.3,
+        microlens-th >=0.4.1.1 && <0.5,
+        mtl >=2.2.1 && <2.3,
+        network >=2.6 && <3.2,
+        parsec >=3.1.11 && <3.2,
+        relapse >=1.0.0.0 && <2.0,
+        servant >=0.13 && <0.17,
+        servant-client >=0.13 && <0.17,
+        tagged >=0.8.5 && <0.9,
+        tar ==0.5.*,
+        template-haskell >=2.12 && <2.16,
+        text >=1.2.2.2 && <1.3,
+        transformers >=0.5.2.0 && <0.6,
+        unordered-containers ==0.2.*,
+        uuid-types >=1.0.3 && <1.1,
+        vector ==0.12.*,
+        vinyl >=0.5.3 && <0.13,
+        websockets >=0.11 && <0.13
+
+    if flag(debug)
+        ghc-options: -ddump-splices
+
+    if flag(compiler)
+        cpp-options:     -DSOLIDITY_COMPILER
+        c-sources:       ./compiler/cbits/solidity_lite.cpp
+        hs-source-dirs:  compiler
+        other-modules:
+            Language.Solidity.Compiler
+            Language.Solidity.Compiler.Foreign
+
+        extra-libraries: solidity
+        include-dirs:    ./compiler/cbits
+        build-depends:   containers >=0.6.2.1 && <0.7
