bitcoin-block-0.9.0: src/Data/Bitcoin/Block/Types.hs
{-# LANGUAGE FlexibleInstances #-}
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 type describing a block in the bitcoin protocol.
data Block = Block {
-- | Header information for this block.
blockHeader :: BlockHeader,
-- | Coinbase transaction of this block.
blockCoinbaseTx :: Btc.Coinbase,
-- | List of transactions pertaining to this block.
blockTxns :: [Btc.Transaction]
} deriving (Eq, Show)
instance Binary Block where
get = do
header <- get
(VarInt c) <- get
cb <- get
txs <- replicateM (fromIntegral (c-1)) 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 type recording information on a 'Block'. The hash of a block is
-- defined as the hash of this data structure. The block mining process
-- involves finding a partial hash collision by varying the nonce in the
-- 'BlockHeader' and/or additional randomness in the 'Btc.Coinbase' of this
-- 'Block'. Variations in the 'Btc.Coinbase' will result in different merkle
-- roots in the 'BlockHeader'.
data BlockHeader = BlockHeader {
-- | Block version information, based on the version of the
-- software creating this block.
blockVersion :: Word32,
-- | Hash of the previous block (parent) referenced by this
-- block.
prevBlock :: BlockHash,
-- | Root of the merkle tree of all transactions pertaining
-- to this block.
merkleRoot :: Word256,
-- | Unix timestamp recording when this block was created
blockTimestamp :: Word32,
-- | The difficulty target being used for this block
blockBits :: Word32,
-- | A random nonce used to generate this block. Additional
-- randomness is included in the coinbase transaction of
-- this block.
bhNonce :: Word32
} deriving (Eq, Show)
instance Binary BlockHeader where
get = do
v <- getWord32le
p <- getByteString 32 -- A BlockHash is exactly 32 bytes
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