| Copyright | (c) 2025 Jared Tobin |
|---|---|
| License | MIT |
| Maintainer | Jared Tobin <jared@ppad.tech> |
| Safe Haskell | None |
| Language | Haskell2010 |
Lightning.Protocol.BOLT3.Decode
Description
Parsing for BOLT #3 transactions and scripts.
Decodes SegWit Bitcoin transactions from raw bytes.
Synopsis
- data DecodeError
- data RawTx = RawTx {
- rtx_version :: !Word32
- rtx_inputs :: ![RawInput]
- rtx_outputs :: ![RawOutput]
- rtx_witness :: ![[ByteString]]
- rtx_locktime :: !Locktime
- data RawInput = RawInput {}
- data RawOutput = RawOutput {}
- decode_tx :: ByteString -> Either DecodeError RawTx
- decode_witness :: ByteString -> Either DecodeError (Witness, ByteString)
- decode_varint :: ByteString -> Either DecodeError (Word64, ByteString)
- decode_le32 :: ByteString -> Either DecodeError (Word32, ByteString)
- decode_le64 :: ByteString -> Either DecodeError (Word64, ByteString)
- decode_outpoint :: ByteString -> Either DecodeError (Outpoint, ByteString)
- decode_output :: ByteString -> Either DecodeError (RawOutput, ByteString)
Error types
data DecodeError Source #
Errors that can occur during transaction decoding.
Constructors
| InsufficientBytes !Int !Int | Expected bytes, actual bytes available |
| InvalidMarker !Word8 | Invalid SegWit marker byte (expected 0x00) |
| InvalidFlag !Word8 | Invalid SegWit flag byte (expected 0x01) |
| InvalidVarint | Malformed varint encoding |
| EmptyInput | No bytes to decode |
Instances
Raw transaction type
A raw transaction as parsed from bytes.
Supports both legacy and SegWit transaction formats.
Constructors
| RawTx | |
Fields
| |
Instances
| Generic RawTx Source # | |||||
Defined in Lightning.Protocol.BOLT3.Decode Associated Types
| |||||
| Show RawTx Source # | |||||
| Eq RawTx Source # | |||||
| type Rep RawTx Source # | |||||
Defined in Lightning.Protocol.BOLT3.Decode type Rep RawTx = D1 ('MetaData "RawTx" "Lightning.Protocol.BOLT3.Decode" "ppad-bolt3-0.0.1-BTVAwWY46FT4MsZtX0EtFp" 'False) (C1 ('MetaCons "RawTx" 'PrefixI 'True) ((S1 ('MetaSel ('Just "rtx_version") 'SourceUnpack 'SourceStrict 'DecidedStrict) (Rec0 Word32) :*: S1 ('MetaSel ('Just "rtx_inputs") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [RawInput])) :*: (S1 ('MetaSel ('Just "rtx_outputs") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [RawOutput]) :*: (S1 ('MetaSel ('Just "rtx_witness") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [[ByteString]]) :*: S1 ('MetaSel ('Just "rtx_locktime") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Locktime))))) | |||||
A raw transaction input as parsed from bytes.
Constructors
| RawInput | |
Fields
| |
Instances
| Generic RawInput Source # | |||||
Defined in Lightning.Protocol.BOLT3.Decode Associated Types
| |||||
| Show RawInput Source # | |||||
| Eq RawInput Source # | |||||
| type Rep RawInput Source # | |||||
Defined in Lightning.Protocol.BOLT3.Decode type Rep RawInput = D1 ('MetaData "RawInput" "Lightning.Protocol.BOLT3.Decode" "ppad-bolt3-0.0.1-BTVAwWY46FT4MsZtX0EtFp" 'False) (C1 ('MetaCons "RawInput" 'PrefixI 'True) (S1 ('MetaSel ('Just "ri_outpoint") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Outpoint) :*: (S1 ('MetaSel ('Just "ri_script_sig") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ByteString) :*: S1 ('MetaSel ('Just "ri_sequence") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Sequence)))) | |||||
A raw transaction output as parsed from bytes.
Instances
| Generic RawOutput Source # | |||||
Defined in Lightning.Protocol.BOLT3.Decode Associated Types
| |||||
| Show RawOutput Source # | |||||
| Eq RawOutput Source # | |||||
| type Rep RawOutput Source # | |||||
Defined in Lightning.Protocol.BOLT3.Decode type Rep RawOutput = D1 ('MetaData "RawOutput" "Lightning.Protocol.BOLT3.Decode" "ppad-bolt3-0.0.1-BTVAwWY46FT4MsZtX0EtFp" 'False) (C1 ('MetaCons "RawOutput" 'PrefixI 'True) (S1 ('MetaSel ('Just "ro_value") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Satoshi) :*: S1 ('MetaSel ('Just "ro_script") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Script))) | |||||
Transaction parsing
decode_tx :: ByteString -> Either DecodeError RawTx Source #
Decode a raw Bitcoin transaction from bytes.
Handles both legacy and SegWit transaction formats.
SegWit format: * version (4 bytes LE) * marker (0x00) + flag (0x01) * input count (varint) * inputs: outpoint (32+4), scriptSig length (varint), scriptSig, sequence * output count (varint) * outputs: value (8 LE), scriptPubKey length (varint), scriptPubKey * witness data (for each input) * locktime (4 bytes LE)
>>>decode_tx rawTxBytesRight (RawTx {...})
Witness parsing
decode_witness :: ByteString -> Either DecodeError (Witness, ByteString) Source #
Decode a witness stack for one input.
Format: varint num_items + (varint length + data) for each item
Primitive decoding
decode_varint :: ByteString -> Either DecodeError (Word64, ByteString) Source #
Decode a Bitcoin varint (CompactSize).
Encoding: * 0x00-0xFC: 1 byte * 0xFD: 2 bytes little-endian follow * 0xFE: 4 bytes little-endian follow * 0xFF: 8 bytes little-endian follow
>>>decode_varint (BS.pack [0x01])Right (1, "")>>>decode_varint (BS.pack [0xfd, 0x00, 0x01])Right (256, "")
decode_le32 :: ByteString -> Either DecodeError (Word32, ByteString) Source #
Decode a little-endian 32-bit integer.
>>>decode_le32 (BS.pack [0x01, 0x00, 0x00, 0x00])Right (1, "")
decode_le64 :: ByteString -> Either DecodeError (Word64, ByteString) Source #
Decode a little-endian 64-bit integer.
>>>decode_le64 (BS.pack [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])Right (1, "")
decode_outpoint :: ByteString -> Either DecodeError (Outpoint, ByteString) Source #
Decode a transaction outpoint (txid + output index).
Format: 32 bytes txid (little-endian) + 4 bytes index (little-endian)
>>>let txid = BS.replicate 32 0>>>let idx = BS.pack [0x01, 0x00, 0x00, 0x00]>>>decode_outpoint (txid <> idx)Right (Outpoint {outpoint_txid = ..., outpoint_index = 1}, "")
decode_output :: ByteString -> Either DecodeError (RawOutput, ByteString) Source #
Decode a transaction output (value + scriptPubKey).
Format: 8 bytes value (little-endian) + varint script length + script