{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module Haskoin.Address (
Address (..),
isPubKeyAddress,
isScriptAddress,
isWitnessAddress,
isWitnessPubKeyAddress,
isWitnessScriptAddress,
addrToText,
textToAddr,
bech32ToAddr,
cashToAddr,
base58ToAddr,
addrToJSON,
addrToEncoding,
addrFromJSON,
pubKeyAddr,
pubKeyWitnessAddr,
pubKeyCompatWitnessAddr,
p2pkhAddr,
p2wpkhAddr,
p2shAddr,
p2wshAddr,
inputAddress,
outputAddress,
addressToScript,
addressToScriptBS,
addressToOutput,
payToScriptAddress,
payToWitnessScriptAddress,
payToNestedScriptAddress,
scriptToAddress,
scriptToAddressBS,
module Haskoin.Address.Base58,
module Haskoin.Address.Bech32,
module Haskoin.Address.CashAddr,
) where
import Control.Applicative
import Control.Arrow (second)
import Control.DeepSeq
import Control.Monad
import Data.Aeson as A
import Data.Aeson.Encoding as A
import Data.Aeson.Types
import Data.Binary (Binary (..))
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Data.Bytes.Get
import Data.Bytes.Put
import Data.Bytes.Serial
import Data.Hashable
import Data.Maybe
import Data.Serialize (Serialize (..))
import Data.Text (Text)
import qualified Data.Text as T
import Data.Word (Word8)
import GHC.Generics (Generic)
import Haskoin.Address.Base58
import Haskoin.Address.Bech32
import Haskoin.Address.CashAddr
import Haskoin.Crypto
import Haskoin.Data
import Haskoin.Keys.Common
import Haskoin.Script
import Haskoin.Util
data Address
=
PubKeyAddress
{
Address -> Hash160
getAddrHash160 :: !Hash160
}
|
ScriptAddress
{
getAddrHash160 :: !Hash160
}
|
WitnessPubKeyAddress
{
getAddrHash160 :: !Hash160
}
|
WitnessScriptAddress
{
Address -> Hash256
getAddrHash256 :: !Hash256
}
|
WitnessAddress
{ Address -> Word8
getAddrVersion :: !Word8
, Address -> ByteString
getAddrData :: !ByteString
}
deriving
(Address -> Address -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Address -> Address -> Bool
$c/= :: Address -> Address -> Bool
== :: Address -> Address -> Bool
$c== :: Address -> Address -> Bool
Eq, Eq Address
Address -> Address -> Bool
Address -> Address -> Ordering
Address -> Address -> Address
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Address -> Address -> Address
$cmin :: Address -> Address -> Address
max :: Address -> Address -> Address
$cmax :: Address -> Address -> Address
>= :: Address -> Address -> Bool
$c>= :: Address -> Address -> Bool
> :: Address -> Address -> Bool
$c> :: Address -> Address -> Bool
<= :: Address -> Address -> Bool
$c<= :: Address -> Address -> Bool
< :: Address -> Address -> Bool
$c< :: Address -> Address -> Bool
compare :: Address -> Address -> Ordering
$ccompare :: Address -> Address -> Ordering
Ord, forall x. Rep Address x -> Address
forall x. Address -> Rep Address x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Address x -> Address
$cfrom :: forall x. Address -> Rep Address x
Generic, Int -> Address -> ShowS
[Address] -> ShowS
Address -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Address] -> ShowS
$cshowList :: [Address] -> ShowS
show :: Address -> String
$cshow :: Address -> String
showsPrec :: Int -> Address -> ShowS
$cshowsPrec :: Int -> Address -> ShowS
Show, ReadPrec [Address]
ReadPrec Address
Int -> ReadS Address
ReadS [Address]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Address]
$creadListPrec :: ReadPrec [Address]
readPrec :: ReadPrec Address
$creadPrec :: ReadPrec Address
readList :: ReadS [Address]
$creadList :: ReadS [Address]
readsPrec :: Int -> ReadS Address
$creadsPrec :: Int -> ReadS Address
Read, Eq Address
Int -> Address -> Int
Address -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Address -> Int
$chash :: Address -> Int
hashWithSalt :: Int -> Address -> Int
$chashWithSalt :: Int -> Address -> Int
Hashable, Address -> ()
forall a. (a -> ()) -> NFData a
rnf :: Address -> ()
$crnf :: Address -> ()
NFData)
instance Serial Address where
serialize :: forall (m :: * -> *). MonadPut m => Address -> m ()
serialize (PubKeyAddress Hash160
k) = do
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 Word8
0x00
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
k
serialize (ScriptAddress Hash160
s) = do
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 Word8
0x01
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
s
serialize (WitnessPubKeyAddress Hash160
h) = do
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 Word8
0x02
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
h
serialize (WitnessScriptAddress Hash256
s) = do
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 Word8
0x03
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash256
s
serialize (WitnessAddress Word8
v ByteString
d) = do
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 Word8
0x04
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 Word8
v
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be (forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
B.length ByteString
d))
forall (m :: * -> *). MonadPut m => ByteString -> m ()
putByteString ByteString
d
deserialize :: forall (m :: * -> *). MonadGet m => m Address
deserialize =
forall (m :: * -> *). MonadGet m => m Word8
getWord8 forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Word8
0x00 -> Hash160 -> Address
PubKeyAddress forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
Word8
0x01 -> Hash160 -> Address
ScriptAddress forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
Word8
0x02 -> Hash160 -> Address
WitnessPubKeyAddress forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
Word8
0x03 -> Hash256 -> Address
WitnessScriptAddress forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
Word8
0x04 ->
Word8 -> ByteString -> Address
WitnessAddress forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadGet m => m Word8
getWord8
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (forall (m :: * -> *). MonadGet m => Int -> m ByteString
getByteString forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *). MonadGet m => m Word64
getWord64be)
Word8
b ->
forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack forall a b. (a -> b) -> a -> b
$
Text
"Could not decode address type byte: "
forall a. Semigroup a => a -> a -> a
<> ByteString -> Text
encodeHex (Word8 -> ByteString
B.singleton Word8
b)
instance Serialize Address where
put :: Putter Address
put = forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
get :: Get Address
get = forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
instance Binary Address where
put :: Address -> Put
put = forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
get :: Get Address
get = forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
isPubKeyAddress :: Address -> Bool
isPubKeyAddress :: Address -> Bool
isPubKeyAddress PubKeyAddress{} = Bool
True
isPubKeyAddress Address
_ = Bool
False
isScriptAddress :: Address -> Bool
isScriptAddress :: Address -> Bool
isScriptAddress ScriptAddress{} = Bool
True
isScriptAddress Address
_ = Bool
False
isWitnessPubKeyAddress :: Address -> Bool
isWitnessPubKeyAddress :: Address -> Bool
isWitnessPubKeyAddress WitnessPubKeyAddress{} = Bool
True
isWitnessPubKeyAddress Address
_ = Bool
False
isWitnessScriptAddress :: Address -> Bool
isWitnessScriptAddress :: Address -> Bool
isWitnessScriptAddress WitnessScriptAddress{} = Bool
True
isWitnessScriptAddress Address
_ = Bool
False
isWitnessAddress :: Address -> Bool
isWitnessAddress :: Address -> Bool
isWitnessAddress WitnessAddress{} = Bool
True
isWitnessAddress Address
_ = Bool
False
addrToJSON :: Network -> Address -> Value
addrToJSON :: Network -> Address -> Value
addrToJSON Network
net Address
a = forall a. ToJSON a => a -> Value
toJSON (Network -> Address -> Maybe Text
addrToText Network
net Address
a)
addrToEncoding :: Network -> Address -> Encoding
addrToEncoding :: Network -> Address -> Encoding
addrToEncoding Network
net = forall b a. b -> (a -> b) -> Maybe a -> b
maybe Encoding
null_ forall a. Text -> Encoding' a
text forall b c a. (b -> c) -> (a -> b) -> a -> c
. Network -> Address -> Maybe Text
addrToText Network
net
addrFromJSON :: Network -> Value -> Parser Address
addrFromJSON :: Network -> Value -> Parser Address
addrFromJSON Network
net =
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"address" forall a b. (a -> b) -> a -> b
$ \Text
t ->
case Network -> Text -> Maybe Address
textToAddr Network
net Text
t of
Maybe Address
Nothing -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"could not decode address"
Just Address
x -> forall (m :: * -> *) a. Monad m => a -> m a
return Address
x
addrToText :: Network -> Address -> Maybe Text
addrToText :: Network -> Address -> Maybe Text
addrToText Network
net a :: Address
a@PubKeyAddress{getAddrHash160 :: Address -> Hash160
getAddrHash160 = Hash160
h}
| forall a. Maybe a -> Bool
isNothing (Network -> Maybe Text
getCashAddrPrefix Network
net) =
forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
encodeBase58Check forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
runPutS forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). MonadPut m => Network -> Address -> m ()
base58put Network
net Address
a
| Bool
otherwise = Network -> Word8 -> ByteString -> Maybe Text
cashAddrEncode Network
net Word8
0 (Put -> ByteString
runPutS forall a b. (a -> b) -> a -> b
$ forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
h)
addrToText Network
net a :: Address
a@ScriptAddress{getAddrHash160 :: Address -> Hash160
getAddrHash160 = Hash160
h}
| forall a. Maybe a -> Bool
isNothing (Network -> Maybe Text
getCashAddrPrefix Network
net) =
forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
encodeBase58Check forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
runPutS forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). MonadPut m => Network -> Address -> m ()
base58put Network
net Address
a
| Bool
otherwise =
Network -> Word8 -> ByteString -> Maybe Text
cashAddrEncode Network
net Word8
1 (Put -> ByteString
runPutS forall a b. (a -> b) -> a -> b
$ forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
h)
addrToText Network
net WitnessPubKeyAddress{getAddrHash160 :: Address -> Hash160
getAddrHash160 = Hash160
h} = do
Text
hrp <- Network -> Maybe Text
getBech32Prefix Network
net
Text -> Word8 -> Data -> Maybe Text
segwitEncode Text
hrp Word8
0 (ByteString -> Data
B.unpack (Put -> ByteString
runPutS forall a b. (a -> b) -> a -> b
$ forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
h))
addrToText Network
net WitnessScriptAddress{getAddrHash256 :: Address -> Hash256
getAddrHash256 = Hash256
h} = do
Text
hrp <- Network -> Maybe Text
getBech32Prefix Network
net
Text -> Word8 -> Data -> Maybe Text
segwitEncode Text
hrp Word8
0 (ByteString -> Data
B.unpack (Put -> ByteString
runPutS forall a b. (a -> b) -> a -> b
$ forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash256
h))
addrToText Network
net WitnessAddress{getAddrVersion :: Address -> Word8
getAddrVersion = Word8
v, getAddrData :: Address -> ByteString
getAddrData = ByteString
d} = do
Text
hrp <- Network -> Maybe Text
getBech32Prefix Network
net
Text -> Word8 -> Data -> Maybe Text
segwitEncode Text
hrp Word8
v (ByteString -> Data
B.unpack ByteString
d)
textToAddr :: Network -> Text -> Maybe Address
textToAddr :: Network -> Text -> Maybe Address
textToAddr Network
net Text
txt =
Network -> Text -> Maybe Address
cashToAddr Network
net Text
txt forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Network -> Text -> Maybe Address
bech32ToAddr Network
net Text
txt forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Network -> Text -> Maybe Address
base58ToAddr Network
net Text
txt
cashToAddr :: Network -> Text -> Maybe Address
cashToAddr :: Network -> Text -> Maybe Address
cashToAddr Network
net Text
txt = do
(Word8
ver, ByteString
bs) <- Network -> Text -> Maybe (Word8, ByteString)
cashAddrDecode Network
net Text
txt
case Word8
ver of
Word8
0 -> Hash160 -> Address
PubKeyAddress forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a b. Either a b -> Maybe b
eitherToMaybe (forall a. Get a -> ByteString -> Either String a
runGetS forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize ByteString
bs)
Word8
1 -> Hash160 -> Address
ScriptAddress forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a b. Either a b -> Maybe b
eitherToMaybe (forall a. Get a -> ByteString -> Either String a
runGetS forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize ByteString
bs)
Word8
_ -> forall a. Maybe a
Nothing
bech32ToAddr :: Network -> Text -> Maybe Address
bech32ToAddr :: Network -> Text -> Maybe Address
bech32ToAddr Network
net Text
txt = do
Text
hrp <- Network -> Maybe Text
getBech32Prefix Network
net
(Word8
ver, ByteString
bs) <- forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second Data -> ByteString
B.pack forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Text -> Maybe (Word8, Data)
segwitDecode Text
hrp Text
txt
case Word8
ver of
Word8
0 -> case ByteString -> Int
B.length ByteString
bs of
Int
20 -> Hash160 -> Address
WitnessPubKeyAddress forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a b. Either a b -> Maybe b
eitherToMaybe (forall a. Get a -> ByteString -> Either String a
runGetS forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize ByteString
bs)
Int
32 -> Hash256 -> Address
WitnessScriptAddress forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a b. Either a b -> Maybe b
eitherToMaybe (forall a. Get a -> ByteString -> Either String a
runGetS forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize ByteString
bs)
Int
_ -> forall a. Maybe a
Nothing
Word8
_ -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString -> Address
WitnessAddress Word8
ver ByteString
bs
base58ToAddr :: Network -> Text -> Maybe Address
base58ToAddr :: Network -> Text -> Maybe Address
base58ToAddr Network
net Text
txt =
forall a b. Either a b -> Maybe b
eitherToMaybe forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Get a -> ByteString -> Either String a
runGetS (forall (m :: * -> *). MonadGet m => Network -> m Address
base58get Network
net) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Text -> Maybe ByteString
decodeBase58Check Text
txt
base58get :: MonadGet m => Network -> m Address
base58get :: forall (m :: * -> *). MonadGet m => Network -> m Address
base58get Network
net = do
Word8
pfx <- forall (m :: * -> *). MonadGet m => m Word8
getWord8
Hash160
addr <- forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
forall {m :: * -> *}. MonadFail m => Word8 -> Hash160 -> m Address
f Word8
pfx Hash160
addr
where
f :: Word8 -> Hash160 -> m Address
f Word8
x Hash160
a
| Word8
x forall a. Eq a => a -> a -> Bool
== Network -> Word8
getAddrPrefix Network
net = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Hash160 -> Address
PubKeyAddress Hash160
a
| Word8
x forall a. Eq a => a -> a -> Bool
== Network -> Word8
getScriptPrefix Network
net = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Hash160 -> Address
ScriptAddress Hash160
a
| Bool
otherwise = forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Does not recognize address prefix"
base58put :: MonadPut m => Network -> Address -> m ()
base58put :: forall (m :: * -> *). MonadPut m => Network -> Address -> m ()
base58put Network
net (PubKeyAddress Hash160
h) = do
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 (Network -> Word8
getAddrPrefix Network
net)
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
h
base58put Network
net (ScriptAddress Hash160
h) = do
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 (Network -> Word8
getScriptPrefix Network
net)
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
h
base58put Network
_ Address
_ = forall a. HasCallStack => String -> a
error String
"Cannot serialize this address as Base58"
pubKeyAddr :: PubKeyI -> Address
pubKeyAddr :: PubKeyI -> Address
pubKeyAddr = Hash160 -> Address
PubKeyAddress forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b. ByteArrayAccess b => b -> Hash160
addressHash forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
runPutS forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
p2pkhAddr :: Hash160 -> Address
p2pkhAddr :: Hash160 -> Address
p2pkhAddr = Hash160 -> Address
PubKeyAddress
pubKeyWitnessAddr :: PubKeyI -> Address
pubKeyWitnessAddr :: PubKeyI -> Address
pubKeyWitnessAddr = Hash160 -> Address
WitnessPubKeyAddress forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b. ByteArrayAccess b => b -> Hash160
addressHash forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
runPutS forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
pubKeyCompatWitnessAddr :: PubKeyI -> Address
pubKeyCompatWitnessAddr :: PubKeyI -> Address
pubKeyCompatWitnessAddr =
Hash160 -> Address
p2shAddr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b. ByteArrayAccess b => b -> Hash160
addressHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptOutput -> ByteString
encodeOutputBS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hash160 -> ScriptOutput
PayWitnessPKHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b. ByteArrayAccess b => b -> Hash160
addressHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
runPutS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
p2wpkhAddr :: Hash160 -> Address
p2wpkhAddr :: Hash160 -> Address
p2wpkhAddr = Hash160 -> Address
WitnessPubKeyAddress
p2shAddr :: Hash160 -> Address
p2shAddr :: Hash160 -> Address
p2shAddr = Hash160 -> Address
ScriptAddress
p2wshAddr :: Hash256 -> Address
p2wshAddr :: Hash256 -> Address
p2wshAddr = Hash256 -> Address
WitnessScriptAddress
payToScriptAddress :: ScriptOutput -> Address
payToScriptAddress :: ScriptOutput -> Address
payToScriptAddress = Hash160 -> Address
p2shAddr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b. ByteArrayAccess b => b -> Hash160
addressHash forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptOutput -> ByteString
encodeOutputBS
payToWitnessScriptAddress :: ScriptOutput -> Address
payToWitnessScriptAddress :: ScriptOutput -> Address
payToWitnessScriptAddress = Hash256 -> Address
p2wshAddr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b. ByteArrayAccess b => b -> Hash256
sha256 forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptOutput -> ByteString
encodeOutputBS
payToNestedScriptAddress :: ScriptOutput -> Address
payToNestedScriptAddress :: ScriptOutput -> Address
payToNestedScriptAddress =
Hash160 -> Address
p2shAddr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b. ByteArrayAccess b => b -> Hash160
addressHash forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptOutput -> ByteString
encodeOutputBS forall b c a. (b -> c) -> (a -> b) -> a -> c
. Script -> ScriptOutput
toP2WSH forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptOutput -> Script
encodeOutput
addressToOutput :: Address -> ScriptOutput
addressToOutput :: Address -> ScriptOutput
addressToOutput =
\case
PubKeyAddress Hash160
h -> Hash160 -> ScriptOutput
PayPKHash Hash160
h
ScriptAddress Hash160
h -> Hash160 -> ScriptOutput
PayScriptHash Hash160
h
WitnessPubKeyAddress Hash160
h -> Hash160 -> ScriptOutput
PayWitnessPKHash Hash160
h
WitnessScriptAddress Hash256
h -> Hash256 -> ScriptOutput
PayWitnessScriptHash Hash256
h
WitnessAddress Word8
v ByteString
d -> Word8 -> ByteString -> ScriptOutput
PayWitness Word8
v ByteString
d
addressToScript :: Address -> Script
addressToScript :: Address -> Script
addressToScript = ScriptOutput -> Script
encodeOutput forall b c a. (b -> c) -> (a -> b) -> a -> c
. Address -> ScriptOutput
addressToOutput
addressToScriptBS :: Address -> ByteString
addressToScriptBS :: Address -> ByteString
addressToScriptBS = Put -> ByteString
runPutS forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize forall b c a. (b -> c) -> (a -> b) -> a -> c
. Address -> Script
addressToScript
scriptToAddress :: Script -> Either String Address
scriptToAddress :: Script -> Either String Address
scriptToAddress =
forall b a. b -> Maybe a -> Either b a
maybeToEither String
"Could not decode address" forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptOutput -> Maybe Address
outputAddress forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Script -> Either String ScriptOutput
decodeOutput
scriptToAddressBS :: ByteString -> Either String Address
scriptToAddressBS :: ByteString -> Either String Address
scriptToAddressBS =
forall b a. b -> Maybe a -> Either b a
maybeToEither String
"Could not decode address" forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptOutput -> Maybe Address
outputAddress forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< ByteString -> Either String ScriptOutput
decodeOutputBS
outputAddress :: ScriptOutput -> Maybe Address
outputAddress :: ScriptOutput -> Maybe Address
outputAddress =
\case
PayPKHash Hash160
h -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Hash160 -> Address
PubKeyAddress Hash160
h
PayScriptHash Hash160
h -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Hash160 -> Address
ScriptAddress Hash160
h
PayPK PubKeyI
k -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ PubKeyI -> Address
pubKeyAddr PubKeyI
k
PayWitnessPKHash Hash160
h -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Hash160 -> Address
WitnessPubKeyAddress Hash160
h
PayWitnessScriptHash Hash256
h -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Hash256 -> Address
WitnessScriptAddress Hash256
h
PayWitness Word8
v ByteString
d -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString -> Address
WitnessAddress Word8
v ByteString
d
ScriptOutput
_ -> forall a. Maybe a
Nothing
inputAddress :: ScriptInput -> Maybe Address
inputAddress :: ScriptInput -> Maybe Address
inputAddress =
\case
(RegularInput (SpendPKHash TxSignature
_ PubKeyI
key)) -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ PubKeyI -> Address
pubKeyAddr PubKeyI
key
(ScriptHashInput SimpleInput
_ ScriptOutput
rdm) -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ ScriptOutput -> Address
payToScriptAddress ScriptOutput
rdm
ScriptInput
_ -> forall a. Maybe a
Nothing