# ZIP 374: Partially Created Zcash Transaction Format

Status: Draft

Owners: Jack Grigg

Snapshot: a34cfc091434275120ff017c92c3b50d3cef623a

Source date: 2026-10-16T02:56:04+01:00

[Source revision](https://github.com/zcash/zips/commit/a34cfc091434275120ff017c92c3b50d3cef623a)

[Official source](https://zips.z.cash/zip-0374) · [Source file](https://github.com/zcash/zips/blob/a34cfc091434275120ff017c92c3b50d3cef623a/zips/zip-0374.md) · [Discussion](https://github.com/zcash/zips/issues/693)

## Document parts

[Part 1](https://zip-tools-web.harpocrates.workers.dev/zip/374) · [Part 2](https://zip-tools-web.harpocrates.workers.dev/zip/374?part=2)

Reading part 1 of 2. Follow all parts for the complete proposal.

Preamble

**ZIP**: 374

**Title**: Partially Created Zcash Transaction Format

**Owners**: [Jack Grigg](mailto:jack@electriccoin.co)

**Credits**: 

- Daira-Emma Hopwood
- Kris Nuttycombe
- Ava Chow

**Status**: [Revision 0] Draft

**Category**: Standards / Wallet

**Created**: 2024-12-09

**License**: MIT (and BSD-2-Clause for paragraphs from BIP 174 and BIP 370)

**Discussions-To**: [https://github.com/zcash/zips/issues/693](https://github.com/zcash/zips/issues/693)

**Pull-Request**: [https://github.com/zcash/zips/pull/1063](https://github.com/zcash/zips/pull/1063)

<a id="terminology"></a>

## Terminology

The key words "MUST", "MUST NOT", "SHOULD", and "MAY" in this document are to be
interpreted as described in BCP 14 <a id="user-content-fnref-bcp14"></a>
[1](/zip/374?part=2#user-content-fn-bcp14) when, and only when, they appear in
all capitals.

`I2LEOSP_\ell(k)` is the byte sequence $S$ of length $\ell/8$ representing in
little-endian order the integer $k$ in range $\{ 0\,..\, 2^\ell - 1 \}$.

In structures, a bare type `T` (e.g. `u32` for an unsigned 32-bit integer) is
always present and always has a value. `Option<T>` is an optional value; if it
is not set, a sentinel `None` is present instead.

`(A, B)` is a sequence of 2 elements, first type `A`, second type `B`.

`[T; N]` is a length-`N` sequence of elements of type `T` (such as an array in
Rust).

`List<T>` is a variable-length sequence of elements of type `T` (such as
`Vec<T>` in Rust).

`Map<K, V>` is a variable-length key-value map (such as `Map<K, V>` in Rust).

`Enum { A, B, ... }` is a tagged enumeration; a value of this type is exactly one
of the listed variants, identified by a discriminant assigned in listed order
starting from 0.

`UTF8String` is a variable-length human-readable string encoded with UTF-8.

<a id="abstract"></a>

## Abstract

This ZIP proposes a binary format for transactions that are in the process of
being created: it carries the information necessary for each participant in
the process — constructing inputs and outputs, computing zero-knowledge
proofs, producing signatures, and assembling the final transaction — to
perform its step, and holds the accumulated proofs and signatures while the
set is incomplete. Participants such as signers can be offline, as all
necessary information is provided in the format. Two versions of the format
are specified: v1, supporting the creation of v5 transactions; and v2,
supporting the creation of v5 and v6 transactions, including v6 workflows in
which a transaction is fully signed before its anchors, Merkle witnesses, and
proofs are known.

<a id="motivation"></a>

## Motivation

Creating a Zcash transaction is not a single-step, single-party operation. In
practice the logical steps of transaction creation — assembling inputs and
outputs, computing zero-knowledge proofs, authorizing spends, and serializing
the result — are frequently performed by distinct entities, on distinct devices,
at distinct times:

- **Offline and hardware signers.** A signing device typically holds spending
  key material but has limited computational and communication capacity. It
  cannot compute Halo 2 or Groth16 proofs, and may not be able to hold an entire
  transaction's worth of data in memory. It needs a format that carries exactly
  the information required to verify what is being authorized and to produce
  signatures, with everything else elidable.

- **Proof delegation.** The prover for a shielded spend requires the note's
  private data and full viewing key, but does not require any spending key
  material. Wallets on constrained devices can therefore delegate proving to a
  more capable device, if there is a standard way to hand over exactly the data
  the prover needs and to receive back the proof.

- **Multiparty transactions.** Threshold signing (for example FROST <a id="user-content-fnref-frost"></a>
  [2](/zip/374?part=2#user-content-fn-frost)),
  transparent multisig <a id="user-content-fnref-zip-0048"></a>
  [3](/zip/374?part=2#user-content-fn-zip-0048), and transactions with inputs contributed by
  multiple parties all require a partially created transaction to be passed
  among participants, accumulating contributions that were produced in parallel,
  and merged deterministically.

- **Pre-authorization and deferred proving.** From the v6 transaction format
  onward <a id="user-content-fnref-zip-0229"></a>
  [4](/zip/374?part=2#user-content-fn-zip-0229), the anchors of the Sapling, Orchard, and Ironwood
  components are authorizing data: signatures do not commit to them, and Merkle
  witnesses never appear in the final transaction. A transaction can therefore
  be fully authorized by its signers before the anchor is chosen, with witnesses
  computed and proofs produced later — including for transactions that spend
  Orchard-protocol notes created by a parent transaction that has not yet been
  mined. Workflows such as the scheduled Orchard-to-Ironwood migration
  <a id="user-content-fnref-draft-schell-ironwood-migration"></a>
  [5](/zip/374?part=2#user-content-fn-draft-schell-ironwood-migration) use this to obtain a user's authorization
  for a chain of transactions in a single signing session, and to re-anchor and
  prove each transaction at its broadcast time. A partial-transaction format
  must be able to represent these intermediate states durably, potentially for
  days.

Bitcoin addressed the analogous problems with the Partially Signed Bitcoin
Transaction (PSBT) format, defined in BIP 174 <a id="user-content-fnref-bip-0174"></a>
[6](/zip/374?part=2#user-content-fn-bip-0174) and revised in BIP 370
<a id="user-content-fnref-bip-0370"></a>
[7](/zip/374?part=2#user-content-fn-bip-0370). PSBTs cannot be used directly for Zcash: they have no
representation for shielded inputs and outputs, no notion of proofs as distinct
from signatures, and their key-value encoding tolerates unknown fields in a way
that is undesirable for signers that must understand everything they authorize.
This ZIP defines the Zcash equivalent, reusing the PSBT role structure and its
transparent-input semantics so that codebases which already support PSBTs can
integrate PCZTs with minimal changes.

<a id="privacy-implications"></a>

## Privacy Implications

A PCZT necessarily contains strictly more information than the transaction that
is extracted from it. In particular, a PCZT may carry, for each shielded spend
or output: the counterparty address, the value, the note randomness, the value
commitment randomness (which opens the value commitment), the full viewing key
of the account spending a note, ZIP 32 derivation paths, the `ock` value (which
opens `out_ciphertext`), and user-facing address strings.

Anyone who receives a copy of a PCZT at a given stage of its lifecycle learns
all of the information present at that stage. Consequently:

- Participants SHOULD send a PCZT only to entities that are required for the
  remaining roles, and SHOULD use the Redactor role to remove fields that
  subsequent entities do not need.

- Delegating the Prover role reveals the private data of the notes being spent
  or created (but not spending authority) to the prover. Users who consider
  their proving delegate untrusted should treat it as learning the transaction's
  full contents.

- The redaction guidance attached to individual fields below ("this can be
  redacted") identifies the points in the lifecycle after which each sensitive
  field is no longer needed.

- Long-lived PCZTs (for example, pre-authorized transactions awaiting proving
  and broadcast) extend the window during which this information exists outside
  the wallet's normal storage. Wallets SHOULD protect stored PCZTs as they would
  protect their own note databases.

Once the final transaction is extracted, none of this additional information is
present in it; the on-chain privacy properties of the transaction itself are
unchanged.

<a id="requirements"></a>

## Requirements

The format must be able to represent a v5 or v6 transaction at every
intermediate state of its creation, across the role separations described
above; in particular, each of the following must be independently performable
by distinct entities, in an order constrained only by data dependencies:
adding inputs and outputs, deciding that the input/output set is final,
attaching key-path and other lookup metadata, computing proofs, producing
signatures, merging parallel contributions, and extracting the final
transaction.

The format must not require spending key material to be present. (Spending keys
for dummy spends, which authorize nothing of value, are the one exception, and
must be removable before signers see the PCZT.)

Signers must be able to determine, from the PCZT alone, exactly what they are
authorizing: amounts, recipients, and the correspondence between the fields
they sign over and the values shown to the user. It must be possible to remove
data that a given signer does not need before the PCZT is sent to it.

Merging two PCZTs derived from the same transaction must be deterministic, and
must fail loudly on any conflict rather than silently discarding data.

For v6 transactions, the format must support pre-authorization: signatures can
be produced while the anchors, Merkle witnesses, and proofs are absent, with
those fields supplied later without invalidating the signatures. <a id="user-content-fnref-zip-0229-2"></a>
[4](/zip/374?part=2#user-content-fn-zip-0229)

The encoding must be compact enough for memory-constrained signing devices, and
must be strictly versioned: an implementation must never misinterpret data
produced under a different version of this specification.

<a id="specification"></a>

## Specification

A PCZT consists of a versioned binary encoding (defined in the "Encoding"
section) of a structured set of fields (defined in the "Structure" section).
The fields are grouped per payment protocol, and are populated and consumed by
entities acting in well-defined roles (defined in the "Roles" section), each of
which advances the PCZT towards a complete transaction. The lifecycle of a
transaction created via PCZTs is:

1. A Creator initializes the PCZT with global transaction fields.

2. Constructors add transparent inputs and outputs, shielded spends and
   outputs, and (for Orchard-protocol bundles) the actions containing them.

3. An IO Finalizer declares the input/output set complete, computes the binding
   signature keys, and signs any dummy spends.

4. Updaters attach information needed by later roles (key derivation paths,
   full viewing keys, Merkle witnesses, anchors).

5. Provers attach zero-knowledge proofs; Signers attach signatures. From the v6
   transaction format onward these two roles are fully independent and may run
   in either order or in parallel.

6. Combiners merge PCZTs processed in parallel by different entities;
   Redactors remove fields that later entities do not need.

7. A Spend Finalizer assembles script signatures for transparent inputs, and a
   Transaction Extractor produces (and verifies) the final transaction.

PCZTs do not support Sprout, and cannot be used to create v4 or earlier
transactions. (The v4 transaction format predates the ZIP 244 <a id="user-content-fnref-zip-0244"></a>
[8](/zip/374?part=2#user-content-fn-zip-0244)
transaction digest algorithm; several of the role separations specified here,
in particular the independence of proving from signing, do not hold for it.)

<a id="versioning"></a>

### Versioning

The PCZT format evolves via revisions to this ZIP. Implementors of this ZIP are
advised to review it regularly for new revisions (at least once per Network
Upgrade).

While evolution of the PCZT format is expected to be gradual, newer versions MAY
change anything about the format (e.g. adding or removing fields, or using a
different encoding scheme). Fields that are only present in a specific PCZT
version will be annotated with a version (or version range, or set of versions)
below; any non-annotated field is present in all PCZT versions.

The following versions are currently specified:

- v1
  
  
  
  - Supports creation of v5 transactions <a id="user-content-fnref-zip-0225"></a>
    [9](/zip/374?part=2#user-content-fn-zip-0225).

- v2
  
  
  
  - Supports creation of v5 transactions <a id="user-content-fnref-zip-0225-2"></a>
    [9](/zip/374?part=2#user-content-fn-zip-0225) and v6 transactions
    <a id="user-content-fnref-zip-0229-3"></a>
    [4](/zip/374?part=2#user-content-fn-zip-0229).
  
  - Adds an `IronwoodBundle` carrying the *Ironwood-pool* component of a v6
    transaction.
  
  - Adds a `note_version` field to the Orchard-protocol bundles, so that an
    `IronwoodBundle` can carry notes using the ZIP 2005 <a id="user-content-fnref-zip-2005"></a>
    [10](/zip/374?part=2#user-content-fn-zip-2005)
    quantum-recoverable note plaintext format. (An `OrchardBundle` is not
    permitted to use that format <a id="user-content-fnref-zip-0229-4"></a>
    [4](/zip/374?part=2#user-content-fn-zip-0229); the field makes the shared
    bundle structure self-describing.)
  
  - Makes the shielded bundle anchors optional, so that (for v6 transactions)
    a PCZT can be signed before its anchors are chosen, and re-anchored
    without invalidating signatures.
  
  - Omits canonically-empty bundles from the encoding, reducing the size of
    the byte streams exchanged with constrained signing devices.

A PCZT version does not pin a transaction version: a v2 PCZT may carry either
a v5 or a v6 transaction, subject to the per-field rules below. A v1 PCZT can
only carry a v5 transaction.

<a id="encoding"></a>

### Encoding

The PCZT encoding is an 8-byte header followed by a version-specific encoding:

```
[0x50, 0x43, 0x5a, 0x54] || I2LEOSP_32(version) || VERSION_SPECIFIC_ENCODING
```

- The first 4 bytes are magic bytes: the ASCII encoding of the string "PCZT".

- The next 4 bytes are the little-endian encoding of the version.

- The remaining bytes should be parsed according to the version.

If a parser encounters a version number it does not recognise, it MUST NOT parse
the remainder of the data, and should instead return an error indicating that
this ZIP should be reviewed for new versions.

Binary PCZT files should use the `.pczt` file extension.

#### Data type encodings

This section canonically defines how the data types used in the "Structure"
part of this specification are encoded. The encodings are a profile of the
Postcard Wire Format <a id="user-content-fnref-postcard"></a>
[11](/zip/374?part=2#user-content-fn-postcard), and are byte-for-byte identical to the
serialization implemented in the `pczt` Rust crate <a id="user-content-fnref-pczt-rust"></a>
[12](/zip/374?part=2#user-content-fn-pczt-rust) (as of
release `pczt 0.7.0` <a id="user-content-fnref-pczt-0.7.0"></a>
[13](/zip/374?part=2#user-content-fn-pczt-0.7.0) for the v1 encoding). That crate is a
reference implementation; this ZIP is the canonical definition of the PCZT
encodings, and implementations in other languages can be written from this
section alone, without reference to the Postcard specification or to the Rust
serialization machinery.

Define `varint(n)` to be the unsigned little-endian base-128 encoding of the
integer `n`: the value is encoded 7 bits at a time, least significant bits
first, one byte per group, where every byte except the last has bit 7 set and
the last byte has bit 7 clear. Encoders MUST emit the shortest encoding of the
value (equivalently: the final byte is nonzero, unless the entire encoding is
the single byte `0x00`). The encoding of a `k`-bit integer occupies at most
`ceiling(k/7)` bytes, and in a maximum-length encoding the final byte
contributes only the high `k mod 7` bits (for example, the fifth byte of an
encoded `u32` is at most `0x0f`); decoders MUST reject encodings that exceed
either limit, and MAY either accept or reject non-minimal encodings within
them. (The reference implementation accepts them; encoders MUST NOT rely on
this.)

The data types are encoded as follows:

- `u8`: a single byte containing the value. (Not a varint.)

- `u32`, `u64`: `varint(n)`; at most 5 and 10 bytes respectively.

- `i128` (used only for `SaplingBundle.value_sum`): `varint(zigzag(n))`,
  at most 19 bytes, where `zigzag(n)` reinterprets
  `(n << 1) XOR (n >> 127)` (with `>>` an arithmetic shift) as an unsigned
  128-bit integer. That is, a non-negative value `n` encodes as `2n`, and a
  negative value `n` encodes as `2|n| - 1`.

- `bool`: a single byte; `0x00` is false and `0x01` is true. Decoders MUST
  reject other values.

- `[T; N]`: the concatenation of the encodings of the N elements, with no
  length prefix. In particular `[u8; N]` is exactly N raw bytes, and
  `[[u8; 32]; 32]` (the type of `witness` Merkle paths) is exactly 1024 raw
  bytes.

- `(A, B)`: the encoding of `A` followed by the encoding of `B`, with no
  framing.

- `Option<T>`: the single byte `0x00` for `None`; the single byte `0x01`
  followed by the encoding of the value for `Some`. Decoders MUST reject
  other tag bytes.

- `List<T>`: `varint(count)`, where count is the number of elements, followed
  by the encodings of the elements in order. (For `List<u8>`, the count is
  the byte length.)

- `UTF8String`: `varint(len)`, where len is the length in bytes, followed by
  the UTF-8 encoding of the string. Decoders MUST reject byte sequences that
  are not valid UTF-8.

- `Map<K, V>`: `varint(count)`, where count is the number of entries,
  followed by each entry as the encoding of its key followed by the encoding
  of its value. Encoders MUST emit entries in strictly ascending
  lexicographic byte order of the (unencoded) keys, with no duplicate keys.
  Decoders MAY either accept or reject out-of-order or duplicated entries.
  (The reference implementation accepts them, retaining the last value for a
  duplicated key; encoders MUST NOT rely on this.)

- `Enum { A, B, ... }`: `varint(d)`, where `d` is the variant's 0-based
  discriminant, followed by the encoding of the variant's payload. (Every
  enumeration in this ZIP consists of payload-free variants, so the
  discriminant stands alone.)

- Structures (`Global`, the bundles, and their substructures): the
  concatenation of the encodings of their fields, in the order the fields are
  listed in this ZIP, with no framing, field tags, or padding. A field that
  is annotated as not present in the PCZT version being encoded is omitted
  entirely (it is *not* encoded as an absent `Option`).

The version-specific encoding ends at the last byte of the final field.
Encoders MUST NOT emit trailing data after it; decoders MAY either ignore or
reject trailing data. (The reference implementation ignores it.)

#### v1 Encoding

The v1 version-specific encoding is the concatenation of the following
structures, encoded according to the "Data type encodings" section above,
using the struct names from the "Structure" part of the specification; fields
within each struct are encoded in the order they appear in the ZIP.

```
PCZT
- Global
  - fields...
- TransparentBundle
  - List<TransparentInput>
    - fields...
  - List<TransparentOutput>
    - fields...
- SaplingBundle
  - List<SaplingSpend>
    - fields...
  - List<SaplingOutput>
    - fields...
  - fields...
- OrchardBundle
  - List<OrchardAction>
    - cv_net
    - OrchardSpend
      - fields...
    - OrchardOutput
      - fields...
    - rcv
  - fields...
```

Fields annotated below as present only in v2 PCZTs are absent from the v1
encoding entirely (they are not encoded as `None`). A v1 PCZT can represent
only a subset of the states representable in a v2 PCZT; serializing to the v1
encoding MUST fail if:

- `Global.tx_version` is not 5;

- the `IronwoodBundle` is not the canonical empty bundle (see the v2 Encoding
  section);

- `OrchardBundle.note_version` is not `V2`; or

- any bundle anchor that would be required before signing a v5 transaction is
  absent.

#### v2 Encoding

The v2 version-specific encoding likewise uses the encodings of the "Data
type encodings" section above, and differs from the v1 encoding as follows:

```
PCZT
- Global
  - fields...
- Option<TransparentBundle>
- Option<SaplingBundle>
- Option<OrchardBundle>
- Option<IronwoodBundle>
```

- Each bundle is wrapped in an `Option`. A bundle that is exactly equal to the
  **canonical empty bundle** for its slot MUST be encoded as `None`, and a
  parser encountering `None` MUST reconstruct exactly the canonical empty
  bundle, so that re-serialization round-trips and copies of a PCZT that take
  different serialization paths continue to be combinable. A bundle that
  differs from the canonical empty bundle in any field (including its `flags`,
  `note_version`, or `anchor`) MUST be encoded as `Some`.
  
  
  
  
  The canonical empty bundles are:
  
  
  
  
  
  - `TransparentBundle`: empty `inputs` and `outputs` lists.
  
  - `SaplingBundle`: empty `spends` and `outputs` lists, `value_sum = 0`,
    `anchor = None`, `bsk = None`.
  
  - `OrchardBundle`: empty `actions` list, `flags = 0b00000011` (spends and
    outputs enabled), `value_sum = (0, false)`, `anchor = None`,
    `note_version = V2`, `zkproof = None`, `bsk = None`.
  
  - `IronwoodBundle`: empty `actions` list, `flags = 0b00000111` (spends,
    outputs, and cross-address transfers enabled), `value_sum = (0, false)`,
    `anchor = None`, `note_version = V3`, `zkproof = None`, `bsk = None`.

- The `IronwoodBundle` slot is new; it has the same structure as
  `OrchardBundle` (see the `IronwoodBundle` section below).

- The `OrchardBundle` and `IronwoodBundle` structures gain a `note_version`
  field, encoded after `anchor`.

- The `anchor` field of the `SaplingBundle`, `OrchardBundle`, and
  `IronwoodBundle` structures is `Option<[u8; 32]>` rather than `[u8; 32]`.

<a id="structure"></a>

### Structure

A PCZT is comprised of several top-level structures, that map to equivalent
regions of a Zcash transaction:

- `Global`: fields that are relevant to the transaction as a whole.

- `TransparentBundle`: fields relevant to the transparent protocol.

- `SaplingBundle`: fields relevant to the Sapling protocol.

- `OrchardBundle`: fields relevant to the *Orchard-pool* component of the
  Orchard protocol.

- `IronwoodBundle` (PCZT v2): fields relevant to the *Ironwood-pool* component
  of the Orchard protocol <a id="user-content-fnref-zip-0229-5"></a>
  [4](/zip/374?part=2#user-content-fn-zip-0229).

Each structure in turn contains a combination of:

- Transaction effecting data: required fields that are part of the final
  transaction, and are always present in the PCZT.

- Transaction authorizing data: fields that are initially empty, and are filled
  in as the PCZT is processed.

- Context data: information committed to by (or relevant to) the transaction
  effecting data, that enables various Roles to be performed.

The bundle substructures are not logically optional. This is because a PCZT
does not always contain a semantically-valid transaction, and there may be
phases where we need to store protocol-specific metadata before it has been
determined whether there are protocol-specific inputs or outputs. (The v2
*encoding* omits bundles that exactly equal their canonical empty values, but
a parser reconstructs those values, so every PCZT logically contains all of
the bundle substructures.)

#### `Global`

The `Global` struct has the following fields:

- `tx_version: u32`
  
  
  
  
  The version of the transaction being created.
  
  
  
  
  
  - This is set by the Creator.
  
  - This is checked by the Constructor before adding inputs or outputs, to
    confirm that the transaction version will support the payment protocol for
    those inputs or outputs.
  
  - PCZT version 1: MUST be 5.
  
  - PCZT version 2: MUST be 5 or 6.

- `version_group_id: u32`
  
  
  
  
  The version group ID of the transaction being created.
  
  
  
  
  This MUST be consistent with `tx_version` <a id="user-content-fnref-zip-0225-3"></a>
  [9](/zip/374?part=2#user-content-fn-zip-0225) <a id="user-content-fnref-zip-0229-6"></a>
  [4](/zip/374?part=2#user-content-fn-zip-0229).

- `consensus_branch_id: u32`
  
  
  
  
  The consensus branch ID for the chain in which this transaction will be mined.
  
  
  
  
  Non-optional because this commits to the set of consensus rules that will
  apply to the transaction; differences therein can affect every role.
  
  
  
  
  If `tx_version` is 6, this MUST correspond to a network upgrade at which the
  v6 transaction format is supported (NU6.3 or later) <a id="user-content-fnref-zip-0229-7"></a>
  [4](/zip/374?part=2#user-content-fn-zip-0229).

- `fallback_lock_time: Option<u32>`
  
  
  
  
  The transaction locktime to use if no inputs specify a required locktime.
  
  
  
  
  
  - This is set by the Creator.
  
  - If omitted, the fallback locktime is assumed to be 0.

- `expiry_height: u32`
  
  
  
  
  The ZIP 203 <a id="user-content-fnref-zip-0203"></a>
  [14](/zip/374?part=2#user-content-fn-zip-0203) expiry height to use.

- `coin_type: u32`
  
  
  
  
  The SLIP 44 <a id="user-content-fnref-slip-0044"></a>
  [15](/zip/374?part=2#user-content-fn-slip-0044) coin type, indicating the network for which this
  transaction is being constructed.
  
  
  
  
  This is technically information that could be determined indirectly from the
  `consensus_branch_id` (or from BIP 44 <a id="user-content-fnref-bip-0044"></a>
  [16](/zip/374?part=2#user-content-fn-bip-0044) or ZIP 32 <a id="user-content-fnref-zip-0032"></a>
  [17](/zip/374?part=2#user-content-fn-zip-0032) paths
  added by Updaters) but is included explicitly to enable easy identification.
  Note that this field is not included in the transaction and has no consensus
  effect (`consensus_branch_id` fills that role).
  
  
  
  
  
  - This is set by the Creator.
  
  - Roles that encode network-specific information (for example, derivation paths
    for key identification) should check against this field for correctness.

- `tx_modifiable: u8`
  
  
  
  
  A bitfield for various transaction modification flags.
  
  
  
  
  
  - Bit 0 is the Transparent Inputs Modifiable Flag and indicates whether
    transparent inputs can be modified.
    
    
    
    - This is set to `true` by the Creator.
    
    - This is checked by the Constructor before adding transparent inputs, and
      may be set to `false` by the Constructor.
    
    - This is set to `false` by the IO Finalizer if there are shielded spends or
      outputs.
    
    - This is set to `false` by a Signer that adds a signature that does not use
      `SIGHASH_ANYONECANPAY` (which includes all shielded signatures).
    
    - The Combiner merges this bit towards `false`.
  
  - Bit 1 is the Transparent Outputs Modifiable Flag and indicates whether
    transparent outputs can be modified.
    
    
    
    - This is set to `true` by the Creator.
    
    - This is checked by the Constructor before adding transparent outputs, and
      may be set to `false` by the Constructor.
    
    - This is set to `false` by the IO Finalizer if there are shielded spends or
      outputs.
    
    - This is set to `false` by a Signer that adds a signature that does not use
      `SIGHASH_NONE` (which includes all shielded signatures).
    
    - The Combiner merges this bit towards `false`.
  
  - Bit 2 is the Has `SIGHASH_SINGLE` Flag and indicates whether the transaction
    has a `SIGHASH_SINGLE` transparent signature who's input and output pairing
    must be preserved.
    
    
    
    - This is set to `false` by the Creator.
    
    - This is updated by a Constructor.
    
    - This is set to `true` by a Signer that adds a signature that uses
      `SIGHASH_SINGLE`.
    
    - This essentially indicates that the Constructor must iterate the
      transparent inputs to determine whether and how to add a transparent
      input.
    
    - The Combiner merges this bit towards `true`.
  
  - Bits 3-6 MUST be 0 for version 1 PCZTs.
  
  - Bit 7 is the Shielded Modifiable Flag and indicates whether shielded spends
    or outputs can be modified.
    
    
    
    - This is set to `true` by the Creator.
    
    - This is checked by the Constructor before adding shielded spends or
      outputs, and may be set to `false` by the Constructor.
    
    - This is set to `false` by the IO Finalizer if there are shielded spends or
      outputs.
    
    - This is set to `false` by every Signer (as all signatures commit to all
      shielded spends and outputs).
    
    - The Combiner merges this bit towards `false`.

- `proprietary: Map<UTF8String, List<u8>>`
  
  
  
  
  Proprietary fields related to the overall transaction. See "Proprietary Use
  fields" below.

#### `TransparentBundle`

The  `TransparentBundle` struct has the following fields:

- `inputs: List<TransparentInput>`
  
  
  
  
  The transparent coins that will be spent by this transaction.

- `outputs: List<TransparentOutput>`
  
  
  
  
  The transparent coins that will be created by this transaction.

##### `TransparentInput`

The `TransparentInput` struct has the following fields:

- `prevout_txid: [u8; 32]`
  
  
  
  
  This is filled in by the Constructor when adding an input.

- `prevout_index: u32`
  
  
  
  
  This is filled in by the Constructor when adding an input.

- `sequence: Option<u32>`
  
  
  
  
  The sequence number of this input.
  
  
  
  
  
  - This is set by the Constructor.
  
  - If omitted, the sequence number is assumed to be the final sequence number
    (`0xffffffff`).

- `required_time_lock_time: Option<u32>`
  
  
  
  
  The minimum Unix timstamp that this input requires to be set as the
  transaction's lock time.
  
  
  
  
  
  - This is set by the Constructor.
  
  - This MUST be greater than or equal to 500000000.

- `required_height_lock_time: Option<u32>`
  
  
  
  
  The minimum block height that this input requires to be set as the
  transaction's lock time.
  
  
  
  
  
  - This is set by the Constructor.
  
  - This MUST be greater than 0 and less than 500000000.

- `script_sig: Option<List<u8>>`
  
  
  
  
  A satisfying witness for the `script_pubkey` of the input being spent.
  
  
  
  
  This is set by the Spend Finalizer.

- `value: u64`
  
  
  
  
  This is required by the Transaction Extractor, to derive the shielded sighash
  needed for computing the binding signatures.

- `script_pubkey: List<u8>`
  
  
  
  
  This is required by the Transaction Extractor, to derive the shielded sighash
  needed for computing the binding signatures.

- `redeem_script: Option<List<u8>>`
  
  
  
  
  The script required to spend this output, if it is P2SH.
  
  
  
  
  Set to `None` if this is a P2PKH output.

- `partial_signatures: Map<[u8; 33], List<u8>>`
  
  
  
  
  A map from a pubkey to a signature created by it.
  
  
  
  
  
  - Each pubkey should appear in `script_pubkey` or `redeem_script`.
  
  - Each entry is set by a Signer, and should contain an ECDSA signature that is
    valid under the corresponding pubkey.
  
  - These are required by the Spend Finalizer to assemble `script_sig`.

- `sighash_type: u8`
  
  
  
  
  The sighash type to be used for this input.
  
  
  
  
  
  - Signers MUST use this sighash type to produce their signatures. Signers that
    cannot produce signatures for this sighash type MUST NOT provide a signature.
  
  - Spend Finalizers MUST fail to finalize inputs which have signatures not
    matching this sighash type.

- `bip32_derivation: Map<[u8; 33], Zip32Derivation>`
  
  
  
  
  A map from a pubkey to the BIP 32 derivation path at which its corresponding
  spending key can be found.
  
  
  
  
  
  - The pubkeys should appear in `script_pubkey` or `redeem_script`.
  
  - Each entry is set by an Updater.
  
  - Individual entries may be required by a Signer.
  
  - It is not required that the map include entries for all of the used pubkeys.
    In particular, it is not possible to include entries for non-BIP-32 pubkeys.

- `ripemd160_preimages: Map<[u8; 20], List<u8>>`
  
  
  
  
  Mappings of the form `key = RIPEMD160(value)`.
  
  
  
  
  
  - These may be used by the Signer to inspect parts of `script_pubkey` or
    `redeem_script`.

- `sha256_preimages: Map<[u8; 32], List<u8>>`
  
  
  
  
  Mappings of the form `key = SHA256(value)`.
  
  
  
  
  
  - These may be used by the Signer to inspect parts of `script_pubkey` or
    `redeem_script`.

- `hash160_preimages: Map<[u8; 20], List<u8>>`
  
  
  
  
  Mappings of the form `key = RIPEMD160(SHA256(value))`.
  
  
  
  
  
  - These may be used by the Signer to inspect parts of `script_pubkey` or
    `redeem_script`.

- `hash256_preimages: Map<[u8; 32], List<u8>>`
  
  
  
  
  Mappings of the form `key = SHA256(SHA256(value))`.
  
  
  
  
  
  - These may be used by the Signer to inspect parts of `script_pubkey` or
    `redeem_script`.

- `proprietary: Map<UTF8String, List<u8>>`
  
  
  
  
  Proprietary fields related to the coin being spent. See "Proprietary Use
  fields" below.

##### `TransparentOutput`

The `TransparentOutput` struct has the following fields:

- `value: u64`
  
  
  
  
  This is filled in by the Constructor when adding an output.

- `script_pubkey: List<u8>`
  
  
  
  
  This is filled in by the Constructor when adding an output.

- `redeem_script: Option<List<u8>>`
  
  
  
  
  The script required to spend this output, if it is P2SH.
  
  
  
  
  Set to `None` if this is a P2PKH output.

- `bip32_derivation: Map<[u8; 33], Zip32Derivation>`
  
  
  
  
  A map from a pubkey to the BIP 32 derivation path at which its corresponding
  spending key can be found.
  
  
  
  
  
  - The pubkeys should appear in `script_pubkey` or `redeem_script`.
  
  - Each entry is set by an Updater.
  
  - Individual entries may be required by a Signer.
  
  - It is not required that the map include entries for all of the used pubkeys.
    In particular, it is not possible to include entries for non-BIP-32 pubkeys.

- `user_address: Option<UTF8String>`
  
  
  
  
  The user-facing address to which this output is being sent, if any.
  
  
  
  
  
  - This is set by an Updater.
  
  - Signers MUST parse this address (if present) and confirm that it contains
    `recipient` (either directly, or e.g. as a receiver within a Unified
    Address).

- `proprietary: Map<UTF8String, List<u8>>`
  
  
  
  
  Proprietary fields related to the coin being created. See "Proprietary Use
  fields" below.

#### `SaplingBundle`

The  `SaplingBundle` struct has the following fields:

- `spends: List<SaplingSpend>`
  
  
  
  
  The Sapling notes that will be spent by this transaction.

- `outputs: List<SaplingOutput>`
  
  
  
  
  The Sapling notes that will be created by this transaction.

- `value_sum: i128`
  
  
  
  
  The net value of Sapling spends minus outputs.
  
  
  
  
  This is initialized by the Creator, and updated by the Constructor as spends
  or outputs are added to the PCZT. It enables per-spend and per-output values
  to be redacted from the PCZT after they are no longer necessary.

- `anchor: [u8; 32]` (PCZT v1) / `anchor: Option<[u8; 32]>` (PCZT v2)
  
  
  
  
  The Sapling anchor for this transaction.
  
  
  
  
  
  - If `tx_version` is 5, this MUST be set by the Creator, and MUST NOT
    subsequently change: the v5 signature hash commits to the anchor, so
    changing it would invalidate signatures.
  
  - If `tx_version` is 6, this is set by the Creator or by an Updater, and MAY
    be replaced by an Updater at any time before proving (see "Anchors and
    pre-authorization"). It MUST be set before the Prover runs.

- `bsk: Option<[u8; 32]>`
  
  
  
  
  The Sapling binding signature signing key.
  
  
  
  
  
  - This is `None` until it is set by the IO Finalizer.
  
  - The Transaction Extractor uses this to produce the binding signature.

##### `SaplingSpend`

The  `SaplingSpend` struct has the following fields:

- `cv: [u8; 32]`
  
  
  
  
  This is filled in by the Constructor when adding a spend.

- `nullifier: [u8; 32]`
  
  
  
  
  This is filled in by the Constructor when adding a spend.

- `rk: [u8; 32]`
  
  
  
  
  This is filled in by the Constructor when adding a spend.

- `zkproof: Option<[u8; 192]>`
  
  
  
  
  The Sapling Spend proof.
  
  
  
  
  This is set by the Prover.

- `spend_auth_sig: Option<[u8; 64]>`
  
  
  
  
  The spend authorization signature.
  
  
  
  
  This is set by the Signer.

- `recipient: Option<[u8; 43]>`
  
  
  
  
  The raw encoding <a id="user-content-fnref-protocol-saplingpaymentaddrencoding"></a>
  [18](/zip/374?part=2#user-content-fn-protocol-saplingpaymentaddrencoding) of the Sapling payment
  address that received the note being spent.
  
  
  
  
  
  - This is set by the Constructor.
  
  - This is required by the Prover.

- `value: Option<u64>`
  
  
  
  
  The value of the input being spent.
  
  
  
  
  This may be used by Signers to verify that the value matches `cv`, and to
  confirm the values and change involved in the transaction.
  
  
  
  
  This exposes the input value to all participants. For Signers who don't need
  this information, or after signatures have been applied, this can be redacted.

- `rcm: Option<[u8; 32]>`
  
  
  
  
  The note commitment randomness.
  
  
  
  
  
  - This is set by the Constructor. It MUST NOT be set if the note has an `rseed`
    (i.e. was created after ZIP 212 <a id="user-content-fnref-zip-0212"></a>
    [19](/zip/374?part=2#user-content-fn-zip-0212) activation).
  
  - The Prover requires either this or `rseed`.

- `rseed: Option<[u8; 32]>`
  
  
  
  
  The seed randomness for the note being spent.
  
  
  
  
  
  - This is set by the Constructor. It MUST NOT be set if the note has no
    `rseed` (i.e. was created before ZIP 212 <a id="user-content-fnref-zip-0212-2"></a>
    [19](/zip/374?part=2#user-content-fn-zip-0212) activation).
  
  - The Prover requires either this or `rcm`.

- `rcv: Option<[u8; 32]>`
  
  
  
  
  The value commitment randomness.
  
  
  
  
  
  - This is set by the Constructor.
  
  - The IO Finalizer compresses it into `bsk`.
  
  - This is required by the Prover.
  
  - This may be used by Signers to verify that the value correctly matches `cv`.
  
  
  
  
  
  This opens `cv` for all participants. For Signers who don't need this
  information, or after proofs / signatures have been applied, this can be
  redacted.

- `proof_generation_key: Option<([u8; 32], [u8; 32])>`
  
  
  
  
  The proof generation key `(ak, nsk)` corresponding to the recipient that
  received the note being spent.
  
  
  
  
  
  - This is set by the Updater.
  
  - This is required by the Prover.

- `witness: Option<(u32, [[u8; 32]; 32])>`
  
  
  
  
  A witness from the note to the bundle's anchor.
  
  
  
  
  
  - This is set by the Updater.
  
  - This is required by the Prover.

- `alpha: Option<[u8; 32]>`
  
  
  
  
  The spend authorization randomizer.
  
  
  
  
  
  - This is chosen by the Constructor.
  
  - This is required by the Signer for creating `spend_auth_sig`, and may be
    used to validate `rk`.
  
  - After `zkproof` / `spend_auth_sig` has been set, this can be redacted.

- `zip32_derivation: Option<Zip32Derivation>`
  
  
  
  
  The ZIP 32 derivation path at which the spending key can be found for the note
  being spent.

- `dummy_ask: Option<[u8; 32]>`
  
  
  
  
  The spend authorizing key for this spent note, if it is a dummy note.
  
  
  
  
  
  - This is chosen by the Constructor.
  
  - This is required by the IO Finalizer, and is cleared by it once used.
  
  - Signers MUST reject PCZTs that contain `dummy_ask` values.

- `proprietary: Map<UTF8String, List<u8>>`
  
  
  
  
  Proprietary fields related to the note being spent. See "Proprietary Use
  fields" below.

##### `SaplingOutput`

The  `SaplingOutput` struct has the following fields:

- `cv: [u8; 32]`
  
  
  
  
  This is filled in by the Constructor when adding an output.

- `cmu: [u8; 32]`
  
  
  
  
  This is filled in by the Constructor when adding an output.

- `ephemeral_key: [u8; 32]`
  
  
  
  
  This is filled in by the Constructor when adding an output.

- `enc_ciphertext: List<u8>`
  
  
  
  
  The encrypted note plaintext for the output.
  
  
  
  
  This is filled in by the Constructor when adding an output.
  
  
  
  
  Represented as a `List<u8>` because its length depends on the transaction
  version.
  
  
  
  
  Once we have memo bundles <a id="user-content-fnref-zip-0231"></a>
  [20](/zip/374?part=2#user-content-fn-zip-0231), we will be able to set memos
  independently of Outputs. For now, the Constructor sets both at the same time.

- `out_ciphertext: List<u8>`
  
  
  
  
  The encrypted note plaintext for the output.
  
  
  
  
  This is filled in by the Constructor when adding an output.
  
  
  
  
  Represented as a `List<u8>` because its length depends on the transaction
  version.

- `zkproof: Option<[u8; 192]>`
  
  
  
  
  The Sapling Output proof.
  
  
  
  
  This is set by the Prover.

- `recipient: Option<[u8; 43]>`
  
  
  
  
  The raw encoding <a id="user-content-fnref-protocol-saplingpaymentaddrencoding-2"></a>
  [18](/zip/374?part=2#user-content-fn-protocol-saplingpaymentaddrencoding) of the Sapling payment
  address that will receive the output.
  
  
  
  
  
  - This is set by the Constructor.
  
  - This is required by the Prover.

- `value: Option<u64>`
  
  
  
  
  The value of the output.
  
  
  
  
  This may be used by Signers to verify that the value matches `cv`, and to
  confirm the values and change involved in the transaction.
  
  
  
  
  This exposes the output value to all participants. For Signers who don't need
  this information, or after signatures have been applied, this can be redacted.

- `rseed: Option<[u8; 32]>`
  
  
  
  
  The seed randomness for the output.
  
  
  
  
  
  - This is set by the Constructor.
  
  - This is required by the Prover, instead of disclosing `shared_secret` to
    them.

- `rcv: Option<[u8; 32]>`
  
  
  
  
  The value commitment randomness.
  
  
  
  
  
  - This is set by the Constructor.
  
  - The IO Finalizer compresses it into `bsk`.
  
  - This is required by the Prover.
  
  - This may be used by Signers to verify that the value correctly matches `cv`.
  
  
  
  
  
  This opens `cv` for all participants. For Signers who don't need this
  information, or after proofs / signatures have been applied, this can be
  redacted.

- `ock: Option<[u8; 32]>`
  
  
  
  
  The `ock` value used to encrypt `out_ciphertext`.
  
  
  
  
  This enables Signers to verify that `out_ciphertext` is correctly encrypted.
  
  
  
  
  This may be `None` if the Constructor added the output using an OVK policy of
  "None", to make the output unrecoverable from the chain by the sender.

- `zip32_derivation: Option<Zip32Derivation>`
  
  
  
  
  The ZIP 32 derivation path at which the spending key can be found for the
  output.

- `user_address: Option<UTF8String>`
  
  
  
  
  The user-facing address to which this output is being sent, if any.
  
  
  
  
  
  - This is set by an Updater.
  
  - Signers MUST parse this address (if present) and confirm that it contains
    `recipient` (either directly, or e.g. as a receiver within a Unified
    Address).

- `proprietary: Map<UTF8String, List<u8>>`
  
  
  
  
  Proprietary fields related to the note being created. See "Proprietary Use
  fields" below.

#### `OrchardBundle`

The  `OrchardBundle` struct has the following fields:

- `actions: List<OrchardAction>`
  
  
  
  
  The Orchard actions in this bundle.
  
  
  
  
  Entries are added by the Constructor, and modified by an Updater, IO
  Finalizer, Signer, Combiner, or Spend Finalizer.

- `flags: u8`
  
  
  
  
  The flags for the Orchard bundle.
  
  
  
  
  Contains:
  
  
  
  
  
  - `enableSpends` flag (bit 0)
  
  - `enableOutputs` flag (bit 1)
  
  - `enableCrossAddress` flag (bit 2) (PCZT v2; MUST be 0 in PCZT v1, and in
    the `OrchardBundle` of any transaction that will be mined under NU6.3 or
    later <a id="user-content-fnref-zip-0229-8"></a>
    [4](/zip/374?part=2#user-content-fn-zip-0229) <a id="user-content-fnref-zip-0258"></a>
    [21](/zip/374?part=2#user-content-fn-zip-0258))
  
  - Reserved, zeros (bits 3..=7)
  
  
  
  
  
  This is set by the Creator. The Constructor MUST only add spends and outputs
  that are consistent with these flags (i.e. are dummies as appropriate; and,
  when `enableCrossAddress` is 0, each action's output is addressed to the
  same protocol-level address as its spend — see "Fabricated same-address
  outputs").

- `value_sum: (u64, bool)`
  
  
  
  
  The net value of Orchard spends minus outputs.
  
  
  
  
  This is initialized by the Creator, and updated by the Constructor as spends
  or outputs are added to the PCZT. It enables per-spend and per-output values
  to be redacted from the PCZT after they are no longer necessary.

- `anchor: [u8; 32]` (PCZT v1) / `anchor: Option<[u8; 32]>` (PCZT v2)
  
  
  
  
  The Orchard anchor for this transaction.
  
  
  
  
  
  - If `tx_version` is 5, this MUST be set by the Creator, and MUST NOT
    subsequently change: the v5 signature hash commits to the anchor, so
    changing it would invalidate signatures.
  
  - If `tx_version` is 6, this is set by the Creator or by an Updater, and MAY
    be replaced by an Updater at any time before proving (see "Anchors and
    pre-authorization"). It MUST be set before the Prover runs.

- `note_version: NoteVersion` (PCZT v2)
  
  
  
  
  The note plaintext version for notes in this bundle, where `NoteVersion` is
  `Enum { V2, V3 }`:
  
  
  
  
  
  - `V2` denotes the ZIP 212 <a id="user-content-fnref-zip-0212-3"></a>
    [19](/zip/374?part=2#user-content-fn-zip-0212) note plaintext format (lead byte
    `0x02`).
  
  - `V3` denotes the ZIP 2005 <a id="user-content-fnref-zip-2005-2"></a>
    [10](/zip/374?part=2#user-content-fn-zip-2005) quantum-recoverable note plaintext
    format (lead byte `0x03`).
  
  
  
  
  
  Every note in a bundle has the same note version. For an `OrchardBundle`
  this MUST be `V2`; for an `IronwoodBundle` this MUST be `V3`. <a id="user-content-fnref-zip-0229-9"></a>
  [4](/zip/374?part=2#user-content-fn-zip-0229)
  
  
  
  
  In PCZT v1, the note version of the `OrchardBundle` is implicitly `V2`.

- `zkproof: Option<List<u8>>`
  
  
  
  
  The Orchard bundle proof.
  
  
  
  
  This is `None` until it is set by the Prover.
  
  
  
  
  If `tx_version` is 6 and the bundle's `anchor` is replaced after this field
  has been set, this field MUST be cleared (the proof commits to the anchor,
  so it is no longer valid).

- `bsk: Option<[u8; 32]>`
  
  
  
  
  The Orchard binding signature signing key.
  
  
  
  
  
  - This is `None` until it is set by the IO Finalizer.
  
  - The Transaction Extractor uses this to produce the binding signature.

##### `OrchardAction`

The  `OrchardAction` struct has the following fields:

- `cv_net: [u8; 32]`
  
  
  
  
  This is filled in by the Constructor when adding an action.

- `spend: OrchardSpend`
  
  
  
  
  This is filled in by the Constructor when adding an action.

- `output: OrchardOutput`
  
  
  
  
  This is filled in by the Constructor when adding an action.

- `rcv: Option<[u8; 32]>`
  
  
  
  
  The value commitment randomness.
  
  
  
  
  
  - This is set by the Constructor.
  
  - The IO Finalizer compresses it into the bsk.
  
  - This is required by the Prover.
  
  - This may be used by Signers to verify that the value correctly matches `cv`.
  
  
  
  
  
  This opens `cv` for all participants. For Signers who don't need this
  information, or after proofs / signatures have been applied, this can be
  redacted.

###### `OrchardSpend`

The  `OrchardSpend` struct has the following fields:

## Citation relationships

Cites: [ZIP 32](https://zip-tools-web.harpocrates.workers.dev/zip/32), [ZIP 48](https://zip-tools-web.harpocrates.workers.dev/zip/48), [ZIP 203](https://zip-tools-web.harpocrates.workers.dev/zip/203), [ZIP 212](https://zip-tools-web.harpocrates.workers.dev/zip/212), [ZIP 225](https://zip-tools-web.harpocrates.workers.dev/zip/225), [ZIP 229](https://zip-tools-web.harpocrates.workers.dev/zip/229), [ZIP 231](https://zip-tools-web.harpocrates.workers.dev/zip/231), [ZIP 244](https://zip-tools-web.harpocrates.workers.dev/zip/244), [ZIP 256](https://zip-tools-web.harpocrates.workers.dev/zip/256), [ZIP 258](https://zip-tools-web.harpocrates.workers.dev/zip/258), [ZIP 320](https://zip-tools-web.harpocrates.workers.dev/zip/320), [ZIP 2005](https://zip-tools-web.harpocrates.workers.dev/zip/2005)

Cited by: None