{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE NoFieldSelectors #-}

-- |
-- Module      : Haskoin.Transaction.Common
-- Copyright   : No rights reserved
-- License     : MIT
-- Maintainer  : jprupp@protonmail.ch
-- Stability   : experimental
-- Portability : POSIX
--
-- Code related to transactions parsing and serialization.
module Haskoin.Transaction.Common
  ( -- * Transactions
    Tx (..),
    TxIn (..),
    TxOut (..),
    OutPoint (..),
    TxHash (..),
    WitnessData,
    WitnessStack,
    WitnessStackItem,
    txHash,
    hexToTxHash,
    txHashToHex,
    nosigTxHash,
    nullOutPoint,
  )
where

import Control.Applicative ((<|>))
import Control.DeepSeq
import Control.Monad (forM_, guard, liftM2, mzero, replicateM, unless, when, (<=<))
import Data.Aeson as A
import Data.Aeson.Encoding qualified as E
import Data.Binary (Binary (..))
import Data.Bool (bool)
import Data.ByteString (ByteString)
import Data.ByteString qualified as B
import Data.ByteString.Builder (char7)
import Data.ByteString.Lazy qualified as BL
import Data.Bytes.Get
import Data.Bytes.Put
import Data.Bytes.Serial
import Data.Hashable (Hashable)
import Data.Maybe (fromMaybe)
import Data.Serialize (Serialize (..))
import Data.String (IsString, fromString)
import Data.String.Conversions (cs)
import Data.Text (Text)
import Data.Word (Word32, Word64)
import GHC.Generics (Generic)
import Haskoin.Crypto.Hash
import Haskoin.Network.Common
import Haskoin.Util.Helpers
import Text.Read as R

-- | Transaction id: hash of transaction excluding witness data.
newtype TxHash = TxHash {TxHash -> Hash256
get :: Hash256}
  deriving (TxHash -> TxHash -> Bool
(TxHash -> TxHash -> Bool)
-> (TxHash -> TxHash -> Bool) -> Eq TxHash
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TxHash -> TxHash -> Bool
== :: TxHash -> TxHash -> Bool
$c/= :: TxHash -> TxHash -> Bool
/= :: TxHash -> TxHash -> Bool
Eq, Eq TxHash
Eq TxHash =>
(TxHash -> TxHash -> Ordering)
-> (TxHash -> TxHash -> Bool)
-> (TxHash -> TxHash -> Bool)
-> (TxHash -> TxHash -> Bool)
-> (TxHash -> TxHash -> Bool)
-> (TxHash -> TxHash -> TxHash)
-> (TxHash -> TxHash -> TxHash)
-> Ord TxHash
TxHash -> TxHash -> Bool
TxHash -> TxHash -> Ordering
TxHash -> TxHash -> TxHash
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
$ccompare :: TxHash -> TxHash -> Ordering
compare :: TxHash -> TxHash -> Ordering
$c< :: TxHash -> TxHash -> Bool
< :: TxHash -> TxHash -> Bool
$c<= :: TxHash -> TxHash -> Bool
<= :: TxHash -> TxHash -> Bool
$c> :: TxHash -> TxHash -> Bool
> :: TxHash -> TxHash -> Bool
$c>= :: TxHash -> TxHash -> Bool
>= :: TxHash -> TxHash -> Bool
$cmax :: TxHash -> TxHash -> TxHash
max :: TxHash -> TxHash -> TxHash
$cmin :: TxHash -> TxHash -> TxHash
min :: TxHash -> TxHash -> TxHash
Ord, (forall x. TxHash -> Rep TxHash x)
-> (forall x. Rep TxHash x -> TxHash) -> Generic TxHash
forall x. Rep TxHash x -> TxHash
forall x. TxHash -> Rep TxHash x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. TxHash -> Rep TxHash x
from :: forall x. TxHash -> Rep TxHash x
$cto :: forall x. Rep TxHash x -> TxHash
to :: forall x. Rep TxHash x -> TxHash
Generic)
  deriving newtype (Eq TxHash
Eq TxHash =>
(Int -> TxHash -> Int) -> (TxHash -> Int) -> Hashable TxHash
Int -> TxHash -> Int
TxHash -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> TxHash -> Int
hashWithSalt :: Int -> TxHash -> Int
$chash :: TxHash -> Int
hash :: TxHash -> Int
Hashable, TxHash -> ()
(TxHash -> ()) -> NFData TxHash
forall a. (a -> ()) -> NFData a
$crnf :: TxHash -> ()
rnf :: TxHash -> ()
NFData)

instance Serial TxHash where
  serialize :: forall (m :: * -> *). MonadPut m => TxHash -> m ()
serialize (TxHash Hash256
h) = Hash256 -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => Hash256 -> m ()
serialize Hash256
h
  deserialize :: forall (m :: * -> *). MonadGet m => m TxHash
deserialize = Hash256 -> TxHash
TxHash (Hash256 -> TxHash) -> m Hash256 -> m TxHash
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Hash256
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m Hash256
deserialize

instance Serialize TxHash where
  put :: Putter TxHash
put = Putter TxHash
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => TxHash -> m ()
serialize
  get :: Get TxHash
get = Get TxHash
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m TxHash
deserialize

instance Binary TxHash where
  put :: TxHash -> Put
put = TxHash -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => TxHash -> m ()
serialize
  get :: Get TxHash
get = Get TxHash
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m TxHash
deserialize

instance Show TxHash where
  showsPrec :: Int -> TxHash -> ShowS
showsPrec Int
_ = Text -> ShowS
forall a. Show a => a -> ShowS
shows (Text -> ShowS) -> (TxHash -> Text) -> TxHash -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TxHash -> Text
txHashToHex

instance Read TxHash where
  readPrec :: ReadPrec TxHash
readPrec = do
    R.String String
str <- ReadPrec Lexeme
R.lexP
    ReadPrec TxHash
-> (TxHash -> ReadPrec TxHash) -> Maybe TxHash -> ReadPrec TxHash
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ReadPrec TxHash
forall a. ReadPrec a
R.pfail TxHash -> ReadPrec TxHash
forall a. a -> ReadPrec a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TxHash -> ReadPrec TxHash)
-> Maybe TxHash -> ReadPrec TxHash
forall a b. (a -> b) -> a -> b
$ Text -> Maybe TxHash
hexToTxHash (Text -> Maybe TxHash) -> Text -> Maybe TxHash
forall a b. (a -> b) -> a -> b
$ String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs String
str

instance IsString TxHash where
  fromString :: String -> TxHash
fromString String
s =
    let e :: a
e = String -> a
forall a. HasCallStack => String -> a
error String
"Could not read transaction hash from hex string"
     in TxHash -> Maybe TxHash -> TxHash
forall a. a -> Maybe a -> a
fromMaybe TxHash
forall {a}. a
e (Maybe TxHash -> TxHash) -> Maybe TxHash -> TxHash
forall a b. (a -> b) -> a -> b
$ Text -> Maybe TxHash
hexToTxHash (Text -> Maybe TxHash) -> Text -> Maybe TxHash
forall a b. (a -> b) -> a -> b
$ String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs String
s

instance FromJSON TxHash where
  parseJSON :: Value -> Parser TxHash
