diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,10 @@
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
 
+## 0.18.0
+### Added
+- Support SegWit addresses with version other than 0.
+
 ## 0.17.6
 ### Added
 - Serialize instances for `XPubKey` and `XPrvKey`.
diff --git a/haskoin-core.cabal b/haskoin-core.cabal
--- a/haskoin-core.cabal
+++ b/haskoin-core.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 80ca7faee9e1700b5927a262126a774fb45156219675eb255ba45e31aabcfe92
+-- hash: 9861fe70166471990a6ee8fcf42174a9d40cda5b4e28119073d56a221e78fee3
 
 name:           haskoin-core
-version:        0.17.6
+version:        0.18.0
 synopsis:       Bitcoin & Bitcoin Cash library for Haskell
 description:    Please see the README on GitHub at <https://github.com/haskoin/haskoin-core#readme>
 category:       Bitcoin, Finance, Network
diff --git a/src/Haskoin/Address.hs b/src/Haskoin/Address.hs
--- a/src/Haskoin/Address.hs
+++ b/src/Haskoin/Address.hs
@@ -64,6 +64,7 @@
 import           Data.Maybe
 import           Data.Serialize           as S
 import           Data.Text                (Text)
+import           Data.Word                (Word8)
 import           GHC.Generics             (Generic)
 import           Haskoin.Address.Base58
 import           Haskoin.Address.Bech32
@@ -96,6 +97,11 @@
           { getAddrHash256 :: !Hash256
           -- ^ HASH256 hash of script
           }
+    -- | other witness address
+    | WitnessAddress
+         { getAddrVersion :: !Word8
+         , getAddrData    :: !ByteString
+         }
     deriving (Eq, Ord, Generic, Show, Read, Serialize, Hashable, NFData)
 
 -- | 'Address' pays to a public key hash.
@@ -118,6 +124,10 @@
 isWitnessScriptAddress WitnessScriptAddress {} = True
 isWitnessScriptAddress _                       = False
 
+isWitnessAddress :: Address -> Bool
+isWitnessAddress WitnessAddress {} = True
+isWitnessAddress _                 = False
+
 addrToJSON :: Network -> Address -> Value
 addrToJSON net a = toJSON (addrToText net a)
 
@@ -151,6 +161,9 @@
 addrToText net WitnessScriptAddress {getAddrHash256 = h} = do
     hrp <- getBech32Prefix net
     segwitEncode hrp 0 (B.unpack (S.encode h))
+addrToText net WitnessAddress {getAddrVersion = v, getAddrData = d} = do
+    hrp <- getBech32Prefix net
+    segwitEncode hrp v (B.unpack d)
 
 -- | Parse 'Base58', 'Bech32' or 'CashAddr' address, depending on network.
 textToAddr :: Network -> Text -> Maybe Address
@@ -169,11 +182,12 @@
 bech32ToAddr net txt = do
     hrp <- getBech32Prefix net
     (ver, bs) <- second B.pack <$> segwitDecode hrp txt
-    guard (ver == 0) -- We only support version 0 for now
-    case B.length bs of
-        20 -> WitnessPubKeyAddress <$> eitherToMaybe (S.decode bs)
-        32 -> WitnessScriptAddress <$> eitherToMaybe (S.decode bs)
-        _  -> Nothing
+    case ver of
+        0 -> case B.length bs of
+            20 -> WitnessPubKeyAddress <$> eitherToMaybe (S.decode bs)
+            32 -> WitnessScriptAddress <$> eitherToMaybe (S.decode bs)
+            _  -> Nothing
+        _ -> Just $ WitnessAddress ver bs
 
 base58ToAddr :: Network -> Text -> Maybe Address
 base58ToAddr net txt =
@@ -250,10 +264,11 @@
 addressToOutput :: Address -> ScriptOutput
 addressToOutput =
     \case
-        (PubKeyAddress h) -> PayPKHash h
-        (ScriptAddress h) -> PayScriptHash h
-        (WitnessPubKeyAddress h) -> PayWitnessPKHash h
-        (WitnessScriptAddress h) -> PayWitnessScriptHash h
+        PubKeyAddress h -> PayPKHash h
+        ScriptAddress h -> PayScriptHash h
+        WitnessPubKeyAddress h -> PayWitnessPKHash h
+        WitnessScriptAddress h -> PayWitnessScriptHash h
+        WitnessAddress v d -> PayWitness v d
 
 -- | Get output script AST for an 'Address'.
 addressToScript :: Address -> Script
@@ -277,11 +292,12 @@
 outputAddress :: ScriptOutput -> Maybe Address
 outputAddress =
     \case
