Blockchain

BSV Transaction Serialization: From Object to Broadcast

Understanding transaction serialization is key to connecting application development with the blockchain network. This article explains why serialization is needed, the standard transaction structure, the role of hex, serialization and deserialization in the SDK, the relationship with txid, and common misconceptions, helping you move from calling the SDK to debugging on-chain data.

Ethan Lin

Ethan Lin

technical_editor

Published Jun 18, 20264 min read

Conclusion First

In BSV application development, you use the SDK to construct and sign transaction objects, but the network only accepts binary data encoded per the Bitcoin protocol. Serialization converts in-memory transaction objects into a standard byte format (usually represented as a hex string) for broadcasting, storage, or debugging. This article clarifies the core concepts, structure, SDK usage, and common misunderstandings of serialization, so you don't just know how to call the SDK but can also read on-chain data.

BSV Transaction Serialization: From Object to Broadcast article cover

Why Serialization Is Needed

In code, you can intuitively build a transaction:

TypeScript
1const tx = new Transaction()
2tx.addInput(...)
3tx.addOutput(...)
4await tx.fee()
5await tx.sign()

But miner nodes and broadcast services don't understand your JavaScript objects; they only accept transaction data encoded strictly by the rules. So eventually you need to convert it to the standard format:

TypeScript
1const txHex = tx.toHex()

This txHex is the hexadecimal representation of the transaction, transmittable over the network or recognizable by block explorers.

Standard Transaction Structure

According to the BSV TypeScript SDK documentation, the serialization structure of a standard transaction is roughly as follows:

Code
1version
2input count
3inputs
4output count
5outputs
6lock time

Each input contains:

Code
1previous tx hash
2output index
3script length
4unlocking script
5sequence

Each output contains:

Code
1value
2script length
3locking script

Serialization is not simply stringifying JSON; it's a binary format defined by the Bitcoin protocol. You don't need to write every byte manually, but you must understand this structure to grasp how transactions are encoded.

What Is Hex

Hex is a hexadecimal string, where one byte is represented by two hexadecimal characters. For example, 48 65 6c 6c 6f corresponds to the text Hello. A transaction hex is a long string of hexadecimal characters, commonly used by block explorers, broadcast APIs, and debugging tools to represent raw transactions.

Serialization and Deserialization with the SDK

The SDK provides convenient methods:

TypeScript
1// Serialization: object -> hex
2const txHex = tx.toHex()
3
4// Deserialization: hex -> object
5const parsed = Transaction.fromHex(txHex)

toHex() is often used for broadcasting, logging, or interacting with other services. Transaction.fromHex() is commonly used for reading a previous source transaction, debugging raw transactions, or loading transactions from external services.

Besides hex, the SDK also supports formats like BEEF, Atomic BEEF, and binary. At the entry level, master raw transaction hex first, and delve into other formats when you later study SPV, BUMP, and BEEF.

The Relationship Between txid and Serialization

The transaction ID (txid) is derived from a hash of the transaction content. In the SDK, you can use:

TypeScript
1const txid = Buffer.from(tx.id()).toString('hex')

The txid is the unique identifier of a transaction. When another transaction references an output of this transaction, it uses this txid plus the output index. It's crucial to note: if you modify the transaction (e.g., signing or adjusting outputs), the txid will change. Don't treat it as final prematurely.

Steps to Complete Before Serialization

Serialization itself is just encoding; it does not guarantee transaction validity. Before calling toHex(), you typically need to ensure:

  • Inputs correctly reference spendable UTXOs
  • Outputs have correct amounts and locking scripts
  • Change is handled
  • Fees are calculated
  • Each input needing a signature is signed
  • The transaction passes validation

An unsigned transaction can still produce a hex, but that doesn't mean it will be accepted by the network.

Endianness and Debugging

Bitcoin transaction formats involve mixed endianness. For example, the txid in raw hex may appear byte-reversed; this is common in Bitcoin transaction formats. As a beginner, you don't need to write a parser by hand, but if you encounter a situation where something seems reversed, don't be surprised – that's exactly what to watch for when debugging transaction construction.

Position in the BSV Tech Stack

Serialization is the boundary between application code and the network protocol:

  • Application layer operates on transaction objects
  • Wallet layer constructs and signs objects
  • Broadcast layer needs to send encoded transactions
  • Block explorers and indexers parse encoded transactions
  • SPV and proof formats revolve around transaction encoding, txid, Merkle paths, and block headers

Understanding serialization is a key step from just calling the SDK to being able to debug on-chain data.

Common Beginner Misconceptions

  • Hex is not encryption: It's just a textual representation of binary data.
  • Being able to toHex() doesn't mean the transaction is valid: Unsigned or structurally wrong transactions can also be encoded.
  • txid and raw transaction are not the same thing: txid is a hash identifier of the transaction content.
  • Modifying the transaction may change the txid: Don't record the txid prematurely.
  • Endianness issues can affect debugging display: Don't rely solely on visual inspection to judge if transaction references are correct.

References

Recommended articles