parseJSON =
    String -> (Text -> Parser TxHash) -> Value -> Parser TxHash
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"txid" ((Text -> Parser TxHash) -> Value -> Parser TxHash)
-> (Text -> Parser TxHash) -> Value -> Parser TxHash
forall a b. (a -> b) -> a -> b
$
      Parser TxHash
-> (TxHash -> Parser TxHash) -> Maybe TxHash -> Parser TxHash
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Parser TxHash
forall a. Parser a
forall (m :: * -> *) a. MonadPlus m => m a
mzero TxHash -> Parser TxHash
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TxHash -> Parser TxHash)
-> (Text -> Maybe TxHash) -> Text -> Parser TxHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe TxHash
hexToTxHash

instance ToJSON TxHash where
  toJSON :: TxHash -> Value
toJSON = Text -> Value
A.String (Text -> Value) -> (TxHash -> Text) -> TxHash -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TxHash -> Text
txHashToHex
  toEncoding :: TxHash -> Encoding
toEncoding = ByteString -> Encoding
hexEncoding (ByteString -> Encoding)
-> (TxHash -> ByteString) -> TxHash -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
BL.reverse (ByteString -> ByteString)
-> (TxHash -> ByteString) -> TxHash -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
runPutL (Put -> ByteString) -> (TxHash -> Put) -> TxHash -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TxHash -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => TxHash -> m ()
serialize

-- | Transaction hash excluding signatures.
nosigTxHash :: Tx -> TxHash
nosigTxHash :: Tx -> TxHash
nosigTxHash Tx {WitnessData
[TxOut]
[TxIn]
Word32
version :: Word32
inputs :: [TxIn]
outputs :: [TxOut]
witness :: WitnessData
locktime :: Word32
$sel:version:Tx :: Tx -> Word32
$sel:inputs:Tx :: Tx -> [TxIn]
$sel:outputs:Tx :: Tx -> [TxOut]
$sel:witness:Tx :: Tx -> WitnessData
$sel:locktime:Tx :: Tx -> Word32
..} =
  Hash256 -> TxHash
TxHash (Hash256 -> TxHash) -> (Put -> Hash256) -> Put -> TxHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Hash256
forall b. ByteArrayAccess b => b -> Hash256
doubleSHA256 (ByteString -> Hash256) -> (Put -> ByteString) -> Put -> Hash256
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
runPutS (Put -> TxHash) -> Put -> TxHash
forall a b. (a -> b) -> a -> b
$ Tx -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => Tx -> m ()
serialize Tx
tx
  where
    tx :: Tx
tx = Tx {$sel:inputs:Tx :: [TxIn]
inputs = (TxIn -> TxIn) -> [TxIn] -> [TxIn]
forall a b. (a -> b) -> [a] -> [b]
map TxIn -> TxIn
clr [TxIn]
inputs, WitnessData
[TxOut]
Word32
version :: Word32
outputs :: [TxOut]
witness :: WitnessData
locktime :: Word32
$sel:version:Tx :: Word32
$sel:outputs:Tx :: [TxOut]
$sel:witness:Tx :: WitnessData
$sel:locktime:Tx :: Word32
..}
    clr :: TxIn -> TxIn
clr TxIn {Word32
ByteString
OutPoint
outpoint :: OutPoint
script :: ByteString
sequence :: Word32
$sel:outpoint:TxIn :: TxIn -> OutPoint
$sel:script:TxIn :: TxIn -> ByteString
$sel:sequence:TxIn :: TxIn -> Word32
..} = TxIn {$sel:script:TxIn :: ByteString
script = ByteString
B.empty, Word32
OutPoint
outpoint :: OutPoint
sequence :: Word32
$sel:outpoint:TxIn :: OutPoint
$sel:sequence:TxIn :: Word32
..}

-- | Convert transaction hash to hex form, reversing bytes.
txHashToHex :: TxHash -> Text
txHashToHex :: TxHash -> Text
txHashToHex (TxHash Hash256
h) =
  ByteString -> Text
encodeHex (ByteString -> Text) -> (Put -> ByteString) -> Put -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
B.reverse (ByteString -> ByteString)
-> (Put -> ByteString) -> Put -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
runPutS (Put -> Text) -> Put -> Text
forall a b. (a -> b) -> a -> b
$ Hash256 -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => Hash256 -> m ()
serialize Hash256
h

-- | Convert transaction hash from hex, reversing bytes.
hexToTxHash :: Text -> Maybe TxHash
hexToTxHash :: Text -> Maybe TxHash
hexToTxHash Text
hex = do
  ByteString
bs <- ByteString -> ByteString
B.reverse (ByteString -> ByteString) -> Maybe ByteString -> Maybe ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Maybe ByteString
decodeHex Text
hex
  Hash256
h <- (String -> Maybe Hash256)
-> (Hash256 -> Maybe Hash256)
-> Either String Hash256
-> Maybe Hash256
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe Hash256 -> String -> Maybe Hash256
forall a b. a -> b -> a
const Maybe Hash256
forall a. Maybe a
Nothing) Hash256 -> Maybe Hash256
forall a. a -> Maybe a
Just (Get Hash256 -> ByteString -> Either String Hash256
forall a. Get a -> ByteString -> Either String a
runGetS Get Hash256
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m Hash256
deserialize ByteString
bs)
  TxHash -> Maybe TxHash
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (TxHash -> Maybe TxHash) -> TxHash -> Maybe TxHash
forall a b. (a -> b) -> a -> b
$ Hash256 -> TxHash
TxHash Hash256
h

-- | Witness stack for SegWit transactions.
type WitnessData = [WitnessStack]

-- | Witness stack for SegWit transactions.
type WitnessStack = [WitnessStackItem]

-- | Witness stack item for SegWit transactions.
type WitnessStackItem = ByteString

