@@ -45,24 +45,36 @@ module Bitcoin.Address (
4545
4646import Bitcoin.Address.Base58
4747import Bitcoin.Address.Bech32
48- import Bitcoin.Crypto
49- import Bitcoin.Data
50- import Bitcoin.Keys.Common
51- import Bitcoin.Script
52- import Bitcoin.Util
53- import Control.Applicative
48+ import Bitcoin.Crypto (Hash160 , Hash256 , addressHash , addressHashL , sha256 )
49+ import Bitcoin.Data (Network (.. ))
50+ import Bitcoin.Keys.Common (PubKeyI )
51+ import Bitcoin.Script (
52+ Script ,
53+ ScriptInput (.. ),
54+ ScriptOutput (.. ),
55+ SimpleInput (SpendPKHash ),
56+ decodeOutput ,
57+ decodeOutputBS ,
58+ encodeOutput ,
59+ encodeOutputBS ,
60+ toP2WSH ,
61+ )
62+ import Bitcoin.Util (eitherToMaybe , encodeHex , maybeToEither )
63+ import qualified Bitcoin.Util as U
64+ import Control.Applicative ((<|>) )
5465import Control.Arrow (second )
55- import Control.DeepSeq
56- import Control.Monad
57- import Data.Binary (Binary (.. ))
66+ import Control.DeepSeq (NFData )
67+ import Control.Monad ((<=<) )
68+ import Data.Binary (Binary (.. ), Get , Put )
69+ import qualified Data.Binary as Bin
70+ import Data.Binary.Get (runGet )
71+ import qualified Data.Binary.Get as Get
72+ import Data.Binary.Put (runPut )
73+ import qualified Data.Binary.Put as Put
5874import Data.ByteString (ByteString )
59- import qualified Data.ByteString as B
60- import Data.Bytes.Get
61- import Data.Bytes.Put
62- import Data.Bytes.Serial
63- import Data.Hashable
64- import Data.Maybe
65- import Data.Serialize (Serialize (.. ))
75+ import qualified Data.ByteString as BS
76+ import qualified Data.ByteString.Lazy as BSL
77+ import Data.Hashable (Hashable )
6678import Data.Text (Text )
6779import qualified Data.Text as T
6880import Data.Word (Word8 )
@@ -100,50 +112,41 @@ data Address
100112 (Eq , Ord , Generic , Show , Read , Hashable , NFData )
101113
102114
103- instance Serial Address where
104- serialize (PubKeyAddress k) = do
105- putWord8 0x00
106- serialize k
107- serialize (ScriptAddress s) = do
108- putWord8 0x01
109- serialize s
110- serialize (WitnessPubKeyAddress h) = do
111- putWord8 0x02
112- serialize h
113- serialize (WitnessScriptAddress s) = do
114- putWord8 0x03
115- serialize s
116- serialize (WitnessAddress v d) = do
117- putWord8 0x04
118- putWord8 v
119- putWord64be (fromIntegral (B. length d))
120- putByteString d
121-
122-
123- deserialize =
124- getWord8 >>= \ case
125- 0x00 -> PubKeyAddress <$> deserialize
126- 0x01 -> ScriptAddress <$> deserialize
127- 0x02 -> WitnessPubKeyAddress <$> deserialize
128- 0x03 -> WitnessScriptAddress <$> deserialize
115+ instance Binary Address where
116+ put = \ case
117+ PubKeyAddress k -> do
118+ Put. putWord8 0x00
119+ put k
120+ ScriptAddress s -> do
121+ Put. putWord8 0x01
122+ put s
123+ WitnessPubKeyAddress h -> do
124+ Put. putWord8 0x02
125+ put h
126+ WitnessScriptAddress s -> do
127+ Put. putWord8 0x03
128+ put s
129+ WitnessAddress v d -> do
130+ Put. putWord8 0x04
131+ Put. putWord8 v
132+ Put. putWord64be (fromIntegral (BS. length d))
133+ Put. putByteString d
134+
135+
136+ get =
137+ Get. getWord8 >>= \ case
138+ 0x00 -> PubKeyAddress <$> get
139+ 0x01 -> ScriptAddress <$> get
140+ 0x02 -> WitnessPubKeyAddress <$> get
141+ 0x03 -> WitnessScriptAddress <$> get
129142 0x04 ->
130143 WitnessAddress
131- <$> getWord8
132- <*> (getByteString . fromIntegral =<< getWord64be)
144+ <$> Get. getWord8
145+ <*> (Get. getByteString . fromIntegral =<< Get. getWord64be)
133146 b ->
134147 fail . T. unpack $
135148 " Could not decode address type byte: "
136- <> encodeHex (B. singleton b)
137-
138-
139- instance Serialize Address where
140- put = serialize
141- get = deserialize
142-
143-
144- instance Binary Address where
145- put = serialize
146- get = deserialize
149+ <> encodeHex (BS. singleton b)
147150
148151
149152-- | 'Address' pays to a public key hash.
@@ -178,17 +181,17 @@ isWitnessAddress _ = False
178181-- | Convert address to human-readable string. Uses 'Base58', or 'Bech32'
179182-- depending on network.
180183addrToText :: Network -> Address -> Maybe Text
181- addrToText net a@ PubKeyAddress {} = Just . encodeBase58Check . runPutS $ base58put net a
182- addrToText net a@ ScriptAddress {} = Just . encodeBase58Check . runPutS $ base58put net a
184+ addrToText net a@ PubKeyAddress {} = Just . encodeBase58Check . Put. runPut $ base58put net a
185+ addrToText net a@ ScriptAddress {} = Just . encodeBase58Check . Put. runPut $ base58put net a
183186addrToText net WitnessPubKeyAddress {getAddrHash160 = h} = do
184187 hrp <- getBech32Prefix net
185- segwitEncode hrp 0 ( B. unpack (runPutS $ serialize h))
188+ segwitEncode hrp 0 . BSL. unpack $ Bin. encode h
186189addrToText net WitnessScriptAddress {getAddrHash256 = h} = do
187190 hrp <- getBech32Prefix net
188- segwitEncode hrp 0 ( B. unpack (runPutS $ serialize h))
191+ segwitEncode hrp 0 . BSL. unpack $ Bin. encode h
189192addrToText net WitnessAddress {getAddrVersion = v, getAddrData = d} = do
190193 hrp <- getBech32Prefix net
191- segwitEncode hrp v (B . unpack d)
194+ segwitEncode hrp v (BS . unpack d)
192195
193196
194197-- | Parse 'Base58', or 'Bech32' address, depending on network.
@@ -200,24 +203,24 @@ textToAddr net txt =
200203bech32ToAddr :: Network -> Text -> Maybe Address
201204bech32ToAddr net txt = do
202205 hrp <- getBech32Prefix net
203- (ver, bs) <- second B . pack <$> segwitDecode hrp txt
206+ (ver, bs) <- second BS . pack <$> segwitDecode hrp txt
204207 case ver of
205- 0 -> case B .length bs of
206- 20 -> WitnessPubKeyAddress <$> eitherToMaybe (runGetS deserialize bs)
207- 32 -> WitnessScriptAddress <$> eitherToMaybe (runGetS deserialize bs)
208+ 0 -> case BS .length bs of
209+ 20 -> WitnessPubKeyAddress <$> ( eitherToMaybe . U. decode . BSL. fromStrict) bs
210+ 32 -> WitnessScriptAddress <$> ( eitherToMaybe . U. decode . BSL. fromStrict) bs
208211 _ -> Nothing
209212 _ -> Just $ WitnessAddress ver bs
210213
211214
212215base58ToAddr :: Network -> Text -> Maybe Address
213216base58ToAddr net txt =
214- eitherToMaybe . runGetS (base58get net) =<< decodeBase58Check txt
217+ eitherToMaybe . U. runGet (base58get net) =<< decodeBase58Check txt
215218
216219
217- base58get :: MonadGet m => Network -> m Address
220+ base58get :: Network -> Get Address
218221base58get net = do
219- pfx <- getWord8
220- addr <- deserialize
222+ pfx <- Get. getWord8
223+ addr <- get
221224 f pfx addr
222225 where
223226 f x a
@@ -226,19 +229,19 @@ base58get net = do
226229 | otherwise = fail " Does not recognize address prefix"
227230
228231
229- base58put :: MonadPut m => Network -> Address -> m ()
232+ base58put :: Network -> Address -> Put
230233base58put net (PubKeyAddress h) = do
231- putWord8 (getAddrPrefix net)
232- serialize h
234+ Put. putWord8 (getAddrPrefix net)
235+ put h
233236base58put net (ScriptAddress h) = do
234- putWord8 (getScriptPrefix net)
235- serialize h
237+ Put. putWord8 (getScriptPrefix net)
238+ put h
236239base58put _ _ = error " Cannot serialize this address as Base58"
237240
238241
239242-- | Obtain a standard pay-to-public-key-hash address from a public key.
240243pubKeyAddr :: PubKeyI -> Address
241- pubKeyAddr = PubKeyAddress . addressHash . runPutS . serialize
244+ pubKeyAddr = PubKeyAddress . addressHashL . Bin. encode
242245
243246
244247-- | Obtain a standard pay-to-public-key-hash (P2PKH) address from a 'Hash160'.
@@ -249,7 +252,7 @@ p2pkhAddr = PubKeyAddress
249252-- | Obtain a SegWit pay-to-witness-public-key-hash (P2WPKH) address from a
250253-- public key.
251254pubKeyWitnessAddr :: PubKeyI -> Address
252- pubKeyWitnessAddr = WitnessPubKeyAddress . addressHash . runPutS . serialize
255+ pubKeyWitnessAddr = WitnessPubKeyAddress . addressHashL . Bin. encode
253256
254257
255258-- | Obtain a backwards-compatible SegWit P2SH-P2WPKH address from a public key.
@@ -259,9 +262,8 @@ pubKeyCompatWitnessAddr =
259262 . addressHash
260263 . encodeOutputBS
261264 . PayWitnessPKHash
262- . addressHash
263- . runPutS
264- . serialize
265+ . addressHashL
266+ . Bin. encode
265267
266268
267269-- | Obtain a SegWit pay-to-witness-public-key-hash (P2WPKH) address from a
@@ -316,7 +318,7 @@ addressToScript = encodeOutput . addressToOutput
316318
317319-- | Encode address as output script in 'ByteString' form.
318320addressToScriptBS :: Address -> ByteString
319- addressToScriptBS = runPutS . serialize . addressToScript
321+ addressToScriptBS = U. encodeS . addressToScript
320322
321323
322324-- | Decode an output script into an 'Address' if it has such representation.
0 commit comments