easy-bitcoin-0.0.0.2: Network/EasyBitcoin/Address.hs
{-# LANGUAGE ScopedTypeVariables #-}
module Network.EasyBitcoin.Address
where
import Network.EasyBitcoin.Internal.Words
import Network.EasyBitcoin.Internal.Base58 ( encodeBase58
, decodeBase58
, addRedundancy
, liftRedundacy
)
import Network.EasyBitcoin.Internal.ByteString
import Network.EasyBitcoin.Internal.InstanciationHelpers
import Network.EasyBitcoin.Internal.HashFunctions
import Network.EasyBitcoin.Internal.Keys (PrvKey(), PubKey(),Compressed(..))
import Network.EasyBitcoin.Keys
import Network.EasyBitcoin.NetworkParams
import qualified Data.ByteString as BS
import Data.Char(isSpace)
import Data.Word
-- | Bitcoin address, either Pay2PKH or Pay2SH
data Address net = PubKeyAddress { getAddrHash :: Word160 }
| ScriptAddress { getAddrHash :: Word160 }
deriving (Eq, Ord)
-- | Values from where an address can be derived. Keys, are interpreted as compressed by default, if need to derive an address from
-- an uncompressed key, use 'addressFromUncompressed' instead.
class Addressable add where
address :: (BlockNetwork net) => add net -> Address net
-- | As addresses are obtained from public keys hashes, when deriving from a private key, it will first get derived to public
--
-- prop> address key = address (derivePublic key)
--
-- Addresses derived from Keys will always be Pay2PKH addresses:
--
-- prop> isPay2PKH (address key) = True
instance Addressable (Key v) where
address = PubKeyAddress . hash160 . hash256BS . encode' . Compressed True. pub_key . derivePublic
-- | Derive an address from a key as uncompressed.
addressFromUncompressed:: Key v net -> Address net
addressFromUncompressed = PubKeyAddress . hash160 . hash256BS . encode' . Compressed False . pub_key . derivePublic
-- | Address was derived from an script hash. Though these addresses can represent the hash of any script, only redeem
-- scripts for multi-signature are currently supported.
isPay2SH :: Address net -> Bool
isPay2SH addr = case addr of
PubKeyAddress _ -> True
_ -> False
-- | Address was derived from a public key hash.
isPay2PKH :: Address net -> Bool
isPay2PKH addr = case addr of
ScriptAddress _ -> True
_ -> False
---------------------------------------------------------------------------------------------------------------------------------
instance (BlockNetwork net ) => Show (Address net) where
show = show_aux
where
show_aux :: forall net . (BlockNetwork net ) => Address net -> String
show_aux addr = let params = (valuesOf :: Params net)
in case addr of
PubKeyAddress payload -> show_ (addrPrefix params) payload
ScriptAddress payload -> show_ (scriptPrefix params) payload
instance (BlockNetwork net ) => Read (Address net) where
readsPrec _ = read_aux
where
read_aux :: forall net . (BlockNetwork net ) => ReadS (Address net)
read_aux str = let params = (valuesOf :: Params net)
in case readsPrec_ str of
( Just (prefix, payload), rest)
| addrPrefix params == prefix -> [(PubKeyAddress payload, rest)]
| scriptPrefix params == prefix -> [(ScriptAddress payload, rest)]
_ -> []
----------------------------------------------------------------------------------------------------------------------------------