-- | Data type representing a transaction.
data Tx = Tx
  { -- | transaction data format version
    Tx -> Word32
version :: !Word32,
    -- | list of transaction inputs
    Tx -> [TxIn]
inputs :: ![TxIn],
    -- | list of transaction outputs
    Tx -> [TxOut]
outputs :: ![TxOut],
    -- | witness data for the transaction
    Tx -> WitnessData
witness :: !WitnessData,
    -- | earliest mining height or time
    Tx -> Word32
locktime :: !Word32
  }
  deriving (Int -> Tx -> ShowS
[Tx] -> ShowS
Tx -> String
(Int -> Tx -> ShowS)
-> (Tx -> String) -> ([Tx] -> ShowS) -> Show Tx
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Tx -> ShowS
showsPrec :: Int -> Tx -> ShowS
$cshow :: Tx -> String
show :: Tx -> String
$cshowList :: [Tx] -> ShowS
showList :: [Tx] -> ShowS
Show, ReadPrec [Tx]
ReadPrec Tx
Int -> ReadS Tx
ReadS [Tx]
(Int -> ReadS Tx)
-> ReadS [Tx] -> ReadPrec Tx -> ReadPrec [Tx] -> Read Tx
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Tx
readsPrec :: Int -> ReadS Tx
$creadList :: ReadS [Tx]
readList :: ReadS [Tx]
$creadPrec :: ReadPrec Tx
readPrec :: ReadPrec Tx
$creadListPrec :: ReadPrec [Tx]
readListPrec :: ReadPrec [Tx]
Read, Tx -> Tx -> Bool
(Tx -> Tx -> Bool) -> (Tx -> Tx -> Bool) -> Eq Tx
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Tx -> Tx -> Bool
== :: Tx -> Tx -> Bool
$c/= :: Tx -> Tx -> Bool
/= :: Tx -> Tx -> Bool
Eq, Eq Tx
Eq Tx =>
(Tx -> Tx -> Ordering)
-> (Tx -> Tx -> Bool)
-> (Tx -> Tx -> Bool)
-> (Tx -> Tx -> Bool)
-> (Tx -> Tx -> Bool)
-> (Tx -> Tx -> Tx)
-> (Tx -> Tx -> Tx)
-> Ord Tx
Tx -> Tx -> Bool
Tx -> Tx -> Ordering
Tx -> Tx -> Tx
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
$ccompare :: Tx -> Tx -> Ordering
compare :: Tx -> Tx -> Ordering
$c< :: Tx -> Tx -> Bool
< :: Tx -> Tx -> Bool
$c<= :: Tx -> Tx -> Bool
<= :: Tx -> Tx -> Bool
$c> :: Tx -> Tx -> Bool
> :: Tx -> Tx -> Bool
$c>= :: Tx -> Tx -> Bool
>= :: Tx -> Tx -> Bool
$cmax :: Tx -> Tx -> Tx
max :: Tx -> Tx -> Tx
$cmin :: Tx -> Tx -> Tx
min :: Tx -> Tx -> Tx
Ord, (forall x. Tx -> Rep Tx x)
-> (forall x. Rep Tx x -> Tx) -> Generic Tx
forall x. Rep Tx x -> Tx
forall x. Tx -> Rep Tx x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Tx -> Rep Tx x
from :: forall x. Tx -> Rep Tx x
$cto :: forall x. Rep Tx x -> Tx
to :: forall x. Rep Tx x -> Tx
Generic, Eq Tx
Eq Tx => (Int -> Tx -> Int) -> (Tx -> Int) -> Hashable Tx
Int -> Tx -> Int
Tx -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> Tx -> Int
hashWithSalt :: Int -> Tx -> Int
$chash :: Tx -> Int
hash :: Tx -> Int
Hashable, Tx -> ()
(Tx -> ()) -> NFData Tx
forall a. (a -> ()) -> NFData a
$crnf :: Tx -> ()
rnf :: Tx -> ()
NFData)

-- | Compute transaction hash.
txHash :: Tx -> TxHash
txHash :: Tx -> TxHash
txHash Tx
tx = Hash256 -> TxHash
TxHash (Hash256 -> TxHash) -> (Put -> Hash256) -> Put -> TxHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Hash256
forall b. ByteArrayAccess b => b -> Hash256
doubleSHA256 (ByteString -> Hash256) -> (Put -> ByteString) -> Put -> Hash256
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
runPutS (Put -> TxHash) -> Put -> TxHash
forall a b. (a -> b) -> a -> b
$ Tx -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => Tx -> m ()
serialize Tx
tx {witness = []}

instance IsString Tx where
  fromString :: String -> Tx
fromString =
    Tx -> Maybe Tx -> Tx
forall a. a -> Maybe a -> a
fromMaybe Tx
forall {a}. a
e (Maybe Tx -> Tx) -> (String -> Maybe Tx) -> String -> Tx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Either String Tx -> Maybe Tx
forall a b. Either a b -> Maybe b
eitherToMaybe (Either String Tx -> Maybe Tx)
-> (ByteString -> Either String Tx) -> ByteString -> Maybe Tx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Get Tx -> ByteString -> Either String Tx
forall a. Get a -> ByteString -> Either String a
runGetS Get Tx
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m Tx
deserialize (ByteString -> Maybe Tx)
-> (Text -> Maybe ByteString) -> Text -> Maybe Tx
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Text -> Maybe ByteString
decodeHex) (Text -> Maybe Tx) -> (String -> Text) -> String -> Maybe Tx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs
    where
      e :: a
e = String -> a
forall a. HasCallStack => String -> a
error String
"Could not read transaction from hex string"

instance Serial Tx where
  deserialize :: forall (m :: * -> *). MonadGet m => m Tx
deserialize = m Bool
forall (m :: * -> *). MonadGet m => m Bool
isWitnessTx m Bool -> (Bool -> m Tx) -> m Tx
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= m Tx -> m Tx -> Bool -> m Tx
forall a. a -> a -> Bool -> a
bool m Tx
forall (m :: * -> *). MonadGet m => m Tx
parseLegacyTx m Tx
forall (m :: * -> *). MonadGet m => m Tx
parseWitnessTx
  serialize :: forall (m :: * -> *). MonadPut m => Tx -> m ()
serialize Tx
tx
    | WitnessData -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Tx
tx.witness = Tx -> m ()
forall (m :: * -> *). MonadPut m => Tx -> m ()
putLegacyTx Tx
tx
    | Bool
otherwise = Tx -> m ()
forall (m :: * -> *). MonadPut m => Tx -> m ()
putWitnessTx Tx
tx

instance Binary Tx where
  put :: Tx -> Put
put = Tx -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => Tx -> m ()
serialize
  get :: Get Tx
get = Get Tx
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m Tx
deserialize

instance Serialize Tx where
  put :: Tx -> Put
put = Tx -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => Tx -> m ()
serialize
  get :: Get Tx
get = Get Tx
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m Tx
deserialize

putInOut :: (MonadPut m) => Tx -> m ()
putInOut :: forall (m :: * -> *). MonadPut m => Tx -> m ()
putInOut Tx
tx = do
  Int -> m ()
forall (m :: * -> *) a. (MonadPut m, Integral a) => a -> m ()
putVarInt (Int -> m ()) -> Int -> m ()
forall a b. (a -> b) -> a -> b
$ [TxIn] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Tx
tx.inputs
  (TxIn -> m ()) -> [TxIn] -> m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ TxIn -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => TxIn -> m ()
serialize Tx
tx.inputs
  Int -> m ()
forall (m :: * -> *) a. (MonadPut m, Integral a) => a -> m ()
putVarInt (Int -> m ()) -> Int -> m ()
forall a b. (a -> b) -> a -> b
$ [TxOut] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Tx
tx.outputs
  (TxOut -> m ()) -> [TxOut] -> m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ TxOut -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => TxOut -> m ()
serialize Tx
tx.outputs

-- | Non-SegWit transaction serializer.
putLegacyTx :: (MonadPut m) => Tx -> m ()
putLegacyTx :: forall (m :: * -> *). MonadPut m => Tx -> m ()
putLegacyTx Tx
tx = do
  Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32le Tx
tx.version
  Tx -> m ()
forall (m :: * -> *). MonadPut m => Tx -> m ()
putInOut Tx
tx
  Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32le Tx
tx.locktime

-- | Witness transaciton serializer.
putWitnessTx :: (MonadPut m) => Tx -> m ()
putWitnessTx :: forall (m :: * -> *). MonadPut m => Tx -> m ()
putWitnessTx Tx
tx = do
  Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32le Tx
