ZIP: 229
Title: Version 6 Transaction Format
Owners: Daira-Emma Hopwood <daira@jacaranda.org>
Kris Nuttycombe <kris@nutty.land>
Dev Ojha <dev@valargroup.dev>
Sean Bowe <sean@bowe.tech>
Status: Draft
Category: Consensus
Created: 2026-06-13
License: MIT
Discussions-To: <https://github.com/zcash/zips/issues/1326>
The key words “MUST”, “MUST NOT”, “SHOULD”, and “MAY” in this document are to be interpreted as described in BCP 14 1 when, and only when, they appear in all capitals.
The term “network upgrade” in this document is to be interpreted as described in ZIP 200. 2
The character § is used when referring to sections of the Zcash Protocol Specification. 3
The terms “Mainnet” and “Testnet” are to be interpreted as described in § 3.12 ‘Mainnet and Testnet’. 4
The term “Recovery Protocol” is to be interpreted as described in 5.
The terms below are to be interpreted as follows:
This ZIP defines version 6 of the Zcash transaction format, to be activated at NU6.3 8.
NU6.3 8 introduces the Ironwood shielded pool, an Orchard-protocol successor to the Orchard pool, that ensures quantum recoverability 5 and has supply integrity supported from the start by formal verification efforts 9.
This requires a new transaction version that can hold an Ironwood component: a second Orchard-protocol shielded component that commits to, and spends from, the Ironwood pool rather than the Orchard pool. The Orchard Action encoding and the Halo 2 proof system are reused unchanged. The circuit is also shared between these pools, changed only slightly from the pre-NU6.3 circuit 6. This ZIP defines the corresponding transaction format, txid, signature-hash, and block-commitment changes.
The addition of the Ironwood pool does not change address structures or encodings. At the protocol level, Orchard spending-key and viewing-key material grants authority to spend or view notes in both the Orchard and Ironwood pools. However, NU6.3 enforces that outputs to the Orchard pool are sent to an Orchard-protocol-level address for which the transaction creator can authorize spends. The intent is that transfers between users will automatically create notes in the Ironwood pool. The address restriction discourages economic activity between users within the Orchard pool, and encourages faster migration to the Ironwood pool.
This ZIP specifies only the transaction format and its associated hashing. The Action circuit changes needed to restrict address usage within the Orchard pool are specified in 6, and implications for wallets are discussed in 10 and 11. Activation parameters are specified in the NU6.3 deployment ZIP 8.
The main purpose of the NU6.3 network upgrade is to bolster confidence in Zcash’s supply integrity, after the discovery and remediation of the Orchard soundness vulnerability described in 12. The turnstile mechanism 13 ensures that the overall ZEC supply is bounded. However, since a substantial portion of ZEC was in the Orchard pool at the time this vulnerability was remediated, it is necessary to take further steps to ensure confidence in the supply by migrating funds to a new pool.
All funds in the Ironwood pool will be quantum-recoverable 5. The existing Zcash shielded protocols are dependent on the hardness of finding discrete logarithms; an adversary who can do so (via quantum computers or otherwise) would be able to steal or forge funds. In the event of needing to disable these protocols in order to prevent such attacks, it will be possible to use a Recovery Protocol to recover funds from the Ironwood pool. This Recovery Protocol is expected to remain secure against discrete-log-breaking and quantum adversaries. This change does not by itself make Zcash secure against attacks using quantum computers, but is a necessary and substantial step toward that goal.
Recovery would not be possible for funds still in the Sprout, Sapling, or Orchard pools; all such funds would be inaccessible after their respective protocols are disabled. They should be migrated to the Ironwood pool in order to take advantage of this change.
The version 6 transaction format also changes the authorization structure for all supported shielded pools (Sapling, Orchard, and Ironwood) so that anchors are considered to be authorizing data rather than effecting data. This allows a transaction to be pre-authorized and its proofs computed independently after choosing an anchor, and also improves opportunities for parallelism in transaction creation.
The turnstile mechanism reveals the amounts in each transaction that cross between pools, including the amounts migrated into the Ironwood pool. This is considered in full detail in 10.
There is no reason to believe that the soundness vulnerability described in 12 could have led to any compromise of key material associated with existing addresses. Independent of the soundness bug, we recommend address rotation for quantum privacy implications discussed in 5.
Changes relative to v5 transactions should be minimized.
The version 6 transaction format must be able to carry an Ironwood-pool component in addition to transparent-pool, Sapling-pool, and Orchard-pool components similar to those in a version 5 transaction.
The Ironwood component must reuse the Orchard Action design and component encoding, so that implementation is shared between them to the maximum extent possible.
The transaction identifier, authorizing-data commitment, and signature digests must commit to the Ironwood-pool component when it is present, using personalizations distinct from those used for the Orchard-pool component.
The changes to the authorization structure must support pre-authorizing transactions using spending key material, and later updating the anchor and proofs (for all supported shielded pools).
Personalizations for nodes in the digest tree must be changed when what is hashed at that node changes.
The flags fields in the Orchard-pool and Ironwood-pool components must support
encoding an indication of whether outputs to the Orchard pool are required to use
a protocol-level address for which the transaction creator can authorize spends.
The one known Orchard-supporting hardware wallet, Keystone, must continue to be able to sign v5 tx format Orchard -> Transparent unshielding transactions, without firmware update.
The v6 transaction format need not support ZSAs, the zip233Amount field, the explicit
fee field, or per-transparent-input sighash information that appeared in the withdrawn
ZIP 230 14, or those features and other extensibility affordances planned for
ZIP 248 15.
The value 6 for the transaction version number need not avoid collisions with the withdrawn ZIP 230 or with the current draft of ZIP 248.
A version 6 transaction is encoded as follows. Fields up to and including the Orchard component are as in the version 5 format 16, except as noted; the Ironwood component is new.
| Note | Bytes | Name | Data Type | Description |
|---|---|---|---|---|
| Common Transaction Fields (unchanged from v5) | ||||
| \(4\) | header |
uint32 |
Contains the fOverwintered flag (bit 31, always set) and version (bits 30 .. 0), which MUST be 6. |
|
| \(4\) | nVersionGroupId |
uint32 |
Version group ID (nonzero, specified in § 7.1.2). | |
| \(4\) | nConsensusBranchId |
uint32 |
Consensus branch ID (nonzero, constrained in § 7.1.2). | |
| \(4\) | lock_time |
uint32 |
Unix-epoch UTC time or block height, encoded as in Bitcoin. | |
| \(4\) | nExpiryHeight |
uint32 |
A block height in {1 .. 499999999} after which the transaction will expire, or 0 to disable expiry. 17 | |
| Transparent Transaction Fields (unchanged from v5) | ||||
varies |
tx_in_count |
compactSize |
Number of transparent inputs in tx_in. |
|
varies |
tx_in |
tx_in |
Transparent inputs, encoded as in Bitcoin. | |
varies |
tx_out_count |
compactSize |
Number of transparent outputs in tx_out. |
|
varies |
tx_out |
tx_out |
Transparent outputs, encoded as in Bitcoin. | |
| Sapling Transaction Fields (unchanged from v5) | ||||
varies |
nSpendsSapling |
compactSize |
Number of Sapling Spend descriptions in vSpendsSapling. |
|
\(96\,\cdot\) nSpendsSapling |
vSpendsSapling |
SpendDescriptionV5[nSpendsSapling] |
Sapling Spend descriptions, encoded per § 7.3 ‘Spend Description Encoding and Consensus’. | |
varies |
nOutputsSapling |
compactSize |
Number of Sapling Output descriptions in vOutputsSapling. |
|
\(756\,\cdot\) nOutputsSapling |
vOutputsSapling |
OutputDescriptionV5[nOutputsSapling] |
Sapling Output descriptions, encoded per § 7.4 ‘Output Description Encoding and Consensus’. | |
| † | \(8\) | valueBalanceSapling |
int64 |
The net value of Sapling Spends minus Outputs. |
| ‡ | \(32\) | anchorSapling |
byte[32] |
A root of the Sapling note commitment tree at some block height in the past. |
\(192\,\cdot\) nSpendsSapling |
vSpendProofsSapling |
byte[192 * nSpendsSapling] |
Encodings of the zk-SNARK proofs for each Sapling Spend. | |
\(64\,\cdot\) nSpendsSapling |
vSpendAuthSigsSapling |
byte[64 * nSpendsSapling] |
Authorizing signatures for each Sapling Spend. | |
\(192\,\cdot\) nOutputsSapling |
vOutputProofsSapling |
byte[192 * nOutputsSapling] |
Encodings of the zk-SNARK proofs for each Sapling Output. | |
| † | \(64\) | bindingSigSapling |
byte[64] |
A Sapling binding signature on the SIGHASH transaction hash. |
| Orchard Transaction Fields | ||||
varies |
nActionsOrchard |
compactSize |
The number of Orchard Action descriptions in vActionsOrchard. |
|
\(820\,\cdot\) nActionsOrchard |
vActionsOrchard |
OrchardAction[nActionsOrchard] |
A sequence of Orchard Action descriptions, encoded per § 7.5 ‘Action Description Encoding and Consensus’. | |
| § | \(1\) | flagsOrchard |
byte |
An 8-bit value representing a set of flags. From LSB to MSB: enableSpends, enableOutputs, enableCrossAddress (new at NU6.3); the remaining bits MUST be 0. |
| § | \(8\) | valueBalanceOrchard |
int64 |
The net value of Orchard spends minus outputs. |
| § | \(32\) | anchorOrchard |
byte[32] |
A root of the Orchard note commitment tree at some block height in the past. |
| § | varies |
sizeProofsOrchard |
compactSize |
Length in bytes of proofsOrchard. Value is 2720 + 2272 * nActionsOrchard. |
| § | sizeProofsOrchard |
proofsOrchard |
byte[sizeProofsOrchard] |
Encoding of aggregated zk-SNARK proofs for Orchard Actions. |
\(64\,\cdot\) nActionsOrchard |
vSpendAuthSigsOrchard |
byte[64 * nActionsOrchard] |
Authorizing signatures for each Orchard Action. | |
| § | \(64\) | bindingSigOrchard |
byte[64] |
An Orchard binding signature on the SIGHASH transaction hash. |
| Ironwood Transaction Fields (new) | ||||
varies |
nActionsIronwood |
compactSize |
The number of Ironwood Action descriptions in vActionsIronwood. |
|
\(820\,\cdot\) nActionsIronwood |
vActionsIronwood |
OrchardAction[nActionsIronwood] |
A sequence of Ironwood Action descriptions, using the same encoding as Orchard Actions (§ 7.5). | |
| ◊ | \(1\) | flagsIronwood |
byte |
The same layout as flagsOrchard, including enableCrossAddress at bit 2; the remaining bits MUST be 0. |
| ◊ | \(8\) | valueBalanceIronwood |
int64 |
The net value of Ironwood spends minus outputs. |
| ◊ | \(32\) | anchorIronwood |
byte[32] |
A root of the Ironwood note commitment tree at some block height in the past. |
| ◊ | varies |
sizeProofsIronwood |
compactSize |
Length in bytes of proofsIronwood. Value is 2720 + 2272 * nActionsIronwood. |
| ◊ | sizeProofsIronwood |
proofsIronwood |
byte[sizeProofsIronwood] |
Encoding of aggregated zk-SNARK proofs for Ironwood Actions. |
\(64\,\cdot\) nActionsIronwood |
vSpendAuthSigsIronwood |
byte[64 * nActionsIronwood] |
Authorizing signatures for each Ironwood Action. | |
| ◊ | \(64\) | bindingSigIronwood |
byte[64] |
An Ironwood binding signature on the SIGHASH transaction hash. |
Fields marked in the Note column are conditionally present:
| Note | Description |
|---|---|
| † | valueBalanceSapling and bindingSigSapling are present if and only if nSpendsSapling + nOutputsSapling > 0. If valueBalanceSapling is not present, it is taken to be 0. |
| ‡ | anchorSapling is present if and only if nSpendsSapling > 0. |
| § | flagsOrchard, valueBalanceOrchard, anchorOrchard, sizeProofsOrchard, proofsOrchard, and bindingSigOrchard are present if and only if nActionsOrchard > 0. If valueBalanceOrchard is not present, it is taken to be 0. |
| ◊ | flagsIronwood, valueBalanceIronwood, anchorIronwood, sizeProofsIronwood, proofsIronwood, and bindingSigIronwood are present if and only if nActionsIronwood > 0. If valueBalanceIronwood is not present, it is taken to be 0. |
The encoding of the transparent and Sapling fields is unchanged from version 5
16. Ironwood Action descriptions use the same OrchardAction encoding as
Orchard Action descriptions. Every Ironwood-pool output note uses the quantum-recoverable
note plaintext format (lead byte 0x03) defined in ZIP 2005 5; no Orchard-pool
output note uses that format. This is the only note-level distinction between the two pools.
Two flagsOrchard bits have been renamed relative to version 5: enableSpendsOrchard →
enableSpends and enableOutputsOrchard → enableOutputs. In version 6 these bits
—together with enableCrossAddress— are defined with the same meaning in both flagsOrchard
and flagsIronwood, so the previous ...Orchard suffix would be misleading.
The version 6 transaction format requires the changes below to the transaction consensus rules in § 7.1.2 ‘Transaction Consensus Rules’ 18, effective from NU6.3 activation. Purely editorial generalizations — such as replacing Orchard pool with Orchard or Ironwood pool, or updating cross-references — are not enumerated.
[Pre-NU6.3] The transaction version number MUST be 4 or 5.
with
[NU6.3 onward] The transaction version number MUST be 4 or 5 or 6.
[NU6.3 onward] If the transaction version number is 6 then the version group ID MUST be
0xD884B698.
[NU6.3 onward] If
effectiveVersion\(\geq 6\kern-0.05em\textsf{,}\) thennActionsIronwoodMUST be less than \(2^{16}\kern-0.05em\textsf{.}\)
[NU5 onward] If
effectiveVersion\(\geq 5\) then this condition MUST hold:tx_in_count\(> 0\) ornSpendsSapling\(> 0\) or (nActionsOrchard\(> 0\) andenableSpendsOrchard\(= 1\kern-0.15em\) ).
with
[NU5, pre-NU6.3] If
effectiveVersion\(= 5\) then this condition MUST hold:tx_in_count\(> 0\) ornSpendsSapling\(> 0\) or (nActionsOrchard\(> 0\) andenableSpendsOrchard\(= 1\kern-0.15em\) ).[NU6.3 onward] If
effectiveVersion\(\geq 6\) then this condition MUST hold:tx_in_count\(> 0\) ornSpendsSapling\(> 0\) or (nActionsOrchard\(> 0\) andenableSpendsOrchard\(= 1\kern-0.15em\) ) or (nActionsIronwood\(> 0\) andenableSpendsIronwood\(= 1\kern-0.15em\) ).
and likewise for the corresponding output-side condition, with tx_out_count, nOutputsSapling,
enableOutputsOrchard, and enableOutputsIronwood in place of tx_in_count, nSpendsSapling,
enableSpendsOrchard, and enableSpendsIronwood respectively.
[NU6.3 onward] If
effectiveVersion\(\geq 6\) andnActionsIronwood\(> 0\kern-0.05em\textsf{,}\) then at least one ofenableSpendsIronwoodandenableOutputsIronwoodMUST be 1.
[NU6.3 onward] If
effectiveVersion\(\geq 6\) andnActionsIronwood\(> 0\kern-0.05em\textsf{,}\) thenbindingSigIronwoodMUST represent a valid signature, under the Ironwood pool’s transaction binding validating key, of the SIGHASH transaction hash — with the binding validating key and SIGHASH as defined for the Ironwood pool in § 4.14 ‘Balance and Binding Signature (Orchard)’. As for the Orchard pool, validation of theRcomponent of the signature prohibits non-canonical point encodings.
[NU6.3 onward] A coinbase transaction MUST NOT have any Orchard-pool Action Descriptions.
[NU5 onward] In a version 5 coinbase transaction, the
enableSpendsOrchardflag MUST be 0.
with
[NU5 onward] In a version 5 or version 6 coinbase transaction, the
enableSpendsOrchardflag MUST be 0.
[NU6.3 onward] In a version 6 coinbase transaction, the
enableSpendsIronwoodflag MUST be 0.
[NU5 onward] In a version 5 transaction, the reserved bits 2..7 of the
flagsOrchardfield MUST be zero.
with
[NU5 onward] In a version 5 or version 6 transaction, the reserved bits 2..7 of the
flagsOrchardfield MUST be zero.
[NU6.3 onward] In a version 6 transaction, the reserved bits 3..7 of the
flagsIronwoodfield MUST be zero.
The enableCrossAddress bit is specified in 6. Note that the reserved-bit rules above
leave bit 2 of flagsOrchard reserved as 0 (bits 2..7), while bit 2 of flagsIronwood is the
enableCrossAddress bit (reserved bits 3..7); the Orchard pool’s cross-address restriction is
enforced for its Actions from NU6.3 onward as specified in 6.
This ZIP additionally specifies, for the version 6 format, that the proofs in proofsOrchard and the
signatures in vSpendAuthSigsOrchard each correspond 1:1 to the elements of vActionsOrchard, in
the same order; and likewise the proofs in proofsIronwood and the signatures in
vSpendAuthSigsIronwood to the elements of vActionsIronwood. (Conditional presence of fields is
given in the format table above.)
Version 4, version 5, and version 6 transactions are all valid from NU6.3 activation onward; this ZIP defines only the version 6 format (the version 4 and version 5 formats are unchanged). The NU6.3 consensus rules on Orchard actions apply regardless of transaction version. In particular, the Orchard-protocol cross-address restriction is enforced for every Orchard-pool Action mined from NU6.3 onward 6, so that it cannot be bypassed by using a version 5 transaction.
See 8 for additional consensus requirements that apply
to all transactions from NU6.3 onward, regardless of transaction version. (Briefly and
non-normatively, these are that coinbase transactions must have an empty Orchard component;
that the enableCrossAddress bit of flagsOrchard must be 0; and that
\(\mathsf{v}^{\textit{OrchardPoolBalance}}\) must be nonnegative.)
Version 6 transaction identifiers (txids), authorizing-data commitments (“auth digests”), and signature digests are computed as in ZIP 244 19, with two changes: an Ironwood component digest is added, and for version 6 the Sapling, Orchard and Ironwood anchors move from effecting data to authorizing data. The version 5 algorithm is unchanged.
Relative to the txid digest for v5 transactions 20, the version 6 txid digest adds an Ironwood component digest as the last child, after the Orchard component digest:
txid_digest_v6 = BLAKE2b-256("ZcashTxHash_" || consensusBranchId,
header_digest || transparent_digest || sapling_digest_v6 ||
orchard_digest_v6 || ironwood_digest_v6)
Relative to the auth digest for v5 transactions 21, the version 6 auth digest adds an Ironwood auth digest as the last child, after the Orchard one:
auth_digest_v6 = BLAKE2b-256("ZTxAuthHash_" || consensusBranchId,
transparent_auth_digest || sapling_auth_digest_v6 ||
orchard_auth_digest_v6 || ironwood_auth_digest_v6)
In version 5, the Sapling anchor (encoded redundantly as anchor in each
sapling_spends_noncompact_digest) and the Orchard anchor (anchorOrchard in orchard_digest)
are part of the effecting data: they are committed to in txid_digest, while the Sapling and
Orchard auth digests commit only to proofs and signatures 21.
In version 6, for Sapling, Orchard, and Ironwood components, the anchor is instead part of the authorizing data. Relative to ZIP 244, for version 6 transactions:
sapling_spends_noncompact_digest_v6, orchard_digest_v6, and ironwood_digest_v6 omit the anchor.sapling_auth_digest_v6, orchard_auth_digest_v6, and ironwood_auth_digest_v6 additionally commit
to anchorSapling, anchorOrchard, or anchorIronwood respectively, after the existing fields.
As in the serialization, each anchor is present only when its component has a spend or
action referencing it: anchorSapling iff nSpendsSapling > 0, anchorOrchard iff
nActionsOrchard > 0, and anchorIronwood iff nActionsIronwood > 0. In particular,
a Sapling component with outputs but no spends (for example a transparent-to-Sapling
transfer) commits to no anchorSapling.This lets the anchor be updated (re-anchored to a more recent note commitment tree root) without changing the transaction ID, while the proofs still bind to the specific anchor used.
ironwood_digest_v6 and ironwood_auth_digest_v6 are computed with the same structure as
orchard_digest_v6 and orchard_auth_digest_v6, but with Ironwood-specific 16-byte BLAKE2b-256
personalizations at each node. Also, distinct personalizations are used for Sapling and Orchard nodes
where what is directly hashed has been affected as a result of moving the anchor commitments to auth
data, as follows:
| Node | v5 personalization | v6 personalization | Comment for v6 |
|---|---|---|---|
| \(\hspace{22em}\) Sapling | |||
sapling_digest[_v6] |
ZTxIdSaplingHash |
ZTxIdSaplingHash |
not changed directly |
sapling_spends_digest |
ZTxIdSSpendsHash |
ZTxIdSSpendsHash |
unchanged |
sapling_spends_compact_digest |
ZTxIdSSpendCHash |
ZTxIdSSpendCHash |
unchanged |
sapling_spends_noncompact_digest[_v6] |
ZTxIdSSpendNHash |
ZTxIdSSpendNH_v6 |
omits anchor |
sapling_auth_digest[_v6] |
ZTxAuthSapliHash |
ZTxAuthSapliH_v6 |
includes anchorSapling |
| \(\hspace{22em}\) Orchard | |||
orchard_digest[_v6] |
ZTxIdOrchardHash |
ZTxIdOrchardH_v6 |
omits anchorOrchard |
orchard_actions_compact_digest |
ZTxIdOrcActCHash |
ZTxIdOrcActCHash |
unchanged |
orchard_actions_memos_digest |
ZTxIdOrcActMHash |
ZTxIdOrcActMHash |
unchanged |
orchard_actions_noncompact_digest |
ZTxIdOrcActNHash |
ZTxIdOrcActNHash |
unchanged |
orchard_auth_digest[_v6] |
ZTxAuthOrchaHash |
ZTxAuthOrchaH_v6 |
includes anchorOrchard |
| \(\hspace{22em}\) Ironwood | |||
ironwood_digest_v6 |
n/a | ZTxIdIronwd_H_v6 |
omits anchorIronwood |
ironwood_actions_compact_digest_v6 |
n/a | ZTxIdIrnActCH_v6 |
|
ironwood_actions_memos_digest_v6 |
n/a | ZTxIdIrnActMH_v6 |
|
ironwood_actions_noncompact_digest_v6 |
n/a | ZTxIdIrnActNH_v6 |
|
ironwood_auth_digest_v6 |
n/a | ZTxAuthIrnwdH_v6 |
includes anchorIronwood |
As in the case of Sapling and Orchard, when a version 6 transaction has no Ironwood actions,
ironwood_digest_v6 and ironwood_auth_digest_v6 are the hashes of empty input under the component
and auth personalizations respectively, i.e. BLAKE2b-256("ZTxIdIronwd_H_v6", []) and
BLAKE2b-256("ZTxAuthIrnwdH_v6", []), which are distinct from the Orchard empty-component digests.
Below, (*) indicates a node that is directly changed relative to v5, and (+) indicates a node
that is added relative to v5.
The txid digest structure becomes:
txid_digest_v6
├── header_digest
├── transparent_digest
│ ├── prevouts_digest
│ ├── sequence_digest
│ └── outputs_digest
├── sapling_digest_v6
│ ├── sapling_spends_digest_v6
│ │ ├── sapling_spends_compact_digest
│ │ └── sapling_spends_noncompact_digest_v6 (*)
│ │ ├── cv
│ │ └── rk
│ ├── sapling_outputs_digest
│ │ ├── sapling_outputs_compact_digest
│ │ ├── sapling_outputs_memos_digest
│ │ └── sapling_outputs_noncompact_digest
│ └── valueBalance
├── orchard_digest_v6 (*)
│ ├── orchard_actions_compact_digest
│ ├── orchard_actions_memos_digest
│ ├── orchard_actions_noncompact_digest
│ ├── flagsOrchard
│ └── valueBalanceOrchard
└── ironwood_digest_v6 (+)
├── ironwood_actions_compact_digest_v6
├── ironwood_actions_memos_digest_v6
├── ironwood_actions_noncompact_digest_v6
├── flagsIronwood
└── valueBalanceIronwood
The auth digest structure becomes:
auth_digest_v6
├── transparent_scripts_digest
├── sapling_auth_digest_v6 (*)
│ ├── vSpendProofsSapling
│ ├── vSpendAuthSigsSapling
│ ├── vOutputProofsSapling
│ ├── bindingSigSapling
│ └── anchorSapling (+)
├── orchard_auth_digest_v6 (*)
│ ├── proofsOrchard
│ ├── vSpendAuthSigsOrchard
│ ├── bindingSigOrchard
│ └── anchorOrchard (+)
└── ironwood_auth_digest_v6 (+)
├── proofsIronwood
├── vSpendAuthSigsIronwood
├── bindingSigIronwood
└── anchorIronwood
Note that the nodes under each of sapling_digest_v6, orchard_digest_v6, ironwood_digest_v6,
and their auth_digests are present only if the corresponding component is non-empty.
The hashAuthDataRoot component of hashBlockCommitments 19 incorporates the version 6 auth
digest — which now includes the Ironwood auth digest, and (per the change above) the anchors — with
no further structural change.
The main purpose of the NU6.3 network upgrade is to bolster confidence in Zcash’s supply integrity, after the discovery and remediation of the Orchard soundness vulnerability described in 12.
The urgency of this motivation called for an accelerated timeline, which necessitated a high bar for feature inclusion. Therefore, even fairly straightforward improvements (such as 22, which had been “queued” for inclusion in the next transaction format update), were omitted from this upgrade.
Carrying the Ironwood pool as a second Orchard-protocol component, rather than defining a new shielded protocol, keeps the transaction-format and implementation surface small: the Action encoding, proving system, authorization, and note encryption (modulo the new note plaintext format defined by 5) are inherited unchanged. The pools are distinguished by their note commitment trees, nullifier sets, value pool balances, and component position, not by separate circuits.
Giving the Ironwood pool its own note commitment tree, anchor, and nullifier set creates a state boundary from the Orchard pool, so that their chain value pool balance can be accounted for independently.
enableCrossAddress polarity This flag is encoded in the enabled sense (1 = cross-address transfers enabled, the
normal case for Ironwood-pool actions; 0 = action outputs restricted to use the same
protocol-level address as the action’s spend), with bit 2 reserved as 0 before NU6.3.
This is backward-compatible: an Orchard-pool spend after NU6.3 requires the restricted
state, which is bit 2 = 0 — exactly the value that signers treating bit 2 as a
reserved-zero bit already produce. The in-circuit constraint and the equivalent internal
disableCrossAddress instance value are discussed in 6.
This transaction format is deployed at NU6.3. Activation heights and the NU6.3 consensus branch ID are specified in 8; the version 6 version group ID is specified in § 7.1.2 18.
We thank the developers of Penumbra 23 for demonstrating the advantages of treating the note commitment tree anchor as authorizing data rather than effecting data.
Information on BCP 14 — “RFC 2119: Key words for use in RFCs to Indicate Requirement Levels” and “RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words” ↩︎
Zcash Protocol Specification, Version 2026.8.0 [NU6.3] or later ↩︎
Zcash Protocol Specification, Version 2026.8.0 [NU6.3]. Section 3.12: Mainnet and Testnet ↩︎
ZIP 257: Deployment of the Orchard Temporary Vulnerability Mitigation and NU6.2 Network Upgrade ↩︎
ZIP 209: Prohibit Out-of-Range Shielded Chain Value Pool Balances ↩︎
ZIP 248: Extensible Transaction Format (unmerged; PR at https://github.com/zcash/zips/pull/1156) ↩︎
Zcash Protocol Specification, Version 2026.8.0 [NU6.3]. Section 7.1.2: Transaction Consensus Rules ↩︎
ZIP 244: Transaction Identifier Non-Malleability — TxId Digest ↩︎
ZIP 244: Transaction Identifier Non-Malleability — Authorizing Data Commitment ↩︎