Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0865fb5
[ZIP 248]: Add motivation & notes for design of an extensible transac…
nuttycom Jan 11, 2026
2c4e2a5
[ZIP 248]: Fill in Privacy Implications section.
nuttycom Jan 19, 2026
50ec7dc
[ZIP 248]: Add `BundleDescription`
nuttycom Jan 19, 2026
a34686f
[ZIP 248]: Add bundle ID registry
nuttycom Jan 20, 2026
f579c6e
[ZIP 248]: Fix rst rendering
nuttycom Jan 20, 2026
978a2f0
[ZIP 248]: Render update to README.rst
nuttycom Jan 20, 2026
10707fd
[ZIP 248]: Add consensus rules for transaction value balance.
nuttycom Jan 23, 2026
4737975
[ZIP 248]: Separate effecting data bundles from authorizing data bund…
nuttycom Jan 23, 2026
fcb7b4f
[ZIP 248]: Add bundle format specifications for Transparent, Sapling,…
nuttycom Jan 25, 2026
5408249
[ZIP 248]: Add digest algorithms for txid, signature, and auth commit…
nuttycom Jan 25, 2026
7eaf1cf
[ZIP 248]: Add protocol bundles introduction and bundle type registra…
nuttycom Jan 28, 2026
7adfcc3
[ZIP 248]: Fix table rendering
nuttycom Jan 28, 2026
eb46353
[ZIP 248]: Fold away rationale & potental future bundle types spec.
nuttycom Jan 28, 2026
eea32d1
[ZIP 248]: Address PR review comments.
nuttycom Jan 30, 2026
2e691c5
[ZIP 2002]: Propose to register ZIP 248 bundle type 4.
nuttycom Feb 4, 2026
e3e308e
[ZIP 233]: Propose to register ZIP 248 bundle type 5.
nuttycom Feb 4, 2026
f1bb200
[ZIP 231]: Propose to register ZIP 248 bundle types.
nuttycom Feb 4, 2026
8dd23c8
[ZIP 227]: Propose to register a ZIP 248 bundle type for ZSA Issuance.
nuttycom Feb 4, 2026
da23c37
[ZIP 226]: Register ZIP 248 bundle type.
nuttycom Feb 4, 2026
70f0837
[ZIP 248]: Change bundle identifiers to (bundleType, bundleVersion) t…
nuttycom Mar 6, 2026
77ac086
[ZIP 248]: Add wallet implications section; update ZIP 226 references.
nuttycom Mar 6, 2026
90ca207
[ZIP 248]: Rename `bundleVersion` to `bundleVariant`
nuttycom Mar 24, 2026
286d34d
[ZIP 248]: Specify `mValuePoolDeltas` encoding order.
nuttycom Mar 24, 2026
2a8a2d9
[ZIP 248]: Fix ordering constraint in signature hashing.
nuttycom Mar 24, 2026
5c49035
[ZIP 248]: Address comments from code review.
nuttycom Mar 24, 2026
3d31529
Merge remote-tracking branch 'upstream/main' into draft/extensible_tx…
nuttycom May 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ written.
<tr> <td><span class="reserved">240</span></td> <td class="left"><a class="reserved" href="zips/zip-0240.md">Standard Transaction Rules</a></td> <td>Reserved</td> <td class="left"><a href="https://github.com/zcash/zips/issues/648">zips#648</a></td>
<tr> <td>245</td> <td class="left"><a href="zips/zip-0245.rst">Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions</a></td> <td>Draft</td> <td class="left"><a href="https://github.com/zcash/zips/issues/384">zips#384</a></td>
<tr> <td>246</td> <td class="left"><a href="zips/zip-0246.rst">Digests for the Version 6 Transaction Format</a></td> <td>Draft</td> <td class="left"></td>
<tr> <td>248</td> <td class="left"><a href="zips/zip-0248.rst">Extensible Transaction Format</a></td> <td>Draft</td> <td class="left"><a href="https://github.com/zcash/zips/pull/1163">zips/pull/1163</a></td>
<tr> <td><span class="reserved">260</span></td> <td class="left"><a class="reserved" href="zips/zip-0260.md">Extending Block Messages with Additional Authentication Data</a></td> <td>Reserved</td> <td class="left"><a href="https://github.com/zcash/zips/issues/522">zips#522</a></td>
<tr> <td><span class="reserved">270</span></td> <td class="left"><a class="reserved" href="zips/zip-0270.md">Key Rotation for Tracked Signing Keys</a></td> <td>Reserved</td> <td class="left"><a href="https://github.com/zcash/zips/issues/1047">zips#1047</a></td>
<tr> <td>302</td> <td class="left"><a href="zips/zip-0302.rst">Standardized Memo Field Format</a></td> <td>Draft</td> <td class="left"><a href="https://github.com/zcash/zips/issues/366">zips#366</a></td>
Expand Down Expand Up @@ -327,6 +328,7 @@ Index of ZIPs
<tr> <td>244</td> <td class="left"><a href="zips/zip-0244.rst">Transaction Identifier Non-Malleability</a></td> <td>Final</td>
<tr> <td>245</td> <td class="left"><a href="zips/zip-0245.rst">Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions</a></td> <td>Draft</td>
<tr> <td>246</td> <td class="left"><a href="zips/zip-0246.rst">Digests for the Version 6 Transaction Format</a></td> <td>Draft</td>
<tr> <td>248</td> <td class="left"><a href="zips/zip-0248.rst">Extensible Transaction Format</a></td> <td>Draft</td>
<tr> <td>250</td> <td class="left"><a href="zips/zip-0250.rst">Deployment of the Heartwood Network Upgrade</a></td> <td>Final</td>
<tr> <td>251</td> <td class="left"><a href="zips/zip-0251.rst">Deployment of the Canopy Network Upgrade</a></td> <td>Final</td>
<tr> <td>252</td> <td class="left"><a href="zips/zip-0252.rst">Deployment of the NU5 Network Upgrade</a></td> <td>Final</td>
Expand Down
244 changes: 219 additions & 25 deletions zips/zip-0226.rst