tx.version
  Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 Word8
0x00
  Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 Word8
0x01
  Tx -> m ()
forall (m :: * -> *). MonadPut m => Tx -> m ()
putInOut Tx
tx
  WitnessData -> m ()
forall (m :: * -> *). MonadPut m => WitnessData -> m ()
putWitnessData Tx
tx.witness
  Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32le Tx
tx.locktime

isWitnessTx :: (MonadGet m) => m Bool
isWitnessTx :: forall (m :: * -> *). MonadGet m => m Bool
isWitnessTx = m Bool -> m Bool
forall a. m a -> m a
forall (m :: * -> *) a. MonadGet m => m a -> m a
lookAhead (m Bool -> m Bool) -> m Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ do
  Word32
_ <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32le
  Word8
m <- m Word8
forall (m :: * -> *). MonadGet m => m Word8
getWord8
  Word8
f <- m Word8
forall (m :: * -> *). MonadGet m => m Word8
getWord8
  Bool -> m Bool
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
m Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0x00 Bool -> Bool -> Bool
&& Word8
f Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0x01)

-- | Non-SegWit transaction deseralizer.
parseLegacyTx :: (MonadGet m) => m Tx
parseLegacyTx :: forall (m :: * -> *). MonadGet m => m Tx
parseLegacyTx = do
  Word32
version <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32le
  [TxIn]
inputs <- VarInt -> m [TxIn]
forall {m :: * -> *} {a}. (Serial a, MonadGet m) => VarInt -> m [a]
rl (VarInt -> m [TxIn]) -> m VarInt -> m [TxIn]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m VarInt
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m VarInt
deserialize
  [TxOut]
outputs <- VarInt -> m [TxOut]
forall {m :: * -> *} {a}. (Serial a, MonadGet m) => VarInt -> m [a]
rl (VarInt -> m [TxOut]) -> m VarInt -> m [TxOut]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m VarInt
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m VarInt
deserialize
  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([TxIn] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [TxIn]
inputs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0x00 Bool -> Bool -> Bool
&& [TxOut] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [TxOut]
outputs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0x01) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
    String -> m ()
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Witness transaction"
  Word32
locktime <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32le
  Tx -> m Tx
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Tx {$sel:witness:Tx :: WitnessData
witness = [], [TxOut]
[TxIn]
Word32
$sel:version:Tx :: Word32
$sel:inputs:Tx :: [TxIn]
$sel:outputs:Tx :: [TxOut]
$sel:locktime:Tx :: Word32
version :: Word32
inputs :: [TxIn]
outputs :: [TxOut]
locktime :: Word32
..}
  where
    rl :: VarInt -> m [a]
rl (VarInt Word64
c) = Int -> m a -> m [a]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
c) m a
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m a
deserialize

-- | Witness transaction deserializer.
parseWitnessTx :: (MonadGet m) => m Tx
parseWitnessTx :: forall (m :: * -> *). MonadGet m => m Tx
parseWitnessTx = do
  Word32
version <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32le
  Word8
m <- m Word8
forall (m :: * -> *). MonadGet m => m Word8
getWord8
  Word8
f <- m Word8
forall (m :: * -> *). MonadGet m => m Word8
getWord8
  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Word8
m Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0x00 Bool -> Bool -> Bool
&& Word8
f Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0x01) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ String -> m ()
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Not a witness transaction"
  [TxIn]
inputs <- VarInt -> m [TxIn]
forall {m :: * -> *} {a}. (Serial a, MonadGet m) => VarInt -> m [a]
replicateList (VarInt -> m [TxIn]) -> m VarInt -> m [TxIn]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m VarInt
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m VarInt
deserialize
  [TxOut]
outputs <- VarInt -> m [TxOut]
forall {m :: * -> *} {a}. (Serial a, MonadGet m) => VarInt -> m [a]
replicateList (VarInt -> m [TxOut]) -> m VarInt -> m [TxOut]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m VarInt
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m VarInt
deserialize
  WitnessData
witness <- Int -> m WitnessData
forall (m :: * -> *). MonadGet m => Int -> m WitnessData
parseWitnessData (Int -> m WitnessData) -> Int -> m WitnessData
forall a b. (a -> b) -> a -> b
$ [TxIn] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [TxIn]
inputs
  Word32
locktime <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32le
  Tx -> m Tx
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Tx {WitnessData
[TxOut]
[TxIn]
Word32
$sel:version:Tx :: Word32
$sel:inputs:Tx :: [TxIn]
$sel:outputs:Tx :: [TxOut]
$sel:witness:Tx :: WitnessData
$sel:locktime:Tx :: Word32
version :: Word32
inputs :: [TxIn]
outputs :: [TxOut]
witness :: WitnessData
locktime :: Word32
..}
  where
    replicateList :: VarInt -> m [a]
replicateList (VarInt Word64
c) = Int -> m a -> m [a]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
c) m a
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m a
deserialize

-- | Witness data deserializer. Requires count of inputs.
parseWitnessData :: (MonadGet m) => Int -> m WitnessData
parseWitnessData :: forall (m :: * -> *). MonadGet m => Int -> m WitnessData
parseWitnessData Int
n = Int -> m [ByteString] -> m WitnessData
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n m [ByteString]
parseWitnessStack
  where
    parseWitnessStack :: m [ByteString]
parseWitnessStack = do
      VarInt Word64
i <- m VarInt
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m VarInt
deserialize
      Int -> m ByteString -> m [ByteString]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i) m ByteString
parseWitnessStackItem
    parseWitnessStackItem :: m ByteString
parseWitnessStackItem = do
      VarInt Word64
i <- m VarInt
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m VarInt
deserialize
      Int -> m ByteString
forall (m :: * -> *). MonadGet m => Int -> m ByteString
getByteString (Int -> m ByteString) -> Int -> m ByteString
forall a b. (a -> b) -> a -> b
$ Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i

-- | Witness data serializer.
putWitnessData :: (MonadPut m) => WitnessData -> m ()
putWitnessData :: forall (m :: * -> *). MonadPut m => WitnessData -> m ()
putWitnessData = ([ByteString] -> m ()) -> WitnessData -> m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ [ByteString] -> m ()
forall {m :: * -> *} {t :: * -> *}.
(MonadPut m, Foldable t) =>
t ByteString -> m ()
putWitnessStack
  where
    putWitnessStack :: t ByteString -> m ()
putWitnessStack t ByteString
ws = do
      Int -> m ()
forall (m :: * -> *) a. (MonadPut m, Integral a) => a -> m ()
putVarInt (Int -> m ()) -> Int -> m ()
forall a b. (a -> b) -> a -> b
$ t ByteString -> Int
forall a. t a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length t ByteString
ws
      (ByteString -> m ()) -> t ByteString -> m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ByteString -> m ()
forall {m :: * -> *}. MonadPut m => ByteString -> m ()
putWitnessStackItem t ByteString
ws
    putWitnessStackItem :: ByteString -> m ()
putWitnessStackItem ByteString
bs = do
      Int -> m ()
forall (m :: * -> *) a. (MonadPut m, Integral a) => a -> m ()
putVarInt (Int -> m ()) -> Int -> m ()
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
B.length ByteString
bs
      ByteString -> m ()
