module Data.Bitcoin.Block.Types where
import Data.Binary ( Binary, get, put )
import Data.Binary.Get ( getByteString
, getWord32le )
import Data.Binary.Put ( putByteString
, putWord32le )
import Control.Monad ( forM_
, replicateM )
import qualified Data.HexString as HS
import qualified Data.ByteString as BS
import Data.Word ( Word32 )
import Data.LargeWord ( Word256 )
import Data.Bitcoin.Types ( VarInt (..)
, BlockHash )
import qualified Data.Bitcoin.Transaction as Btc ( Transaction (..)
, Coinbase )
data Block = Block {
blockHeader :: BlockHeader,
blockCoinbaseTx :: Btc.Coinbase,
blockTxns :: [Btc.Transaction]
} deriving (Eq, Show)
instance Binary Block where
get = do
header <- get
(VarInt c) <- get
cb <- get
txs <- replicateM (fromIntegral (c1)) get
return $ Block header cb txs
put (Block h cb txs) = do
put h
put $ VarInt $ fromIntegral $ length txs + 1
put cb
forM_ txs put
data BlockHeader = BlockHeader {
blockVersion :: Word32,
prevBlock :: BlockHash,
merkleRoot :: Word256,
blockTimestamp :: Word32,
blockBits :: Word32,
bhNonce :: Word32
} deriving (Eq, Show)
instance Binary BlockHeader where
get = do
v <- getWord32le
p <- getByteString 32
m <- get
bt <- getWord32le
bb <- getWord32le
n <- getWord32le
return $ BlockHeader v ((HS.fromBytes . BS.reverse) p) m bt bb n
put (BlockHeader v p m bt bb n) = do
putWord32le v
putByteString ((BS.reverse . HS.toBytes) p)
put m
putWord32le bt
putWord32le bb
putWord32le n