-        (PayPKHash h) -> Just $ PubKeyAddress h
-        (PayScriptHash h) -> Just $ ScriptAddress h
-        (PayPK k) -> Just $ pubKeyAddr k
-        (PayWitnessPKHash h) -> Just $ WitnessPubKeyAddress h
-        (PayWitnessScriptHash h) -> Just $ WitnessScriptAddress h
+        PayPKHash h -> Just $ PubKeyAddress h
+        PayScriptHash h -> Just $ ScriptAddress h
+        PayPK k -> Just $ pubKeyAddr k
+        PayWitnessPKHash h -> Just $ WitnessPubKeyAddress h
+        PayWitnessScriptHash h -> Just $ WitnessScriptAddress h
+        PayWitness v d -> Just $ WitnessAddress v d
         _ -> Nothing
 
 -- | Infer the 'Address' of a 'ScriptInput'.
diff --git a/src/Haskoin/Script/Standard.hs b/src/Haskoin/Script/Standard.hs
--- a/src/Haskoin/Script/Standard.hs
+++ b/src/Haskoin/Script/Standard.hs
@@ -53,7 +53,9 @@
 import           Data.Function          (on)
 import           Data.Hashable
 import           Data.List              (sortBy)
+import           Data.Maybe             (fromJust, isJust)
 import           Data.Serialize         as S
+import           Data.Word              (Word8)
 import           GHC.Generics           (Generic)
 import           Haskoin.Constants
 import           Haskoin.Crypto
@@ -79,6 +81,10 @@
     | PayWitnessPKHash { getOutputHash :: !Hash160 }
       -- | pay to witness script hash
     | PayWitnessScriptHash { getScriptHash :: !Hash256 }
+      -- | another pay to witness address
+    | PayWitness { getWitnessVersion :: !Word8
+                 , getWitnessData    :: !ByteString
+                 }
       -- | provably unspendable data carrier
     | DataCarrier { getOutputData :: !ByteString }
     deriving (Eq, Show, Read, Generic, Hashable, NFData)
@@ -124,6 +130,11 @@
 isPayWitnessScriptHash (PayWitnessScriptHash _) = True
 isPayWitnessScriptHash _                        = False
 
+-- | Is script paying to a different type of witness address?
+isPayWitness :: ScriptOutput -> Bool
+isPayWitness (PayWitness _ _) = True
+isPayWitness _                = False
+
 -- | Is script a data carrier output?
 isDataCarrier :: ScriptOutput -> Bool
 isDataCarrier (DataCarrier _) = True
@@ -145,11 +156,57 @@
     [OP_0, OP_PUSHDATA bs OPCODE]
       | BS.length bs == 20 -> PayWitnessPKHash     <$> S.decode bs
       | BS.length bs == 32 -> PayWitnessScriptHash <$> S.decode bs
+    -- Other Witness
+    [ver, OP_PUSHDATA bs _]
+      | isJust (opWitnessVersion ver)
+        && BS.length bs >= 2
+        && BS.length bs <= 40 ->
+            Right $ PayWitness (fromJust (opWitnessVersion ver)) bs
     -- Provably unspendable data carrier output
     [OP_RETURN, OP_PUSHDATA bs _] -> Right $ DataCarrier bs
     -- Pay to MultiSig Keys
     _ -> matchPayMulSig s
 
+witnessVersionOp :: Word8 -> Maybe ScriptOp
+witnessVersionOp 0  = Just OP_0
+witnessVersionOp 1  = Just OP_1
+witnessVersionOp 2  = Just OP_2
+witnessVersionOp 3  = Just OP_3
+witnessVersionOp 4  = Just OP_4
+witnessVersionOp 5  = Just OP_5
+witnessVersionOp 6  = Just OP_6
+witnessVersionOp 7  = Just OP_7
+witnessVersionOp 8  = Just OP_8
+witnessVersionOp 9  = Just OP_9
+witnessVersionOp 10 = Just OP_10
+witnessVersionOp 11 = Just OP_11
+witnessVersionOp 12 = Just OP_12
+witnessVersionOp 13 = Just OP_13
+witnessVersionOp 14 = Just OP_14
+witnessVersionOp 15 = Just OP_15
+witnessVersionOp 16 = Just OP_16
+
+opWitnessVersion :: ScriptOp -> Maybe Word8
+opWitnessVersion OP_0  = Just 0
+opWitnessVersion OP_1  = Just 1
+opWitnessVersion OP_2  = Just 2
+opWitnessVersion OP_3  = Just 3
+opWitnessVersion OP_4  = Just 4
+opWitnessVersion OP_5  = Just 5
+opWitnessVersion OP_6  = Just 6
+opWitnessVersion OP_7  = Just 7
+opWitnessVersion OP_8  = Just 8
+opWitnessVersion OP_9  = Just 9
+opWitnessVersion OP_10 = Just 10
+opWitnessVersion OP_11 = Just 11
+opWitnessVersion OP_12 = Just 12
+opWitnessVersion OP_13 = Just 13
+opWitnessVersion OP_14 = Just 14
+opWitnessVersion OP_15 = Just 15
+opWitnessVersion OP_16 = Just 16
+opWitnessVersion _ = Nothing
+
+
 -- | Similar to 'decodeOutput' but decodes from a 'ByteString'.
 decodeOutputBS :: ByteString -> Either String ScriptOutput
 decodeOutputBS = decodeOutput <=< S.decode