forall {m :: * -> *}. MonadPut m => ByteString -> m ()
putByteString ByteString
bs

instance FromJSON Tx where
  parseJSON :: Value -> Parser Tx
parseJSON = String -> (Object -> Parser Tx) -> Value -> Parser Tx
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"Tx" ((Object -> Parser Tx) -> Value -> Parser Tx)
-> (Object -> Parser Tx) -> Value -> Parser Tx
forall a b. (a -> b) -> a -> b
$ \Object
o ->
    Word32 -> [TxIn] -> [TxOut] -> WitnessData -> Word32 -> Tx
Tx
      (Word32 -> [TxIn] -> [TxOut] -> WitnessData -> Word32 -> Tx)
-> Parser Word32
-> Parser ([TxIn] -> [TxOut] -> WitnessData -> Word32 -> Tx)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser Word32
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"version"
      Parser ([TxIn] -> [TxOut] -> WitnessData -> Word32 -> Tx)
-> Parser [TxIn] -> Parser ([TxOut] -> WitnessData -> Word32 -> Tx)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser [TxIn]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"inputs"
      Parser ([TxOut] -> WitnessData -> Word32 -> Tx)
-> Parser [TxOut] -> Parser (WitnessData -> Word32 -> Tx)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser [TxOut]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"outputs"
      Parser (WitnessData -> Word32 -> Tx)
-> Parser WitnessData -> Parser (Word32 -> Tx)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (([Text] -> Parser [ByteString]) -> [[Text]] -> Parser WitnessData
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM ((Text -> Parser ByteString) -> [Text] -> Parser [ByteString]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Text -> Parser ByteString
f) ([[Text]] -> Parser WitnessData)
-> Parser [[Text]] -> Parser WitnessData
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Object
o Object -> Key -> Parser [[Text]]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"witnessdata")
      Parser (Word32 -> Tx) -> Parser Word32 -> Parser Tx
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser Word32
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"locktime"
    where
      f :: Text -> Parser ByteString
f = Parser ByteString
-> (ByteString -> Parser ByteString)
-> Maybe ByteString
-> Parser ByteString
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Parser ByteString
forall a. Parser a
forall (m :: * -> *) a. MonadPlus m => m a
mzero ByteString -> Parser ByteString
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe ByteString -> Parser ByteString)
-> (Text -> Maybe ByteString) -> Text -> Parser ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe ByteString
decodeHex

instance ToJSON Tx where
  toJSON :: Tx -> Value
toJSON (Tx Word32
v [TxIn]
i [TxOut]
o WitnessData
w Word32
l) =
    [Pair] -> Value
object
      [ Key
"version" Key -> Word32 -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Word32
v,
        Key
"inputs" Key -> [TxIn] -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= [TxIn]
i,
        Key
"outputs" Key -> [TxOut] -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= [TxOut]
o,
        Key
"witnessdata" Key -> [[Text]] -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= ([ByteString] -> [Text]) -> WitnessData -> [[Text]]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((ByteString -> Text) -> [ByteString] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> Text
encodeHex) WitnessData
w,
        Key
"locktime" Key -> Word32 -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Word32
l
      ]
  toEncoding :: Tx -> Encoding
toEncoding (Tx Word32
v [TxIn]
i [TxOut]
o WitnessData
w Word32
l) =
    Series -> Encoding
pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$
      [Series] -> Series
forall a. Monoid a => [a] -> a
mconcat
        [ Key
"version" Key -> Encoding -> Series
`E.pair` Word32 -> Encoding
E.word32 Word32
v,
          Key
"inputs" Key -> Encoding -> Series
`E.pair` (TxIn -> Encoding) -> [TxIn] -> Encoding
forall a. (a -> Encoding) -> [a] -> Encoding
E.list TxIn -> Encoding
forall a. ToJSON a => a -> Encoding
toEncoding [TxIn]
i,
          Key
"outputs" Key -> Encoding -> Series
`E.pair` (TxOut -> Encoding) -> [TxOut] -> Encoding
forall a. (a -> Encoding) -> [a] -> Encoding
E.list TxOut -> Encoding
forall a. ToJSON a => a -> Encoding
toEncoding [TxOut]
o,
          Key
"witnessdata" Key -> Encoding -> Series
`E.pair` ([ByteString] -> Encoding) -> WitnessData -> Encoding
forall a. (a -> Encoding) -> [a] -> Encoding
E.list ((ByteString -> Encoding) -> [ByteString] -> Encoding
forall a. (a -> Encoding) -> [a] -> Encoding
E.list ByteString -> Encoding
f) WitnessData
w,
          Key
"locktime" Key -> Encoding -> Series
`E.pair` Word32 -> Encoding
E.word32 Word32
l
        ]
    where
      f :: ByteString -> Encoding
f = ByteString -> Encoding
hexEncoding (ByteString -> Encoding)
-> (ByteString -> ByteString) -> ByteString -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
BL.fromStrict

-- | Data type representing a transaction input.
data TxIn = TxIn
  { -- | output being spent
    TxIn -> OutPoint
outpoint :: !OutPoint,
    -- | signatures and redeem script
    TxIn -> ByteString
script :: !ByteString,
    -- | lock-time using sequence numbers (BIP-68)
    TxIn -> Word32
sequence :: !Word32
  }
  deriving (TxIn -> TxIn -> Bool
(TxIn -> TxIn -> Bool) -> (TxIn -> TxIn -> Bool) -> Eq TxIn
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TxIn -> TxIn -> Bool
== :: TxIn -> TxIn -> Bool
$c/= :: TxIn -> TxIn -> Bool
/= :: TxIn -> TxIn -> Bool
Eq, Int -> TxIn -> ShowS
[TxIn] -> ShowS
TxIn -> String
(Int -> TxIn -> ShowS)
-> (TxIn -> String) -> ([TxIn] -> ShowS) -> Show TxIn
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TxIn -> ShowS
showsPrec :: Int -> TxIn -> ShowS
$cshow :: TxIn -> String
show :: TxIn -> String
$cshowList :: [TxIn] -> ShowS
showList :: [TxIn] -> ShowS
Show, ReadPrec [TxIn]
ReadPrec TxIn
Int -> ReadS TxIn
ReadS [TxIn]
(Int -> ReadS TxIn)
-> ReadS [TxIn] -> ReadPrec TxIn -> ReadPrec [TxIn] -> Read TxIn
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS TxIn
readsPrec :: Int -> ReadS TxIn
$creadList :: ReadS [TxIn]
readList :: ReadS [TxIn]
$creadPrec :: ReadPrec TxIn
readPrec :: ReadPrec TxIn
$creadListPrec :: ReadPrec [TxIn]
readListPrec :: ReadPrec [TxIn]
Read, Eq TxIn
Eq TxIn =>
(TxIn -> TxIn -> Ordering)
-> (TxIn -> TxIn -> Bool)
-> (TxIn -> TxIn -> Bool)
-> (TxIn -> TxIn -> Bool)
-> (TxIn -> TxIn -> Bool)
-> (TxIn -> TxIn -> TxIn)
-> (TxIn -> TxIn -> TxIn)
-> Ord TxIn
TxIn -> TxIn -> Bool
TxIn -> TxIn -> Ordering
TxIn -> TxIn -> TxIn
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
$ccompare :: TxIn -> TxIn -> Ordering
compare :: TxIn -> TxIn -> Ordering
$c< :: TxIn -> TxIn -> Bool
< :: TxIn -> TxIn -> Bool
$c<= :: TxIn -> TxIn -> Bool
<= :: TxIn -> TxIn -> Bool
$c> :: TxIn -> TxIn -> Bool
> :: TxIn -> TxIn -> Bool
$c>= :: TxIn -> TxIn -> Bool
>= :: TxIn -> TxIn -> Bool
$cmax :: TxIn -> TxIn -> TxIn
max :: TxIn -> TxIn -> TxIn
$cmin :: TxIn -> TxIn -> TxIn
min :: TxIn -> TxIn -> TxIn
Ord, (forall x. TxIn -> Rep TxIn x)
-> (forall x. Rep TxIn x -> TxIn) -> Generic TxIn
forall x. Rep TxIn x -> TxIn
forall x. TxIn -> Rep TxIn x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. TxIn -> Rep TxIn x
from :: forall x. TxIn -> Rep TxIn x
$cto :: forall x. Rep TxIn x -> TxIn
to :: forall x. Rep TxIn x -> TxIn
Generic, Eq TxIn
Eq TxIn => (Int -> TxIn -> Int) -> (TxIn -> Int) -> Hashable TxIn
Int -> TxIn -> Int
TxIn -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> TxIn -> Int
hashWithSalt :: Int -> TxIn -> Int
$chash :: TxIn -> Int
hash :: TxIn -> Int
Hashable, TxIn -> ()
(TxIn -> ()) -> NFData TxIn
forall a. (a -> ()) -> NFData a
$crnf :: TxIn -> ()
rnf :: TxIn -> ()
NFData)

