ppad-bolt3-0.0.1: Bitcoin transaction formats per BOLT #3
Copyright(c) 2025 Jared Tobin
LicenseMIT
MaintainerJared Tobin <jared@ppad.tech>
Safe HaskellNone
LanguageHaskell2010

Lightning.Protocol.BOLT3.Encode

Description

Serialization for BOLT #3 transactions and scripts.

Provides Bitcoin transaction serialization in both standard SegWit format (with witness data) and the stripped format used for signing.

Transaction Format (SegWit)

  • 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)
Synopsis

Transaction serialization

encode_tx :: CommitmentTx -> ByteString Source #

Encode a commitment transaction (SegWit format with witness).

SegWit format:

  • version (4 bytes LE)
  • marker (0x00)
  • flag (0x01)
  • input count (varint)
  • inputs
  • output count (varint)
  • outputs
  • witness data
  • locktime (4 bytes LE)

Note: The witness is empty (just count=0) since the commitment tx spending the funding output requires external signatures.

encode_htlc_tx :: HTLCTx -> ByteString Source #

Encode an HTLC transaction (SegWit format with witness).

HTLC transactions have a single input (the commitment tx HTLC output) and a single output (the to_local-style delayed output).

encode_closing_tx :: ClosingTx -> ByteString Source #

Encode a closing transaction (SegWit format with witness).

Closing transactions have a single input (the funding output) and one or two outputs (to_local and/or to_remote).

encode_tx_for_signing :: CommitmentTx -> ByteString Source #

Encode a commitment transaction for signing (stripped format).

The stripped format omits the SegWit marker, flag, and witness data. This is the format used to compute the sighash for signing.

Format:

  • version (4 bytes LE)
  • input count (varint)
  • inputs
  • output count (varint)
  • outputs
  • locktime (4 bytes LE)

Witness serialization

encode_witness :: Witness -> ByteString Source #

Encode a witness stack.

Format: varint item count + (varint length + data) for each item

>>> encode_witness (Witness [sig, pubkey])
<varint 2><varint sigLen><sig><varint pkLen><pubkey>

encode_funding_witness Source #

Arguments

:: ByteString

Signature for pubkey1 (lexicographically lesser)

-> ByteString

Signature for pubkey2 (lexicographically greater)

-> Script

The funding witness script

-> ByteString 

Encode a funding witness (2-of-2 multisig).

The witness stack is: 0 sig1 sig2 witnessScript

Signatures must be ordered to match pubkey order in the funding script.

>>> encode_funding_witness sig1 sig2 fundingScript
<witness with 4 items: empty, sig1, sig2, script>

Primitive encoding

encode_varint :: Word64 -> ByteString Source #

Encode a value as a Bitcoin varint (CompactSize).

Encoding scheme:

  • 0-252: 1 byte
  • 253-65535: 0xFD followed by 2 bytes LE
  • 65536-4294967295: 0xFE followed by 4 bytes LE
  • larger: 0xFF followed by 8 bytes LE
>>> encode_varint 100
"\x64"
>>> encode_varint 1000
"\xFD\xE8\x03"

encode_le32 :: Word32 -> ByteString Source #

Encode a 32-bit value in little-endian format.

>>> encode_le32 0x12345678
"\x78\x56\x34\x12"

encode_le64 :: Word64 -> ByteString Source #

Encode a 64-bit value in little-endian format.

>>> encode_le64 0x123456789ABCDEF0
"\xF0\xDE\xBC\x9A\x78\x56\x34\x12"

encode_outpoint :: Outpoint -> ByteString Source #

Encode an outpoint (txid + output index).

Format: 32 bytes txid (already LE in TxId) + 4 bytes output index LE

>>> encode_outpoint (Outpoint txid 0)
<32-byte txid><4-byte index>

encode_output :: TxOutput -> ByteString Source #

Encode a transaction output.

Format: 8 bytes value LE + varint scriptPubKey length + scriptPubKey

>>> encode_output (TxOutput (Satoshi 100000) script OutputToLocal)
<8-byte value><varint length><scriptPubKey>