Large diffs are not rendered by default.

159 changes: 141 additions & 18 deletions zips/zip-0227.rst

Large diffs are not rendered by default.

171 changes: 166 additions & 5 deletions zips/zip-0231.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,154 @@ Since this proposal is defined only for v6 and later transactions, it is not
necessary to consider Sprout JoinSplit outputs. The following sections apply
to both Sapling and Orchard outputs in v6-onward transactions.

## Changes to ZIP 248

This ZIP proposes to register a new bundle type for Memos and new versions of
the Sapling and Orchard bundle types in the V6 transaction bundle type registry
defined in ZIP 248 [^zip-0248]:

| BundleType | BundleVariant | `mValuePoolDeltas` | `mEffectBundles` | `mAuthBundles` | Bundle kind |
|------------|---------------|--------------------|------------------|----------------|----------------------|
| TBD | 0 |❌ |✅ |❌ | Memos |
| 2 | TBD |✅ |✅ |✅ | Sapling-post-ZIP 231 |
| 3 | TBD |✅ |✅ |✅ | Orchard-post-ZIP 231 |

The Memos bundle has no value pool deltas (memo data does not involve value
transfers) and no authorizing data. The effecting data consists of the encoded
memo bundle as defined in [Encoding in transactions].

The Sapling-post-ZIP 231 and Orchard-post-ZIP 231 entries are new variants of
the existing Sapling (``bundleType`` 2) and Orchard (``bundleType`` 3) bundle
types respectively. Because ZIP 248 requires that each bundle map is keyed by
``bundleType`` alone, a transaction that includes a Sapling-post-ZIP 231 bundle
cannot also include a pre-ZIP 231 Sapling bundle, and similarly for Orchard.

If this ZIP is activated in the same network upgrade as ZIP 248, the encoding
of the Sapling and Orchard bundles described in this ZIP will be used for
bundle type 2 variant 0 and bundle type 3 variant 0, respectively, and
ZIP 248's definition of the Sapling and Orchard bundles must be updated
accordingly. If this ZIP is activated in a network upgrade AFTER the network
upgrade in which ZIP 248 is activated, the encodings it describes will be
assigned distinct bundle variant identifiers for their respective bundle types.

## Sapling-post-ZIP 231 Bundle

The Sapling-post-ZIP 231 bundle replaces the Sapling bundle defined in
ZIP 248 [^zip-0248]. The only change is that the note plaintext in each
Sapling output is shortened: the 512-byte memo field is replaced by a
32-byte $\mathsf{K^{memo}}$, reducing `encCiphertext` from 580 bytes to
100 bytes.

### Sapling-post-ZIP 231 Effecting Data

The effecting data for the Sapling-post-ZIP 231 bundle describes the Sapling
spends and outputs.

| Bytes | Name | Data Type | Description |
|--------------------------|--------------------|---------------------------------------------|------------------------------------------------------------------------------|
| varies | `nSpendsSapling` | `compactSize` | Number of Sapling Spend descriptions. |
| 96 \* nSpendsSapling | `vSpendsSapling` | `SaplingSpendEffecting[nSpendsSapling]` | Effecting data for each Sapling Spend. |
| varies | `nOutputsSapling` | `compactSize` | Number of Sapling Output descriptions. |
| 276 \* nOutputsSapling | `vOutputsSapling` | `SaplingOutputPostZIP231[nOutputsSapling]` | Sapling Output descriptions. |
| 32 | `anchorSapling` | `byte[32]` | A root of the Sapling note commitment tree at some block height in the past. |