instance Serial TxIn where
  deserialize :: forall (m :: * -> *). MonadGet m => m TxIn
deserialize =
    OutPoint -> ByteString -> Word32 -> TxIn
TxIn (OutPoint -> ByteString -> Word32 -> TxIn)
-> m OutPoint -> m (ByteString -> Word32 -> TxIn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m OutPoint
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m OutPoint
deserialize m (ByteString -> Word32 -> TxIn)
-> m ByteString -> m (Word32 -> TxIn)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (VarInt -> m ByteString
forall {m :: * -> *}. MonadGet m => VarInt -> m ByteString
readBS (VarInt -> m ByteString) -> m VarInt -> m ByteString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m VarInt
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m VarInt
deserialize) m (Word32 -> TxIn) -> m Word32 -> m TxIn
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32le
    where
      readBS :: VarInt -> m ByteString
readBS (VarInt Word64
len) = Int -> m ByteString
forall (m :: * -> *). MonadGet m => Int -> m ByteString
getByteString (Int -> m ByteString) -> Int -> m ByteString
forall a b. (a -> b) -> a -> b
$ Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
len

  serialize :: forall (m :: * -> *). MonadPut m => TxIn -> m ()
serialize (TxIn OutPoint
o ByteString
s Word32
q) = do
    OutPoint -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => OutPoint -> m ()
serialize OutPoint
o
    Int -> m ()
forall (m :: * -> *) a. (MonadPut m, Integral a) => a -> m ()
putVarInt (Int -> m ()) -> Int -> m ()
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
B.length ByteString
s
    ByteString -> m ()
forall {m :: * -> *}. MonadPut m => ByteString -> m ()
putByteString ByteString
s
    Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32le Word32
q

instance Binary TxIn where
  get :: Get TxIn
get = Get TxIn
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m TxIn
deserialize
  put :: TxIn -> Put
put = TxIn -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => TxIn -> m ()
serialize

instance Serialize TxIn where
  get :: Get TxIn
get = Get TxIn
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m TxIn
deserialize
  put :: Putter TxIn
put = Putter TxIn
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => TxIn -> m ()
serialize

instance FromJSON TxIn where
  parseJSON :: Value -> Parser TxIn
parseJSON =
    String -> (Object -> Parser TxIn) -> Value -> Parser TxIn
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"TxIn" ((Object -> Parser TxIn) -> Value -> Parser TxIn)
-> (Object -> Parser TxIn) -> Value -> Parser TxIn
forall a b. (a -> b) -> a -> b
$ \Object
o ->
      OutPoint -> ByteString -> Word32 -> TxIn
TxIn
        (OutPoint -> ByteString -> Word32 -> TxIn)
-> Parser OutPoint -> Parser (ByteString -> Word32 -> TxIn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser OutPoint
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"prevoutput"
        Parser (ByteString -> Word32 -> TxIn)
-> Parser ByteString -> Parser (Word32 -> TxIn)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Parser ByteString
-> (ByteString -> Parser ByteString)
-> Maybe ByteString
-> Parser ByteString
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Parser ByteString
forall a. Parser a
forall (m :: * -> *) a. MonadPlus m => m a
mzero ByteString -> Parser ByteString
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe ByteString -> Parser ByteString)
-> (Text -> Maybe ByteString) -> Text -> Parser ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe ByteString
decodeHex (Text -> Parser ByteString) -> Parser Text -> Parser ByteString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"inputscript")
        Parser (Word32 -> TxIn) -> Parser Word32 -> Parser TxIn
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser Word32
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sequence"

instance ToJSON TxIn where
  toJSON :: TxIn -> Value
toJSON (TxIn OutPoint
o ByteString
s Word32
q) =
    [Pair] -> Value
object
      [ Key
"prevoutput" Key -> OutPoint -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= OutPoint
o,
        Key
"inputscript" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= ByteString -> Text
encodeHex ByteString
s,
        Key
"sequence" Key -> Word32 -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Word32
q
      ]
  toEncoding :: TxIn -> Encoding
toEncoding (TxIn OutPoint
o ByteString
s Word32
q) =
    Series -> Encoding
pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$
      [Series] -> Series
forall a. Monoid a => [a] -> a
mconcat
        [ Key
"prevoutput" Key -> Encoding -> Series
`E.pair` OutPoint -> Encoding
forall a. ToJSON a => a -> Encoding
toEncoding OutPoint
o,
          Key
"inputscript" Key -> Encoding -> Series
`E.pair` ByteString -> Encoding
hexEncoding (ByteString -> ByteString
BL.fromStrict ByteString
s),
          Key
"sequence" Key -> Encoding -> Series
`E.pair` Word32 -> Encoding
E.word32 Word32
q
        ]

