Skip to content

Serialization

The transaction-shaped types — Transaction, TransactionInput, TransactionOutput, TransactionOutpoint, UtxoEntryReference — support to_dict() and from_dict(). The dict shape matches the wRPC wire format the node accepts and produces.

Round-tripping

tx_dict = tx.to_dict()
restored = Transaction.from_dict(tx_dict)
assert restored == tx

to_dict() returns a fresh Python dict — modifying it doesn't mutate the source object. from_dict() raises on malformed input (missing required keys, wrong types, invalid values).

What the dict looks like

{
  "id":           "ab12...",          # transaction id, hex
  "version":      0,
  "inputs":       [{ "previousOutpoint": {...}, "signatureScript": "...", "sequence": 0, "sigOpCount": 1, "computeBudget": 0 }, ...],
                  # computeBudget is non-zero only on version-1 (covenant) transactions, where sigOpCount must be 0
  "outputs":      [{ "value": 500000000, "scriptPublicKey": {"version": 0, "script": "..."} }, ...],
  "lockTime":     0,
  "subnetworkId": "0000000000000000000000000000000000000000",
  "gas":          0,
  "payload":      "",                   # hex string
  "mass":         12345,
}

Field names use camelCase (wRPC convention), unlike the snake_case Python class attributes.

When you need this

Within a single process, you rarely need to round-trip — pass typed objects around. The dict form earns its place at process boundaries:

  • Offline signing — build on an online machine, serialize, sign on an air-gapped one, serialize again, send back, submit. The dict is the natural transport.
  • Co-signer flows — multisig where each cosigner signs in turn. Each step ships a dict; the next signer reads, signs, and forwards.
  • Persistence — saving a pending transaction to disk or a queue. Store the dict (as JSON), not the typed object.

For submission itself, client.submit_transaction({"transaction": ...}) requires a Transaction instance; passing a dict raises. If the transaction arrives as a dict (from another process, a queue, or disk), rebuild it with Transaction.from_dict() first. See Submission.