* The field `anchorSapling` is present if and only if $\mathtt{nSpendsSapling} > 0$.

`SaplingSpendEffecting` is unchanged from ZIP 248 [^zip-0248].

#### SaplingOutputPostZIP231

| Bytes | Name | Data Type | Description |
|-------|-----------------|-------------|---------------------------------------------------------------------------------------------------------------------------|
| 32 | `cv` | `byte[32]` | A value commitment to the net value of the output note. |
| 32 | `cmu` | `byte[32]` | The $u$-coordinate of the note commitment for the output note. |
| 32 | `ephemeralKey` | `byte[32]` | An encoding of an ephemeral Jubjub public key. |
| 100 | `encCiphertext` | `byte[100]` | The encrypted contents of the note plaintext, which contains $\mathsf{K^{memo}}$ in place of the 512-byte memo field. |
| 80 | `outCiphertext` | `byte[80]` | The encrypted contents of the byte string created by concatenation of the transmission key with the ephemeral secret key. |

### Sapling-post-ZIP 231 Authorizing Data

The authorizing data is unchanged from the Sapling bundle defined in
ZIP 248 [^zip-0248].

| Bytes | Name | Data Type | Description |
|--------------------------|--------------------------|-----------------------------------|--------------------------------------------------------------|
| 192 \* nSpendsSapling | `vSpendProofsSapling` | `byte[192 * nSpendsSapling]` | Encodings of the zk-SNARK proofs for each Sapling Spend. |
| 64 \* nSpendsSapling | `vSpendAuthSigsSapling` | `byte[64 * nSpendsSapling]` | Authorizing signatures for each Sapling Spend. |
| 192 \* 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. |

* The values of `nSpendsSapling` and `nOutputsSapling` are not re-encoded in
the authorizing data; they are taken from the corresponding effecting data.
* The field `bindingSigSapling` is present if and only if
$\mathtt{nSpendsSapling} + \mathtt{nOutputsSapling} > 0$.
* The elements of `vSpendProofsSapling` and `vSpendAuthSigsSapling` have a
1:1 correspondence to the elements of `vSpendsSapling` in the effecting data
and MUST be ordered such that the element at a given index corresponds to the
`SaplingSpendEffecting` at the same index.
* The elements of `vOutputProofsSapling` have a 1:1 correspondence to the
elements of `vOutputsSapling` in the effecting data and MUST be ordered such
that the proof at a given index corresponds to the `SaplingOutputPostZIP231`
at the same index.

## Orchard-post-ZIP 231 Bundle

The Orchard-post-ZIP 231 bundle replaces the Orchard bundle defined in
ZIP 248 [^zip-0248]. As with Sapling, the only change is that the note
plaintext in each Orchard action is shortened: the 512-byte memo field is
replaced by a 32-byte $\mathsf{K^{memo}}$, reducing `encCiphertext` from
580 bytes to 100 bytes.

### Orchard-post-ZIP 231 Effecting Data

The effecting data for the Orchard-post-ZIP 231 bundle describes the Orchard
actions.

| Bytes | Name | Data Type | Description |
|--------------------------|--------------------|-------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|
| varies | `nActionsOrchard` | `compactSize` | The number of Orchard Action descriptions. |
| 340 \* nActionsOrchard | `vActionsOrchard` | `OrchardActionPostZIP231[nActionsOrchard]` | Effecting data for each Orchard Action. |
| 1 | `flagsOrchard` | `byte` | An 8-bit value representing a set of flags. Ordered from LSB to MSB: `enableSpendsOrchard`, `enableOutputsOrchard`. The remaining bits are set to $0$. |
| 32 | `anchorOrchard` | `byte[32]` | A root of the Orchard note commitment tree at some block height in the past. |

* The fields `flagsOrchard` and `anchorOrchard` are present if and only if
$\mathtt{nActionsOrchard} > 0$.
* For coinbase transactions, the `enableSpendsOrchard` bit MUST be set to $0$.

#### OrchardActionPostZIP231

| Bytes | Name | Data Type | Description |
|-------|-----------------|-------------|---------------------------------------------------------------------------------------------------------------------------|
| 32 | `cv` | `byte[32]` | A value commitment to the net value of the input note minus the output note. |
| 32 | `nullifier` | `byte[32]` | The nullifier of the input note. |
| 32 | `rk` | `byte[32]` | The randomized validating key for this Action. |
| 32 | `cmx` | `byte[32]` | The $x$-coordinate of the note commitment for the output note. |
| 32 | `ephemeralKey` | `byte[32]` | An encoding of an ephemeral Pallas public key. |
| 100 | `encCiphertext` | `byte[100]` | The encrypted contents of the note plaintext, which contains $\mathsf{K^{memo}}$ in place of the 512-byte memo field. |
| 80 | `outCiphertext` | `byte[80]` | The encrypted contents of the byte string created by concatenation of the transmission key with the ephemeral secret key. |