-- | Data type representing a transaction output.
data TxOut = TxOut
  { -- | value of output is satoshi
    TxOut -> Word64
value :: !Word64,
    -- | pubkey script
    TxOut -> ByteString
script :: !ByteString
  }
  deriving (TxOut -> TxOut -> Bool
(TxOut -> TxOut -> Bool) -> (TxOut -> TxOut -> Bool) -> Eq TxOut
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TxOut -> TxOut -> Bool
== :: TxOut -> TxOut -> Bool
$c/= :: TxOut -> TxOut -> Bool
/= :: TxOut -> TxOut -> Bool
Eq, Int -> TxOut -> ShowS
[TxOut] -> ShowS
TxOut -> String
(Int -> TxOut -> ShowS)
-> (TxOut -> String) -> ([TxOut] -> ShowS) -> Show TxOut
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TxOut -> ShowS
showsPrec :: Int -> TxOut -> ShowS
$cshow :: TxOut -> String
show :: TxOut -> String
$cshowList :: [TxOut] -> ShowS
showList :: [TxOut] -> ShowS
Show, ReadPrec [TxOut]
ReadPrec TxOut
Int -> ReadS TxOut
ReadS [TxOut]
(Int -> ReadS TxOut)
-> ReadS [TxOut]
-> ReadPrec TxOut
-> ReadPrec [TxOut]
-> Read TxOut
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS TxOut
readsPrec :: Int -> ReadS TxOut
$creadList :: ReadS [TxOut]
readList :: ReadS [TxOut]
$creadPrec :: ReadPrec TxOut
readPrec :: ReadPrec TxOut
$creadListPrec :: ReadPrec [TxOut]
readListPrec :: ReadPrec [TxOut]
Read, Eq TxOut
Eq TxOut =>
(TxOut -> TxOut -> Ordering)
-> (TxOut -> TxOut -> Bool)
-> (TxOut -> TxOut -> Bool)
-> (TxOut -> TxOut -> Bool)
-> (TxOut -> TxOut -> Bool)
-> (TxOut -> TxOut -> TxOut)
-> (TxOut -> TxOut -> TxOut)
-> Ord TxOut
TxOut -> TxOut -> Bool
TxOut -> TxOut -> Ordering
TxOut -> TxOut -> TxOut
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
$ccompare :: TxOut -> TxOut -> Ordering
compare :: TxOut -> TxOut -> Ordering
$c< :: TxOut -> TxOut -> Bool
< :: TxOut -> TxOut -> Bool
$c<= :: TxOut -> TxOut -> Bool
<= :: TxOut -> TxOut -> Bool
$c> :: TxOut -> TxOut -> Bool
> :: TxOut -> TxOut -> Bool
$c>= :: TxOut -> TxOut -> Bool
>= :: TxOut -> TxOut -> Bool
$cmax :: TxOut -> TxOut -> TxOut
max :: TxOut -> TxOut -> TxOut
$cmin :: TxOut -> TxOut -> TxOut
min :: TxOut -> TxOut -> TxOut
Ord, (forall x. TxOut -> Rep TxOut x)
-> (forall x. Rep TxOut x -> TxOut) -> Generic TxOut
forall x. Rep TxOut x -> TxOut
forall x. TxOut -> Rep TxOut x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. TxOut -> Rep TxOut x
from :: forall x. TxOut -> Rep TxOut x
$cto :: forall x. Rep TxOut x -> TxOut
to :: forall x. Rep TxOut x -> TxOut
Generic, Eq TxOut
Eq TxOut =>
(Int -> TxOut -> Int) -> (TxOut -> Int) -> Hashable TxOut
Int -> TxOut -> Int
TxOut -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> TxOut -> Int
hashWithSalt :: Int -> TxOut -> Int
$chash :: TxOut -> Int
hash :: TxOut -> Int
Hashable, TxOut -> ()
(TxOut -> ()) -> NFData TxOut
forall a. (a -> ()) -> NFData a
$crnf :: TxOut -> ()
rnf :: TxOut -> ()
NFData)

instance Serial TxOut where
  deserialize :: forall (m :: * -> *). MonadGet m => m TxOut
deserialize = do
    Word64
val <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64le
    VarInt Word64
len <- m VarInt
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m VarInt
deserialize
    Word64 -> ByteString -> TxOut
TxOut Word64
val (ByteString -> TxOut) -> m ByteString -> m TxOut
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> m ByteString
forall (m :: * -> *). MonadGet m => Int -> m ByteString
getByteString (Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
len)

  serialize :: forall (m :: * -> *). MonadPut m => TxOut -> m ()
serialize (TxOut Word64
o ByteString
s) = do
    Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64le Word64
o
    Int -> m ()
forall (m :: * -> *) a. (MonadPut m, Integral a) => a -> m ()
putVarInt (Int -> m ()) -> Int -> m ()
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
B.length ByteString
s
    ByteString -> m ()
forall {m :: * -> *}. MonadPut m => ByteString -> m ()
putByteString ByteString
s

instance Binary TxOut where
  put :: TxOut -> Put
put = TxOut -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => TxOut -> m ()
serialize
  get :: Get TxOut
get = Get TxOut
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m TxOut
deserialize

instance Serialize TxOut where
  put :: Putter TxOut
put = Putter TxOut
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => TxOut -> m ()
serialize
  get :: Get TxOut
get = Get TxOut
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m TxOut
deserialize

instance FromJSON TxOut where
  parseJSON :: Value -> Parser TxOut
parseJSON =
    String -> (Object -> Parser TxOut) -> Value -> Parser TxOut
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"TxOut" ((Object -> Parser TxOut) -> Value -> Parser TxOut)
-> (Object -> Parser TxOut) -> Value -> Parser TxOut
forall a b. (a -> b) -> a -> b
$ \Object
o -> do
      Word64
value <- Object
o Object -> Key -> Parser Word64
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"value"
      Text
t <- Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"outputscript"
      ByteString
script <- Parser ByteString
-> (ByteString -> Parser ByteString)
-> Maybe ByteString
-> Parser ByteString
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Parser ByteString
forall a. Parser a
forall (m :: * -> *) a. MonadPlus m => m a
mzero ByteString -> Parser ByteString
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> Maybe ByteString
decodeHex Text
t)
      TxOut -> Parser TxOut
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return TxOut {Word64
ByteString
$sel:value:TxOut :: Word64
$sel:script:TxOut :: ByteString
value :: Word64
script :: ByteString
..}

instance ToJSON TxOut where
  toJSON :: TxOut -> Value
toJSON (TxOut Word64
o ByteString
s) =
    [Pair] -> Value
object [Key
"value" Key -> Word64 -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Word64
o, Key
"outputscript" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= ByteString -> Text
encodeHex ByteString
s]
  toEncoding :: TxOut -> Encoding
toEncoding (TxOut Word64
o ByteString
s) =
    Series -> Encoding
pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$
      [Series] -> Series
forall a. Monoid a => [a] -> a
mconcat
        [ Key
"value" Key -> Encoding -> Series
`E.pair` Word64 -> Encoding
E.word64 Word64
o,
          Key
"outputscript" Key -> Encoding -> Series
`E.pair` ByteString -> Encoding
hexEncoding (ByteString -> ByteString
BL.fromStrict ByteString
s)
        ]

