Step 0: Create Base Transaction
In this step, we define the base structure of the transaction, which includes:
- Version (4 bytes)
- Marker/Flag (required for SegWit transactions)
- Locktime (4 bytes)
Inputs, outputs, and witness data will be added in the next steps.
SegWit vs Legacy Transactions
If a transaction has at least one SegWit input (native or wrapped), it must include:
- Marker byte (0x00)
- Flag byte (0x01)
The transaction structure at this stage is:
1Transaction Breakdown:
2═══════════════════════════════════════════════════════════════════════════════════
3
4version: 01000000
5marker: 00
6flag: 01
7
8in: # We'll add inputs in the next step
9
10out: # We'll add outputs later
11
12locktime: 11000000
Code Implementation
def create_basic_tx(
version: int,
inputs: list,
outputs: list,
locktime: int,
segwit: bool = True
) -> bytes:
# 4-byte version in little-endian
tx_version = int_to_little_endian(version, 4)
# Marker + Flag for segwit (only if segwit=True)
marker_flag = b'\x00\x01' if segwit else b''
# Number of inputs/outputs (varint)
in_count = varint(len(inputs))
out_count = varint(len(outputs))
# Serialize inputs and outputs
serialized_inputs = b''.join(inputs)
serialized_outputs = b''.join(outputs)
# Locktime (4 bytes)
tx_locktime = int_to_little_endian(locktime, 4)
return (
tx_version +
marker_flag +
in_count +
serialized_inputs +
out_count +
serialized_outputs +
tx_locktime
)
Let's now add inputs and outputs in the next step!