### Orchard-post-ZIP 231 Authorizing Data

The authorizing data is unchanged from the Orchard bundle defined in
ZIP 248 [^zip-0248].

| Bytes | Name | Data Type | Description |
|--------------------------|--------------------------|-----------------------------------|--------------------------------------------------------------------------------------------|
| varies | `sizeProofsOrchard` | `compactSize` | Length in bytes of `proofsOrchard`. Value is $2720 + 2272 \cdot \mathtt{nActionsOrchard}$. |
| sizeProofsOrchard | `proofsOrchard` | `byte[sizeProofsOrchard]` | Encoding of aggregated zk-SNARK proofs for Orchard Actions. |
| 64 \* nActionsOrchard | `vSpendAuthSigsOrchard` | `byte[64 * nActionsOrchard]` | Authorizing signatures for each Orchard Action. |
| 64 | `bindingSigOrchard` | `byte[64]` | An Orchard binding signature on the SIGHASH transaction hash. |

* The value of `nActionsOrchard` is not re-encoded in the authorizing data; it
is taken from the corresponding effecting data.
* The fields `sizeProofsOrchard`, `proofsOrchard`, and `bindingSigOrchard` are
present if and only if $\mathtt{nActionsOrchard} > 0$.
* The proofs aggregated in `proofsOrchard`, and the elements of
`vSpendAuthSigsOrchard`, each have a 1:1 correspondence to the elements of
`vActionsOrchard` in the effecting data and MUST be ordered such that the
proof or signature at a given index corresponds to the
`OrchardActionPostZIP231` at the same index.

## Memo bundle

A memo bundle consists of a sequence of 272-byte memo chunks, each encrypting
Expand Down Expand Up @@ -386,6 +534,9 @@ transaction.

## Encoding in transactions

The following describes the effecting data for the memo bundle. This data
appears in `mEffectBundles` with the memo bundle type identifier.

| Bytes | Name | Data Type | Description |
|----------|------------------------|---------------------------------------------------|------------------------------------------------------------------------|
| 1 | $\mathtt{fAllPruned}$ | $\mathtt{uint8}$ | 1 if the memo bundle has been pruned, otherwise 0. |
Expand All @@ -403,13 +554,21 @@ If $\mathtt{fAllPruned} = 0$, then:
If $\mathtt{fAllPruned} = 1$, then:

- $\mathtt{saltOrHash}$ contains the $\mathsf{memo\_bundle\_digest}$ as defined in
[Transaction sighash].
[Transaction Digest].
- The $\mathtt{nMemoChunks}$ and $\mathtt{vMemoChunks}$ fields will be absent.

## Transaction sighash
## Transaction Digest

The memo bundle contributes to the transaction identifier via the
`effects_bundles_digest` defined in ZIP 248 [^zip-0248].

$\mathsf{memo\_chunk\_digest}[i] = H(\mathtt{vMemoChunks}[i]) \\$
$\mathsf{memo\_bundle\_digest} = H(\mathsf{concat}(\mathsf{memo\_chunk\_digests}))$
The memo bundle's effect digest is computed as follows:

$\mathsf{memo\_chunk\_digest}[i] = \mathsf{BLAKE2b\text{-}256}(\texttt{"ZTxIdMemoChunkHs"}, \mathtt{vMemoChunks}[i]) \\$
$\mathsf{memo\_bundle\_digest} = \mathsf{BLAKE2b\text{-}256}(\texttt{"ZTxIdMemoBundHsh"}, \mathsf{concat}(\mathsf{memo\_chunk\_digests}))$

For pruned chunks, the $\mathsf{memo\_chunk\_digest}$ stored in the transaction
encoding is used directly.

The memo bundle digest is used in place of the full memo bundle when
the bundle has been pruned.
Expand Down Expand Up @@ -789,9 +948,11 @@ TBD

[^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst)

[^zip-0248]: [ZIP 248: Extensible Transaction Format](zip-0248.rst)

[^draft-arya-deploy-nu7]: [draft-arya-deploy-nu7: Deployment of the NU7 Network Upgrade](draft-arya-deploy-nu7.md)

[^zip-0230-orchard-note-plaintext]: [ZIP 230: Version 6 Transaction Format — Orchard Note Plaintext](zip-0230.rst#orchard-note-plaintext)
[^zip-0230-note-plaintexts]: [ZIP 230: Version 6 Transaction Format — Note Plaintexts](zip-0230.rst#note-plaintexts)

[^zip-0248]: [ZIP 248: Extensible Transaction Format (PR: zcash/zips#1156)](https://github.com/zcash/zips/pull/1156)

Expand Down
Loading
Loading