-- | The 'OutPoint' refers to a transaction output being spent.
data OutPoint = OutPoint
  { -- | hash of previous transaction
    OutPoint -> TxHash
hash :: !TxHash,
    -- | position of output in previous transaction
    OutPoint -> Word32
index :: !Word32
  }
  deriving (Int -> OutPoint -> ShowS
[OutPoint] -> ShowS
OutPoint -> String
(Int -> OutPoint -> ShowS)
-> (OutPoint -> String) -> ([OutPoint] -> ShowS) -> Show OutPoint
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> OutPoint -> ShowS
showsPrec :: Int -> OutPoint -> ShowS
$cshow :: OutPoint -> String
show :: OutPoint -> String
$cshowList :: [OutPoint] -> ShowS
showList :: [OutPoint] -> ShowS
Show, ReadPrec [OutPoint]
ReadPrec OutPoint
Int -> ReadS OutPoint
ReadS [OutPoint]
(Int -> ReadS OutPoint)
-> ReadS [OutPoint]
-> ReadPrec OutPoint
-> ReadPrec [OutPoint]
-> Read OutPoint
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS OutPoint
readsPrec :: Int -> ReadS OutPoint
$creadList :: ReadS [OutPoint]
readList :: ReadS [OutPoint]
$creadPrec :: ReadPrec OutPoint
readPrec :: ReadPrec OutPoint
$creadListPrec :: ReadPrec [OutPoint]
readListPrec :: ReadPrec [OutPoint]
Read, OutPoint -> OutPoint -> Bool
(OutPoint -> OutPoint -> Bool)
-> (OutPoint -> OutPoint -> Bool) -> Eq OutPoint
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: OutPoint -> OutPoint -> Bool
== :: OutPoint -> OutPoint -> Bool
$c/= :: OutPoint -> OutPoint -> Bool
/= :: OutPoint -> OutPoint -> Bool
Eq, Eq OutPoint
Eq OutPoint =>
(OutPoint -> OutPoint -> Ordering)
-> (OutPoint -> OutPoint -> Bool)
-> (OutPoint -> OutPoint -> Bool)
-> (OutPoint -> OutPoint -> Bool)
-> (OutPoint -> OutPoint -> Bool)
-> (OutPoint -> OutPoint -> OutPoint)
-> (OutPoint -> OutPoint -> OutPoint)
-> Ord OutPoint
OutPoint -> OutPoint -> Bool
OutPoint -> OutPoint -> Ordering
OutPoint -> OutPoint -> OutPoint
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
$ccompare :: OutPoint -> OutPoint -> Ordering
compare :: OutPoint -> OutPoint -> Ordering
$c< :: OutPoint -> OutPoint -> Bool
< :: OutPoint -> OutPoint -> Bool
$c<= :: OutPoint -> OutPoint -> Bool
<= :: OutPoint -> OutPoint -> Bool
$c> :: OutPoint -> OutPoint -> Bool
> :: OutPoint -> OutPoint -> Bool
$c>= :: OutPoint -> OutPoint -> Bool
>= :: OutPoint -> OutPoint -> Bool
$cmax :: OutPoint -> OutPoint -> OutPoint
max :: OutPoint -> OutPoint -> OutPoint
$cmin :: OutPoint -> OutPoint -> OutPoint
min :: OutPoint -> OutPoint -> OutPoint
Ord, (forall x. OutPoint -> Rep OutPoint x)
-> (forall x. Rep OutPoint x -> OutPoint) -> Generic OutPoint
forall x. Rep OutPoint x -> OutPoint
forall x. OutPoint -> Rep OutPoint x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. OutPoint -> Rep OutPoint x
from :: forall x. OutPoint -> Rep OutPoint x
$cto :: forall x. Rep OutPoint x -> OutPoint
to :: forall x. Rep OutPoint x -> OutPoint
Generic, Eq OutPoint
Eq OutPoint =>
(Int -> OutPoint -> Int) -> (OutPoint -> Int) -> Hashable OutPoint
Int -> OutPoint -> Int
OutPoint -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> OutPoint -> Int
hashWithSalt :: Int -> OutPoint -> Int
$chash :: OutPoint -> Int
hash :: OutPoint -> Int
Hashable, OutPoint -> ()
(OutPoint -> ()) -> NFData OutPoint
forall a. (a -> ()) -> NFData a
$crnf :: OutPoint -> ()
rnf :: OutPoint -> ()
NFData)

instance Serial OutPoint where
  deserialize :: forall (m :: * -> *). MonadGet m => m OutPoint
deserialize = do
    (TxHash
h, Word32
i) <- (TxHash -> Word32 -> (TxHash, Word32))
-> m TxHash -> m Word32 -> m (TxHash, Word32)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) m TxHash
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m TxHash
deserialize m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32le
    OutPoint -> m OutPoint
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (OutPoint -> m OutPoint) -> OutPoint -> m OutPoint
forall a b. (a -> b) -> a -> b
$ TxHash -> Word32 -> OutPoint
OutPoint TxHash
h Word32
i
  serialize :: forall (m :: * -> *). MonadPut m => OutPoint -> m ()
serialize (OutPoint TxHash
h Word32
i) = TxHash -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => TxHash -> m ()
serialize TxHash
h m () -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32le Word32
i

instance Binary OutPoint where
  put :: OutPoint -> Put
put = OutPoint -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => OutPoint -> m ()
serialize
  get :: Get OutPoint
get = Get OutPoint
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m OutPoint
deserialize

instance Serialize OutPoint where
  put :: Putter OutPoint
put = Putter OutPoint
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
forall (m :: * -> *). MonadPut m => OutPoint -> m ()
serialize
  get :: Get OutPoint
get = Get OutPoint
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
forall (m :: * -> *). MonadGet m => m OutPoint
deserialize

instance FromJSON OutPoint where
  parseJSON :: Value -> Parser OutPoint
parseJSON =
    String -> (Object -> Parser OutPoint) -> Value -> Parser OutPoint
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"OutPoint" ((Object -> Parser OutPoint) -> Value -> Parser OutPoint)
-> (Object -> Parser OutPoint) -> Value -> Parser OutPoint
forall a b. (a -> b) -> a -> b
$ \Object
o ->
      TxHash -> Word32 -> OutPoint
OutPoint (TxHash -> Word32 -> OutPoint)
-> Parser TxHash -> Parser (Word32 -> OutPoint)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser TxHash
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"txid" Parser (Word32 -> OutPoint) -> Parser Word32 -> Parser OutPoint
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser Word32
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"index"

instance ToJSON OutPoint where
  toJSON :: OutPoint -> Value
toJSON (OutPoint TxHash
h Word32
i) = [Pair] -> Value
object [Key
"txid" Key -> TxHash -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= TxHash
h, Key
"index" Key -> Word32 -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Word32
i]
  toEncoding :: OutPoint -> Encoding
toEncoding (OutPoint TxHash
h Word32
i) =
    Series -> Encoding
pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$
      [Series] -> Series
forall a. Monoid a => [a] -> a
mconcat
        [ Key
"txid" Key -> Encoding -> Series
`E.pair` TxHash -> Encoding
forall a. ToJSON a => a -> Encoding
toEncoding TxHash
h,
          Key
"index" Key -> Encoding -> Series
`E.pair` Word32 -> Encoding
E.word32 Word32
i
        ]

-- | Outpoint used in coinbase transactions.
nullOutPoint :: OutPoint
nullOutPoint :: OutPoint
nullOutPoint =
  OutPoint
    { $sel:hash:OutPoint :: TxHash
hash = TxHash
"0000000000000000000000000000000000000000000000000000000000000000",
      $sel:index:OutPoint :: Word32
index = Word32
forall a. Bounded a => a
maxBound
    }