@@ -161,7 +218,11 @@
     (PayPK k) -> [opPushData $ S.encode k, OP_CHECKSIG]
     -- Pay to PubKey Hash Address
     (PayPKHash h) ->
-        [ OP_DUP, OP_HASH160, opPushData $ S.encode h, OP_EQUALVERIFY, OP_CHECKSIG]
+        [ OP_DUP
+        , OP_HASH160
+        , opPushData $ S.encode h
+        , OP_EQUALVERIFY, OP_CHECKSIG
+        ]
     -- Pay to MultiSig Keys
     (PayMulSig ps r)
       | r <= length ps ->
@@ -178,6 +239,11 @@
         [ OP_0, opPushData $ S.encode h ]
     (PayWitnessScriptHash h) ->
         [ OP_0, opPushData $ S.encode h ]
+    (PayWitness v h) ->
+        [ case witnessVersionOp v of
+              Nothing -> error "encodeOutput: invalid witness version"
+              Just c  -> c
+        , opPushData h ]
     -- Provably unspendable output
     (DataCarrier d) -> [OP_RETURN, opPushData d]
 
diff --git a/src/Haskoin/Util/Arbitrary/Address.hs b/src/Haskoin/Util/Arbitrary/Address.hs
--- a/src/Haskoin/Util/Arbitrary/Address.hs
+++ b/src/Haskoin/Util/Arbitrary/Address.hs
@@ -9,6 +9,7 @@
 -}
 module Haskoin.Util.Arbitrary.Address where
 
+import qualified Data.ByteString as B
 import           Haskoin.Address
 import           Haskoin.Constants
 import           Haskoin.Util.Arbitrary.Crypto
@@ -26,6 +27,7 @@
           , arbitraryScriptAddress
           , arbitraryWitnessPubKeyAddress
           , arbitraryWitnessScriptAddress
+          , arbitraryWitnessAddress
           ]
 
 -- | Arbitrary valid combination of (Network, Address)
@@ -51,3 +53,11 @@
 -- | Arbitrary pay-to-witness script hash
 arbitraryWitnessScriptAddress :: Gen Address
 arbitraryWitnessScriptAddress = WitnessPubKeyAddress <$> arbitraryHash160
+
+arbitraryWitnessAddress :: Gen Address
+arbitraryWitnessAddress = do
+    ver <- choose (0, 16)
+    len <- choose (2, 40)
+    ws <- vectorOf len arbitrary
+    let bs = B.pack ws
+    return $ WitnessAddress ver bs
diff --git a/src/Haskoin/Util/Arbitrary/Script.hs b/src/Haskoin/Util/Arbitrary/Script.hs
--- a/src/Haskoin/Util/Arbitrary/Script.hs
+++ b/src/Haskoin/Util/Arbitrary/Script.hs
@@ -10,6 +10,7 @@
 module Haskoin.Util.Arbitrary.Script where
 
 import           Crypto.Secp256k1
+import qualified Data.ByteString                as B
 import           Data.Maybe
 import           Data.Word
 import           Haskoin.Address
@@ -239,7 +240,10 @@
     , arbitraryDCOutput
     ] ++
     if getSegWit net
-        then [arbitraryWPKHashOutput, arbitraryWSHOutput]
+        then [ arbitraryWPKHashOutput
+             , arbitraryWSHOutput
+             , arbitraryWitOutput
+             ]
         else []
 
 -- | Arbitrary 'ScriptOutput' of type 'PayPK', 'PayPKHash' or 'PayMS'
@@ -267,6 +271,14 @@
 -- | Arbitrary 'PayWitnessScriptHash' output.
 arbitraryWSHOutput :: Gen ScriptOutput
 arbitraryWSHOutput = PayWitnessScriptHash <$> arbitraryHash256
+
+arbitraryWitOutput :: Gen ScriptOutput
+arbitraryWitOutput = do
+    ver <- choose (0, 16)
+    len <- choose (2, 40)
+    ws <- vectorOf len arbitrary
+    let bs = B.pack ws
+    return $ PayWitness ver bs
 
 -- | Arbitrary 'ScriptOutput' of type 'PayMS'.
 arbitraryMSOutput :: Gen ScriptOutput
