PR #1443proposed changes toZIP 233·ZIP 248·ZIP 2002

ZIP 248 fixes

status → Draftby str4d · updated 2026-11-05zips/zip-0233.md @ d878b28d6d · upstream 4699a8d518view on GitHub ↗

Unofficial preview — the proposed text below is rendered from the pull request head and is not part of the canonical ZIP set.

ZIP: 233
Title: Network Sustainability Mechanism: Removing Funds From Circulation
Owners: Jason McGee <jason@shieldedlabs.net>
        Zooko Wilcox <zooko@shieldedlabs.net>
        Mark Henderson <mark@shieldedlabs.net>
        Tomek Piotrowski <tomek@eiger.co>
        Mariusz Pilarek <mariusz@eiger.co>
        Paul Dann <paul@eiger.co>
Original-Authors: Nathan Wilcox
Credits:
Status: Draft
Category: Consensus / Ecosystem
Created: 2023-08-16
License: BSD-2-Clause
Discussions-To: <https://github.com/zcash/zips/issues/922>

Terminology

The key word "MUST" in this document is to be interpreted as described in BCP 14 1 when, and only when, it appears 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

"ZEC/TAZ" refers to the native currency of Zcash on a given network, i.e. ZEC on Mainnet and TAZ on Testnet.

"Block Subsidy" - The algorithmic issuance of ZEC/TAZ on block creation, as defined by consensus. This is split between the miner and Funding Streams.

"Issuance" - The method by which ZEC/TAZ becomes available for circulation on the network. [TODO: there is a potential terminology conflict between this and issuance as defined in ZIP 227.]

𝖬𝖠𝖷_𝖬𝖮𝖭𝖤𝖸, as defined in § 5.3 ‘Constants’ 5, is the total ZEC/TAZ supply cap measured in zatoshi, corresponding to 21,000,000 ZEC. This is slightly larger than the supply cap for the current issuance mechanism, but is the value used in existing critical consensus checks.

Abstract

This ZIP proposes the introduction of a mechanism to voluntarily remove funds entirely from circulation on the network. The explicit intent of this removal is that the funds will be returned to circulation through future block subsidies, rather than being permanently destroyed or held in reserve for discretionary use. This mechanism, in combination with ZIPs 235 6 and 237 7, comprises a long-term strategy for the sustainability of the network. We will refer to the combined effects of these three ZIPs as the “Network Sustainability Mechanism”.

Motivation

This mechanism seeks to address concerns about the sustainability of the network design shared by Bitcoin-like systems:

  1. Long Term Consensus Sustainability: By enabling the removal of funds from circulation, the network gains the ability to create "headroom" between the chain value and 𝖬𝖠𝖷_𝖬𝖮𝖭𝖤𝖸. This lays necessary groundwork for extending the block subsidy system, which currently has a clear final end date. The intent is that removed funds will be automatically and algorithmically reissued through future block subsidies, sustaining the network's long-term security budget, whether or not all three ZIPs comprising the Network Sustainability Mechanism are deployed in the same network upgrade.
  2. Benefits to ZEC Holders: Removing funds from circulation reduces the circulating supply of ZEC. To the extent that this potentially contributes to an increase in the value of remaining ZEC, it can be argued to benefit network users in proportion to their holdings — without requiring them to opt into any scheme, introducing extra risk, active oversight, or accounting complexity.

Privacy Implications

ZIP 233 adds a new type of transparent transaction event that is fully visible to chain observers, and linked to other events performed in the transaction. The removal of funds from circulation does represent a potential distinguisher; transactions that intentionally remove funds from circulation are likely to represent a small fraction of Zcash transactions, and so this will provide another tool that adversaries may use to be able to segment users of the network.

Requirements

  • The mechanism enables users to remove funds from the circulating supply, and each removal event is explicitly specified in the corresponding transaction.
  • The process is publicly auditable, allowing network participants to verify the amount and occurrence of funds removed from circulation.

Specification

Changes to ZIP 248

This ZIP proposes to register bundle type 6 variant 0 ("ZIP 233 NSM field") in the V7 transaction bundle type registry defined in ZIP 248 8.

BundleTypeBundleVariantmValuePoolDeltasmEffectBundlesmAuthBundles
60✅❌❌

The NSM bundle has no effecting data and no authorizing data. The amount to be removed from circulation is represented solely as an entry in mValuePoolDeltas with bundleType = 6 and assetClass = 0 (ZEC).

NSM Amount

When the mValuePoolDeltas map contains an entry with bundleType = 6, the transaction removes funds from circulation. The entry's value field MUST be nonpositive; its negation is denoted 𝗓𝗂𝗉𝟤𝟥𝟥_𝖺𝗆𝗈𝗎𝗇𝗍 and represents the value in zatoshis removed from circulation when the transaction is mined. If no such entry is present, 𝗓𝗂𝗉𝟤𝟥𝟥_𝖺𝗆𝗈𝗎𝗇𝗍 is defined to be 0.

The NSM bundle's effect on the transparent transaction value pool does not reflect an output being produced in any chain value pool. At the point at which the transaction is applied to the global chain state, 𝗓𝗂𝗉𝟤𝟥𝟥_𝖺𝗆𝗈𝗎𝗇𝗍 is subtracted from the issued supply. It is unavailable for circulation on the network at least through to the end of the block in which the transaction is mined.

Changes to ZIP 237

This ZIP proposes to register the following mechanism for removal from circulation in the list defined in ZIP 237 7:

MechanismSource
Transaction field𝖭𝖲𝖬𝖥𝗂𝖾𝗅𝖽𝗌(𝗁𝖾𝗂𝗀𝗁𝗍)

𝖭𝖲𝖬𝖥𝗂𝖾𝗅𝖽𝗌(𝗁𝖾𝗂𝗀𝗁𝗍):=∑i=0𝖻𝗅𝗈𝖼𝗄[𝗁𝖾𝗂𝗀𝗁𝗍].𝗏𝗍𝗑[i].𝗓𝗂𝗉𝟤𝟥𝟥_𝖺𝗆𝗈𝗎𝗇𝗍

Changes to the Zcash Protocol Specification

Let 𝖭𝖲𝖬𝖡𝗎𝗇𝖽𝗅𝖾𝖨𝖽=6.

Let 𝖹𝖾𝖼 be the asset UUID for ZEC as defined in ZIP 248 8.

Make a change to § 3.4 'Transactions and Treestates' 9 adding the following consensus rules:

  • [NU7 onward] The assetClass for any entry in mValuePoolDeltas having bundleType =𝖭𝖲𝖬𝖡𝗎𝗇𝖽𝗅𝖾𝖨𝖽 MUST be 0. That is, amounts to remove from circulation MUST be denominated in ZEC.

  • [NU7 onward] The value of 𝗆𝖵𝖺𝗅𝗎𝖾𝖯𝗈𝗈𝗅𝖣𝖾𝗅𝗍𝖺𝗌[(𝖭𝖲𝖬𝖡𝗎𝗇𝖽𝗅𝖾𝖨𝖽,𝖹𝖾𝖼)], if present, MUST be nonpositive. Its absolute value is 𝗓𝗂𝗉𝟤𝟥𝟥_𝖺𝗆𝗈𝗎𝗇𝗍.

  • [NU7 onward] 𝗓𝗂𝗉𝟤𝟥𝟥_𝖺𝗆𝗈𝗎𝗇𝗍 does not result in an output being produced in any chain value pool.

In § 7.1 'Transaction Encoding and Consensus' 10, add:

[NU7 onward] 𝗓𝗂𝗉𝟤𝟥𝟥_𝖺𝗆𝗈𝗎𝗇𝗍 MUST be in the range {0..𝖬𝖠𝖷_𝖬𝖮𝖭𝖤𝖸}.

Modifications to Digest Algorithms

The 𝗓𝗂𝗉𝟤𝟥𝟥_𝖺𝗆𝗈𝗎𝗇𝗍 is committed to the transaction identifier via value_pool_deltas_digest and to the v0 signature digest via value_pool_deltas_sig_digest, as defined in ZIP 248 8. The NSM bundle's entry is included in the latter digest regardless of the transparent signature's hash_type. Since the NSM bundle (bundle type 6) has no effecting data and no authorizing data, its only contribution to these digests is through its entry in mValuePoolDeltas.

Applicability

All of these changes apply identically to Mainnet and Testnet.

Rationale

All technical decisions in this ZIP are balanced between the necessary robustness of the NSM mechanics, and simplicity of implementation.

New transaction field for amount to remove from circulation

An explicit value distinguishes the funds to remove from circulation from the transaction fee. Explicitness also ensures any arithmetic flaws in any implementations are more likely to be observed and caught immediately.

Deployment

This ZIP is not deployed in Network Upgrade 7. 11 It is proposed to activate in a later network upgrade.

References

Footnotes

  1. 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" ↩

  2. ZIP 200: Network Upgrade Mechanism ↩

  3. Zcash Protocol Specification, Version 2025.6.2 [NU6.1] or later ↩

  4. Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.12: Mainnet and Testnet ↩

  5. Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.3: Constants ↩

  6. ZIP 235: Remove 60% of Transaction Fees From Circulation ↩

  7. ZIP 237: Network Sustainability Mechanism: Halving-Preserving Issuance ↩ ↩2

  8. ZIP 248: Extensible Transaction Format ↩ ↩2 ↩3

  9. Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.4: Transactions And Treestates ↩

  10. Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 7.1.2 Transaction Consensus Rules ↩

  11. ZIP 259: Deployment of the NU7 Network Upgrade ↩

Changes

zips/zip-0233.md +7 −5
@@ -162,11 +162,13 @@ In § 7.1 'Transaction Encoding and Consensus' [^protocol-txnconsensus], add: ## Modifications to Digest Algorithms -The $\mathsf{zip233\_amount}$ is committed to the transaction identifier and -signature digest via the `value_pool_deltas_digest` defined in ZIP 248 [^zip-0248]. -Since the NSM bundle (bundle type 6) has no effecting data and no authorizing -data, its only contribution to the transaction digest is through its entry -in `mValuePoolDeltas`. +The $\mathsf{zip233\_amount}$ is committed to the transaction identifier via +`value_pool_deltas_digest` and to the v0 signature digest via +`value_pool_deltas_sig_digest`, as defined in ZIP 248 [^zip-0248]. The NSM +bundle's entry is included in the latter digest regardless of the transparent +signature's `hash_type`. Since the NSM bundle (bundle type 6) has no effecting +data and no authorizing data, its only contribution to these digests is through +its entry in `mValuePoolDeltas`. ## Applicability
zips/zip-0248.rst +406 −169
@@ -58,13 +58,28 @@ transparent transaction value pool Abstract ======== -This ZIP proposes an encoding for V7 Zcash transactions that is intended to -reduce the impact of future changes to the Zcash transaction format on the -Zcash ecosystem. It defines a new typecode-length-value encoding for a sequence -of protocol bundles, and a "value balance" map that describes the effect of -each bundle on the transparent transaction value pool for each asset. The -entries of this map serve the same purpose as the Sapling and Orchard value -balance fields have done in the past. +This ZIP proposes an encoding for V7 Zcash transactions that reduces the +impact of future transaction format changes on wallets and other clients. +Previous format changes required clients to update their parsers even when +they did not use the newly introduced protocol features. + +The format defines typecode-length-value encodings for protocol bundles and +a value pool delta map describing each bundle's effect on the transparent +transaction value pool for each asset. The entries of this map serve the +same purpose as the Sapling and Orchard value balance fields have done in +the past. Effecting data and authorizing data are encoded separately, allowing +authorizing data to be pruned without removing the transaction's effects. + +Clients can parse the common transaction envelope and enumerate public value +flows without understanding every bundle type or variant. Computing the +transaction identifier additionally requires a supplied digest for each +unsupported effecting bundle. This does not eliminate the need to update +wallets for consensus changes that alter how they must construct or interpret +transactions. + +Future additive bundle introductions can avoid making wallets' support for +unused features distinguishable on-chain, reducing the need for further +transaction-format changes and their associated privacy leakage. Motivation @@ -151,10 +166,6 @@ Requirements transactions in that version group. -Non-requirements -================ - - Specification ============= @@ -220,9 +231,11 @@ The separation of effecting data from authorizing data serves several purposes: authorizing data appears at the end of the encoded transaction, pruning is simply truncation. -3. **Partial validation**: A wallet that does not understand a particular - bundle type can still compute the transaction identifier by hashing the - effecting data opaquely, without needing to parse its internal structure. +3. **Partial processing**: A wallet can parse a transaction's envelope without + understanding every bundle type or variant. To compute the transaction + identifier, it needs the corresponding ``bundle_effects_digest`` for each + unsupported effecting bundle, as described in `Implications for Wallets`_; + hashing the opaque payload does not in general produce that digest. .. raw:: html @@ -288,6 +301,11 @@ A bundle type MUST NOT permit entries in ``mAuthBundles`` unless it also permits entries in ``mEffectBundles``. That is, authorizing data cannot exist without corresponding effecting data for a given bundle type. +If a bundle's encoding defines a per-element sequence in its authorizing data +as corresponding to a per-element sequence in its effecting data, it MUST +specify that the two sequences have the same length and that elements at the +same index correspond. + Once a ``(bundleType, bundleVariant)`` pair is assigned for a given transaction version, its semantics are fixed for the lifetime of that transaction version. A subsequent network upgrade may define a new transaction version that @@ -353,11 +371,12 @@ Potential Future Bundle Types <details> <summary>Click to show/hide</summary> -The following bundle kinds have no allocated ``(bundleType, bundleVariant)`` -pair. Where a bundle type is given, the kind is a new variant of that existing -type and only its variant identifier is unassigned. Those proposed by a ZIP -name it; the rest are provided to illustrate how potential future upgrades -might affect the bundle registry: +This subsection is non-normative. The following bundle kinds illustrate +possible future extensions; they do not register or activate any +``(bundleType, bundleVariant)`` pair. Where a bundle type is given, the kind +is a new variant of that existing type and only its variant identifier is +unassigned. Those proposed by a ZIP name it; the rest illustrate how potential +future upgrades might affect the bundle registry: +------------+-----------------+----------------------+--------------------+------------------+--------------+-------------------------------------------------------------+ | BundleType | BundleVariant | ``mValuePoolDeltas`` | ``mEffectBundles`` | ``mAuthBundles`` | Defining ZIP | Bundle kind | @@ -550,27 +569,12 @@ wallet does not itself implement. * For each ``bundleType`` that appears in ``mAuthBundles``, a corresponding entry with the same ``bundleVariant`` MUST exist in ``mEffectBundles``. -* Within the encoding of any bundle's effecting and authorizing data, every - per-element sequence in the authorizing data that is described as - corresponding to a per-element sequence in the effecting data MUST have - exactly the same length as that effecting-data sequence, and the element at - each index in the authorizing-data sequence corresponds to the element at - the same index in the effecting-data sequence. For the bundle types - defined by this ZIP this requires: - - * ``vSpendProofsSapling`` and ``vSpendAuthSigsSapling`` each have - ``nSpendsSapling`` elements; - * ``vOutputProofsSapling`` has ``nOutputsSapling`` elements; - * in each Orchard protocol bundle, ``vSpendAuthSigsOrchard`` has - ``nActionsOrchard`` elements, and ``proofsOrchard`` aggregates exactly - ``nActionsOrchard`` per-action proofs. - A wallet that successfully parses a V7 transaction under these rules is -guaranteed to be able to compute the transaction identifier (given, for -each bundle type it does not understand, the corresponding 32-byte -``bundle_effects_digest`` value as described in `Implications for Wallets`_), -and to enumerate the transparent value flows of the transaction at the -granularity of bundle types. +guaranteed to be able to compute the transaction identifier (given, for each +``(bundleType, bundleVariant)`` pair in ``mEffectBundles`` it does not +understand, the corresponding 32-byte ``bundle_effects_digest`` value as +described in `Implications for Wallets`_), and to enumerate the transparent +value flows of the transaction at the granularity of bundle types. Consensus Rules @@ -586,12 +590,44 @@ Let ``CoinbaseBundleId`` be the identifier of the coinbase bundle, and $\mathsf{CoinbaseBundleId} = 1$ and $\mathsf{FeeBundleId} = 5$ as defined in the table above. +Shielded balance field substitutions +```````````````````````````````````` + +For V7 transactions, references in existing consensus rules and chain value +pool accounting to ``valueBalanceSapling``, ``valueBalanceOrchard``, and +``valueBalanceIronwood`` MUST use the ZEC map lookups for bundle types 2, 3, +and 4, respectively. These values replace the old encoded fields; they are +not additional contributions. A missing map entry yields zero. The binding +signature checks use the same values, as specified in `Sapling Bundle`_ and +`Orchard Protocol Bundles`_. + +The existing per-pool value ranges, the nonnegative *Orchard-pool* balancing +value restriction, and chain value pool nonnegativity rules continue to +apply. In particular, a V7 transaction contributes the negation of each +pool's ZEC map lookup to that chain value pool's balance, alongside the +contributions from pre-V7 transactions. [#protocol-chainvaluepoolbalances]_ +All balance sums MUST be evaluated without integer overflow. + +Bundle availability +``````````````````` + +For every ``(bundleType, bundleVariant)`` pair appearing in any of +``mValuePoolDeltas``, ``mEffectBundles``, or ``mAuthBundles``, a full validator +MUST verify that the pair is registered for V7 and activated for the consensus +epoch of the block containing the transaction. A full validator MUST reject a +transaction containing an unregistered or unactivated pair. Registration alone +does not activate a bundle type or variant. + +These consensus checks do not prevent a wallet from parsing an unsupported +bundle type or variant opaquely under `Parsing Rules`_. + Bundle-local rules `````````````````` -The following rules constrain the contents of individual bundles. A wallet -or full validator only needs to enforce a given rule in this subsection if -it understands the bundle type that the rule applies to. +The following rules constrain the contents of individual bundles. Full +validators MUST enforce every applicable rule. A wallet only needs to enforce +a given rule in this subsection if it understands the bundle type and variant +that the rule applies to. * A bundle type MUST NOT appear in any map for which the corresponding column of the `V7 Transaction Bundle Type Registry`_ is marked ❌, and MUST NOT @@ -637,9 +673,20 @@ full validators. transaction (expressed as a negative value, since it is removed from the transparent transaction value pool). -* Within the scope of a block, the sum of the fee bundle values MUST equal 0. - That is, the fees collected by the coinbase transaction MUST equal the sum of - fees paid by all other transactions in the block. +* The fees collected by the coinbase transaction MUST equal the sum of the + fees paid by all other transactions in the block, regardless of their + transaction formats. For each non-coinbase transaction, its fee is: + + * for a V7 transaction, the negation of + $\mathsf{mValuePoolDeltas}[(\mathsf{FeeBundleId}, \mathsf{Zec})]$; + * for a pre-V7 transaction, the implicit fee defined in § 3.4 + 'Transactions and Treestates'. [#protocol-transactions]_ + + For a V7 coinbase transaction, its fee bundle value MUST equal this sum. + For a pre-V7 coinbase transaction, this sum is the transaction-fee input + used by its existing coinbase value rules. In a block containing only V7 + transactions, this is equivalent to requiring the sum of fee bundle values + to equal zero. * Exactly one transaction in a block MUST be a coinbase transaction, and it MUST be the first transaction in the block. @@ -671,6 +718,83 @@ full validators. \forall \mathsf{a}. \sum_{\mathsf{d} \in \mathsf{mValuePoolDeltas} | \mathsf{AssetUuid}(\mathsf{d}) = \mathsf{a}} \mathsf{d.value} = 0 + For V7 transactions, this rule replaces the remaining-value treatment of + the transparent transaction value pool in § 3.4 'Transactions and + Treestates', including the implicit transaction fee. [#protocol-transactions]_ + For a V7 coinbase transaction, it also replaces the ``totalInputValue`` and + ``totalOutputValue`` definitions and their comparison in § 7.1.2 + 'Transaction Consensus Rules'. [#protocol-txnconsensus]_ The explicit + coinbase and fee bundle rules above determine the subsidy and fee + contributions instead. These replacements do not change the balance or + implicit-fee rules for pre-V7 transactions. + +Changes to the Protocol Specification +------------------------------------- + +Transaction input and output requirements +````````````````````````````````````````` + +In § 7.1.2 'Transaction Consensus Rules', [#protocol-txnconsensus]_ replace +$\mathsf{effectiveVersion} \geq 6$ with $\mathsf{effectiveVersion} = 6$ in +each of the following rules: + + [NU6.3 onward] If $\mathsf{effectiveVersion} \geq 6$ then this rule MUST hold: + $\mathtt{tx\_in\_count} > 0$ or $\mathtt{nSpendsSapling} > 0$ or + ($\mathtt{nActionsOrchard} > 0$ and $\mathtt{enableSpendsOrchard} = 1$) or + ($\mathtt{nActionsIronwood} > 0$ and $\mathtt{enableSpendsIronwood} = 1$). + + [NU6.3 onward] If $\mathsf{effectiveVersion} \geq 6$ then this rule MUST hold: + $\mathtt{tx\_out\_count} > 0$ or $\mathtt{nOutputsSapling} > 0$ or + ($\mathtt{nActionsOrchard} > 0$ and $\mathtt{enableOutputsOrchard} = 1$) or + ($\mathtt{nActionsIronwood} > 0$ and $\mathtt{enableOutputsIronwood} = 1$). + +Add the following rules for V7 transactions. They apply to variant 0 of the +bundle types listed below; a ZIP introducing another type or variant can +amend these conditions as needed. + +A V7 transaction MUST satisfy at least one of these input-side conditions: + +* Its ``mEffectBundles`` contains the coinbase bundle (type 1). +* Its transparent bundle (type 0) has ``tx_in_count > 0``. +* Its Sapling bundle (type 2) has ``nSpendsSapling > 0``. +* Its ``mEffectBundles`` contains an Orchard or Ironwood bundle (type 3 or 4) + with ``enableSpends = 1``. + +A V7 transaction MUST also satisfy at least one of these output-side +conditions: + +* Its transparent bundle (type 0) has ``tx_out_count > 0``. +* Its Sapling bundle (type 2) has ``nOutputsSapling > 0``. +* Its ``mEffectBundles`` contains an Orchard or Ironwood bundle (type 3 or 4) + with ``enableOutputs = 1``. +* Its ZEC fee delta (type 5) is negative, representing a fee payment. +* Its ZEC NSM delta (type 6) is negative, representing removal of funds from + circulation as specified in ZIP 233. [#zip-0233]_ + +An absent effecting bundle does not satisfy a condition on that bundle's +contents. Orchard and Ironwood bundle presence implies a nonzero action +count, as required in `Orchard Protocol Bundles`_. A missing value pool delta +entry has value zero and does not satisfy either negative-delta condition. + +Rationale for Transaction Input and Output Requirements +''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +.. raw:: html + + <details> + <summary>Click to show/hide</summary> + +These conditions exclude metadata-only transactions while allowing value to +flow to fees or removal from circulation without creating a chain value pool +output. They also allow fee-free transfers within a single shielded pool: +such a transaction can satisfy both sides through its spends and outputs +even when it has no value pool delta entries. A zero net delta does not imply +that no value moves within a pool. + +.. raw:: html + + </details> + Sighash Versioning ------------------- @@ -693,10 +817,13 @@ signers, the ``associatedData`` that each version requires, and the digest that a signature using it commits to. Those definitions are given for the bundle types registered by this ZIP in `Bundle Definitions`_. -Version 0 is by convention the "commit to all effecting data" sighash algorithm. -Other versions can commit to whatever makes sense for desired functionality -within a given transaction version. Consensus rules choose the digest algorithm -for each signer based on ``sighashVersion``. +Version 0 is by convention the "commit to all effecting data" sighash algorithm, +subject to the transparent bundle's legacy ``hash_type`` rules specified below. +Those rules affect only commitments to the transparent bundle; they do not +relax commitments to any other bundle's effecting data or value pool deltas. +Other versions can define different commitments, including partial commitments +across bundles, within a given transaction version. Consensus rules choose the +digest algorithm for each signer based on ``sighashVersion``. Sighash version information is present alongside each signature in the authorizing data of each bundle. @@ -829,6 +956,27 @@ is:: BLAKE2b-256("ZTxIdEffBnd_Hash", []) +Rationale for Per-Bundle Effects Digests +'''''''''''''''''''''''''''''''''''''''' + +.. raw:: html + + <details> + <summary>Click to show/hide</summary> + +Each effecting bundle contributes a fixed-size digest to this hash. A wallet +can therefore use a supplied digest for an unsupported bundle without parsing +its internal structure, while computing the other bundle digests itself. +The ``bundleType`` and ``bundleVariant`` tags remain committed to alongside +each digest, and the header and complete value pool delta map remain separate +commitments in the transaction identifier. This permits bundle-specific hash +trees, including the subtrees used in compact representations, without +requiring every receiving wallet to understand every bundle's hash tree. + +.. raw:: html + + </details> + v0 Signature Digest ``````````````````` @@ -847,22 +995,24 @@ For transactions that have no transparent inputs, the v0 signature digest is identical to the transaction identifier digest. For transactions with transparent inputs, the signature digest replaces -``effects_bundles_digest`` with a ``signature_bundles_digest`` that incorporates -``hash_type``-dependent transparent signing data:: +``value_pool_deltas_digest`` and ``effects_bundles_digest`` with +``value_pool_deltas_sig_digest`` and ``signature_bundles_digest``, respectively. +These incorporate ``hash_type``-dependent commitments to the transparent bundle +while preserving full commitments to all other bundles:: signature_digest ├── header_digest - ├── value_pool_deltas_digest + ├── value_pool_deltas_sig_digest └── signature_bundles_digest signature_digest '''''''''''''''' A BLAKE2b-256 hash of the following values:: - S.1: header_digest (32-byte hash output) - S.2: value_pool_deltas_digest (32-byte hash output) - S.3: signature_bundles_digest (32-byte hash output) + S.1: header_digest (32-byte hash output) + S.2: value_pool_deltas_sig_digest (32-byte hash output) + S.3: signature_bundles_digest (32-byte hash output) The personalization field of this hash is set to:: @@ -872,6 +1022,26 @@ This value has the same personalization as the transaction identifier digest, so that what is being signed in the case that there are no transparent inputs is exactly the transaction id. +S.2: value_pool_deltas_sig_digest +''''''''''''''''''''''''''''''''' + +For a signature over a transparent input with ``SIGHASH_ANYONECANPAY`` set, +this is constructed as specified for ``value_pool_deltas_digest`` (T.2), except +that all entries with ``bundleType = 0`` (the transparent bundle) are omitted, +regardless of ``bundleVariant`` or ``assetClass``. The complete encodings of +the remaining entries are concatenated in their original transaction order, +without a count prefix. No other entry is omitted; in particular, the +transaction fee and all other bundles' value pool deltas remain committed to. + +The personalization remains ``ZTxIdVPDeltaHash``. If no entries remain, the +digest is:: + + BLAKE2b-256("ZTxIdVPDeltaHash", []) + +For every other case, including signatures over shielded bundles and +transactions with no transparent inputs, ``value_pool_deltas_sig_digest`` is +identical to ``value_pool_deltas_digest`` (T.2). + S.3: signature_bundles_digest ''''''''''''''''''''''''''''' @@ -882,6 +1052,33 @@ Otherwise, ``signature_bundles_digest`` is constructed the same as ``effects_bundles_digest``, except that ``transparent_effects_digest`` is replaced with ``transparent_sig_digest``. +Rationale for v0 Transparent Commitments +'''''''''''''''''''''''''''''''''''''''' + +.. raw:: html + + <details> + <summary>Click to show/hide</summary> + +The legacy ``hash_type`` rules select which transparent inputs and outputs a +signature commits to. They do not relax commitments to other bundles. All +transparent bundle value pool delta entries are also excluded when +``SIGHASH_ANYONECANPAY`` is set, so that they do not independently commit to +the aggregate value of transparent inputs and outputs for any asset. +Omitting whole entries accommodates the canonical absence of zero-valued +entries. + +The transaction fee remains committed to for all v0 signatures, as specified +in ZIP 2002 [#zip-2002]_. Together with the other bundles' fixed value pool +deltas and the per-asset balance rule, this constrains the net transparent +value in any valid completion. Thus ``SIGHASH_NONE`` and ``SIGHASH_SINGLE`` +can permit changes to unsigned transparent outputs, but those changes remain +subject to the fixed fee and other bundles' value pool deltas. + +.. raw:: html + + </details> + Authorizing Data Commitment ``````````````````````````` @@ -907,9 +1104,6 @@ The personalization field of this hash is set to:: "ZTxAuthHash_" || CONSENSUS_BRANCH_ID -For transaction versions before V7, a placeholder value consisting of 32 bytes -of ``0xFF`` is used in place of the authorizing data commitment. - A.1: auth_bundles_digest '''''''''''''''''''''''' @@ -973,11 +1167,29 @@ encounters a bundle with a recognized ``bundleType`` but unrecognized ``bundleVariant`` SHOULD alert the user that the transaction affects a pool the wallet is aware of, but in a way the wallet does not fully understand. -For bundle types not understood by a wallet, the wallet can compute the -transaction identifier so long as it has been provided with the 32-byte -``bundle_effects_digest`` value for each bundle that it does not understand. -This enables partial verification of transactions containing unknown bundle -types. +For each unsupported ``(bundleType, bundleVariant)`` pair in +``mEffectBundles``, a wallet needs the corresponding 32-byte +``bundle_effects_digest`` value in order to compute the transaction identifier. +This includes an unsupported variant of a recognized bundle type. For each +such bundle, the wallet uses the supplied digest as T.3c, together with the +``bundleType`` and ``bundleVariant`` encoded in that transaction's +``mEffectBundles`` entry, in `T.3: effects_bundles_digest`_. It computes the +digests of supported bundles normally and includes all bundles in transaction +order. The header and complete value pool delta map are hashed as specified +in T.1 and T.2. Thus access to the unsupported bundles' digests enables the +wallet to compute the transaction identifier without interpreting those +bundles' internal payloads. How those digests are made available to the +wallet is outside the scope of this ZIP. + +The supplied digests act as commitments to subtrees that the wallet does not +need to compute. If the resulting transaction identifier matches a trusted +transaction identifier, this authenticates the effecting data the wallet +understands, the header, and the value pool delta map. Without a trusted +transaction identifier, computing the correct identifier instead depends on +the supplied bundle digests being correct. + +Recognizing a bundle type identifies the affected pool, but does not imply +that the wallet can detect or spend notes created by an unsupported variant. A wallet MUST NOT construct or sign a transaction containing a bundle type or variant that it does not fully understand. @@ -991,14 +1203,44 @@ defines the bundle types that this ZIP registers: the encoding of their effecting and authorizing data, the sighash algorithm versions available to their signers, and their contributions to the digests defined in `Digest Algorithms`_. A ZIP that registers a further bundle type defines the -same things for it, as required by `Bundle Type Registration`_. +same things for it, as required by `Bundle Type Registration`_. In particular, +each bundle type and variant defines when its entries are present or omitted; +the canonical omission rules below apply to the bundle kinds that specify them. + +For the bundle types defined by this ZIP, the corresponding authorizing +sequences take their lengths from the effecting data: + +* ``tx_in_auth`` has ``tx_in_count`` elements; +* ``vSpendProofsSapling`` and ``vSpendAuthSigsSapling`` each have + ``nSpendsSapling`` elements; +* ``vOutputProofsSapling`` has ``nOutputsSapling`` elements; +* in each Orchard protocol bundle, ``vSpendAuthSigsOrchard`` has + ``nActionsOrchard`` elements. + +Decoding a recognized ``vBundleData`` payload MUST consume exactly +``nBundleDataLen`` bytes; missing fields, truncated fields, or trailing bytes +MUST cause rejection. Unsupported payloads are treated as opaque byte arrays +of their declared lengths. Transparent Bundle `````````````````` The transparent bundle's value pool delta in ``mValuePoolDeltas`` represents the net value flowing from the transparent inputs to the transparent outputs. +An entry for this bundle in ``mEffectBundles`` MUST contain at least one +transparent input or output. If both ``tx_in_count`` and ``tx_out_count`` +would be zero, the effecting bundle MUST be omitted instead. An entry in +``mAuthBundles`` MUST NOT be present when ``tx_in_count = 0``; the empty +authorizing bundle is omitted. + +For ``bundleVariant = 0``, all value pool delta entries for this bundle MUST +have ``assetClass = 0`` (ZEC). If there is no transparent effecting bundle, +its ZEC value pool delta MUST be zero. If ``tx_in_count > 0``, a corresponding +entry in ``mAuthBundles`` MUST be present, and the scripts MUST authorize each +input under the existing transparent script validation rules, using the +signature digest specified in `Transparent Sighash Algorithms`_. + A full validator MUST verify that the ZEC value pool delta for ``bundleType = 0`` equals the total value of the transparent inputs minus the total value of the transparent outputs. (The input values are not encoded in @@ -1100,8 +1342,7 @@ Transparent Sighash Algorithms For the transparent bundle at ``bundleVariant = 0``, sighash version 0 is the only version defined, and its ``associatedData`` is the empty byte string. A -signature made with it commits to the digest defined in -`S.3.0: transparent_sig_digest`_. +signature made with it commits to the digest defined in `v0 Signature Digest`_. Transparent Digests ''''''''''''''''''' @@ -1120,10 +1361,8 @@ The personalization field of this hash is set to:: "ZTxIdTranspaHash" -In the case that the transaction has no transparent components, -``transparent_effects_digest`` is:: - - BLAKE2b-256("ZTxIdTranspaHash", []) +If there are no transparent inputs or outputs, there is no transparent +effecting bundle and no entry for it in ``effects_bundles_digest``. T.3.0a: prevouts_digest ~~~~~~~~~~~~~~~~~~~~~~~ @@ -1247,7 +1486,15 @@ If the ``SIGHASH_ANYONECANPAY`` flag is set:: S.3.0e: sequence_sig_digest ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Identical to ``sequence_digest`` (T.3.0b) regardless of ``hash_type``. +If the ``SIGHASH_ANYONECANPAY`` flag is not set, identical to +``sequence_digest`` (T.3.0b). + +Otherwise:: + + BLAKE2b-256("ZTxIdSequencHash", []) + +The signing input's own ``nSequence`` is committed to by ``txin_sig_digest`` +(S.3.0g), regardless of ``hash_type``. S.3.0f: outputs_sig_digest ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1256,7 +1503,11 @@ If the sighash type is neither ``SIGHASH_SINGLE`` nor ``SIGHASH_NONE``, identica to ``outputs_digest`` (T.3.0c). If the sighash type is ``SIGHASH_SINGLE`` and a transparent output exists at the -same index as the input being signed, a hash of that output's encoding. +same index as the input being signed, a BLAKE2b-256 hash of that output's encoding. + +The personalization field of this hash is set to:: + + "ZTxIdOutputsHash" Otherwise:: @@ -1297,15 +1548,14 @@ The personalization field of this hash is set to:: "ZTxAuthTransHash" -In the case that the transaction has no transparent inputs:: - - BLAKE2b-256("ZTxAuthTransHash", []) +If there are no transparent inputs, there is no transparent authorizing +bundle and no entry for it in ``auth_bundles_digest``. Coinbase Bundle ``````````````` -A transaction is a *coinbase transaction* if and only if ``mEffectBundles`` +A V7 transaction is a *coinbase transaction* if and only if ``mEffectBundles`` contains an entry with ``bundleType = 1``. The coinbase bundle replaces the otherwise-unspendable transparent input that identified a coinbase transaction in previous transaction versions, and carries the block height that that input @@ -1373,6 +1623,23 @@ no coinbase bundle contributes no entry for it to ``effects_bundles_digest``. Sapling Bundle `````````````` +An entry for this bundle in ``mEffectBundles`` MUST contain at least one +Sapling Spend or Output description. If both ``nSpendsSapling`` and +``nOutputsSapling`` would be zero, the bundle MUST be omitted instead. + +For ``bundleVariant = 0``, all value pool delta entries for this bundle MUST +have ``assetClass = 0`` (ZEC). The Sapling balancing value is +$\mathsf{mValuePoolDeltas}[(2, \mathsf{Zec})]$, with the sign convention of +the 'Balance and Binding Signature (Sapling)' section. [#protocol-saplingbalance]_ +If there is no Sapling effecting bundle, this value MUST be zero. + +Every Sapling effecting bundle MUST have a corresponding entry in +``mAuthBundles``. A full validator MUST verify the Spend and Output proofs, +Spend authorizing signatures, and binding signature under the existing +Sapling consensus rules. In particular, the binding validating key MUST be +computed using the balancing value above, and the signature messages are +those specified in `Sapling Sighash Algorithms`_. + Sapling Effecting Data '''''''''''''''''''''' @@ -1505,15 +1772,8 @@ The personalization field of this hash is set to:: "ZTxIdSaplingH_v7" -Note that unlike ZIP 244, neither the value balance nor the anchor is included -here. The value balance is committed via ``value_pool_deltas_digest``, and the -anchor via ``sapling_auth_digest``; the personalization differs from ZIP 244's -``ZTxIdSaplingHash`` because what is directly hashed has changed. - -In the case that the transaction has no Sapling spends or outputs, -``sapling_effects_digest`` is:: - - BLAKE2b-256("ZTxIdSaplingH_v7", []) +If there are no Sapling spends or outputs, there is no Sapling effecting +bundle and no entry for it in ``effects_bundles_digest``. T.3.2a: sapling_spends_digest ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1550,15 +1810,12 @@ A BLAKE2b-256 hash of the non-nullifier information for all Sapling spends belonging to the transaction. For each spend, the following elements are included in the hash:: - T.3.2a.ii.1: cv (32 bytes) - T.3.2a.ii.2: anchor (32 bytes) - T.3.2a.ii.3: rk (32 bytes) - -The anchor is hashed for *each* spend (even though it is shared in the encoding). + T.3.2a.ii.1: cv (32 bytes) + T.3.2a.ii.2: rk (32 bytes) The personalization field of this hash is set to:: - "ZTxIdSSpendNHash" + "ZTxIdSSpendNH_v6" T.3.2b: sapling_outputs_digest ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1639,12 +1896,8 @@ The personalization field of this hash is set to:: "ZTxAuthSapliH_v7" -The personalization differs from ZIP 244's ``ZTxAuthSapliHash`` because this -digest now also commits to the anchor. - -In the case that the transaction has no Sapling spends or outputs:: - - BLAKE2b-256("ZTxAuthSapliH_v7", []) +If there are no Sapling spends or outputs, there is no Sapling authorizing +bundle and no entry for it in ``auth_bundles_digest``. Orchard Protocol Bundles @@ -1656,6 +1909,24 @@ upon by its own bundle type: the Orchard bundle, ``bundleType = 3``, acts on the *Orchard pool*, and the Ironwood bundle, ``bundleType = 4``, acts on the *Ironwood pool*. +An entry for either bundle type in ``mEffectBundles`` MUST contain at least +one Action description (``nActionsOrchard > 0``). If there would be no Actions, +the bundle MUST be omitted instead. + +For ``bundleVariant = 0``, all value pool delta entries for either bundle type +MUST have ``assetClass = 0`` (ZEC). For a bundle with type identifier +$\mathsf{b}$, its pool's balancing value is +$\mathsf{mValuePoolDeltas}[(\mathsf{b}, \mathsf{Zec})]$, with the sign convention +of the 'Balance and Binding Signature (Orchard)' section. [#protocol-orchardbalance]_ +If there is no effecting bundle for a pool, its balancing value MUST be zero. + +Every Orchard or Ironwood effecting bundle MUST have a corresponding entry in +``mAuthBundles``. A full validator MUST verify the Action proof, Spend +authorizing signatures, and binding signature under the existing consensus +rules for that pool. In particular, the binding validating key MUST be +computed using that pool's balancing value above, and the signature messages +are those specified in `Orchard Protocol Sighash Algorithms`_. + Both bundle types use the encoding defined in this section. Where a field is described below as belonging to the bundle's pool, that pool is the *Orchard pool* for an Orchard bundle and the *Ironwood pool* for an Ironwood @@ -1799,15 +2070,8 @@ The personalization field of this hash is set to:: "ZTxIdOrchardH_v7" -Note that unlike ZIP 244, neither the value balance nor the anchor is included -here. The value balance is committed via ``value_pool_deltas_digest``, and the -anchor via ``orchard_auth_digest``; the personalization differs from ZIP 244's -``ZTxIdOrchardHash`` because what is directly hashed has changed. - -In the case that the transaction has no Orchard actions, ``orchard_effects_digest`` -is:: - - BLAKE2b-256("ZTxIdOrchardH_v7", []) +If there are no Orchard actions, there is no Orchard effecting bundle and +no entry for it in ``effects_bundles_digest``. T.3.3a: orchard_actions_compact_digest ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1864,20 +2128,15 @@ each personalization string is replaced as follows: +=====================================+======================+======================+ | effects digest |``ZTxIdOrchardH_v7`` |``ZTxIdIronwd_Hash`` | +-------------------------------------+----------------------+----------------------+ -| actions compact digest |``ZTxIdOrcActCHash`` |``ZTxIdIrnActCHash`` | +| actions compact digest |``ZTxIdOrcActCHash`` |``ZTxIdIrnActCH_v6`` | +-------------------------------------+----------------------+----------------------+ -| actions memos digest |``ZTxIdOrcActMHash`` |``ZTxIdIrnActMHash`` | +| actions memos digest |``ZTxIdOrcActMHash`` |``ZTxIdIrnActMH_v6`` | +-------------------------------------+----------------------+----------------------+ -| actions noncompact digest |``ZTxIdOrcActNHash`` |``ZTxIdIrnActNHash`` | +| actions noncompact digest |``ZTxIdOrcActNHash`` |``ZTxIdIrnActNH_v6`` | +-------------------------------------+----------------------+----------------------+ -The personalization strings differ so that the digest of a bundle acting on one -pool cannot be reused as the digest of a bundle acting on the other. - -In the case that the transaction has no Ironwood actions, -``ironwood_effects_digest`` is:: - - BLAKE2b-256("ZTxIdIronwd_Hash", []) +If there are no Ironwood actions, there is no Ironwood effecting bundle and +no entry for it in ``effects_bundles_digest``. A.1.3: orchard_auth_digest .......................... @@ -1897,12 +2156,8 @@ The personalization field of this hash is set to:: "ZTxAuthOrchaH_v7" -The personalization differs from ZIP 244's ``ZTxAuthOrchaHash`` because this -digest now also commits to the anchor. - -In the case that the transaction has no Orchard actions:: - - BLAKE2b-256("ZTxAuthOrchaH_v7", []) +If there are no Orchard actions, there is no Orchard authorizing bundle and +no entry for it in ``auth_bundles_digest``. A.1.4: ironwood_auth_digest ........................... @@ -1914,9 +2169,8 @@ that the personalization field of the hash is set to:: "ZTxAuthIrnwdHash" -In the case that the transaction has no Ironwood actions:: - - BLAKE2b-256("ZTxAuthIrnwdHash", []) +If there are no Ironwood actions, there is no Ironwood authorizing bundle and +no entry for it in ``auth_bundles_digest``. Rationale @@ -1958,12 +2212,20 @@ separate types also keep the two value pool deltas separable, which a client needs in order to report the two chain value pool balances independently. The Sapling and Orchard protocol anchors are authorizing data rather than -effecting data, following ZIP 229 [#zip-0229]_. An anchor selects the note -commitment tree state that the bundle's proofs are verified against, which is a -property of how the spends are authorized rather than of what the transaction -does. Placing it there lets a bundle be re-anchored to a more recent root -without changing the transaction identifier, while the proofs still bind to the -anchor actually used. +effecting data. An anchor selects the note commitment tree state that the +bundle's proofs are verified against, which is a property of how the spends +are authorized rather than of what the transaction does. Placing it there +lets a bundle be re-anchored to a more recent root without changing the +transaction identifier, while the proofs still bind to the anchor actually +used. + +Bundle digests retain the input formats and personalizations of ZIP 229 +[#zip-0229]_ wherever the committed data is unchanged. Effects roots have +different personalizations because value balances are committed separately +in the value pool delta map. Authorizing digests have different +personalizations because signatures include ``sighashInfo`` and anchors +precede the proofs and signatures. Orchard and Ironwood use distinct +personalizations to separate commitments for their respective pools. The coinbase bundle also gives the coinbase metadata a place of its own. In previous transaction versions that metadata was encoded as the ``scriptSig`` of @@ -1992,9 +2254,6 @@ Reference implementation ======================== -Open issues -=========== - Notes from design sessions ========================== @@ -2178,35 +2437,6 @@ Questions * When sending, you need to understand all bundles you are including, and then you can calculate the fee. -* Can wallets still compute the txid and wtxid of an arbitrary transaction? - - * Yes, provided that effecting and authorizing data is separated. Then they - can hash the effecting data even without understanding it to compute the - txid, and they can hash the authorizing data even without understanding - it to compute the authorizing data commitment part of the wtxid (ZIP - 239 [#zip-0239]_). - * *However*, this reintroduces a more direct linkage between the [w]txid - computation and the transaction encoding. It's arguably fine, and - potentially simpler -- since the [w]txid computation need not change at - all for most protocol changes. - * If the hashing uses flat hashes over the effectingData and - authorizingData of each bundle (which it has to because the internal - structure is not known), then it might be more difficult to do Merkle - proofs over subsets of the data within a bundle. We haven't used that so - far; is it really needed? - - * Should the authorizing data be entirely separate from the effecting data, - and encoded at the end of the transaction in a batch, so that pruning is - simply truncation? - -* The light wallet protocol will be updated to allow the client to specify the - set of bundle types that the client understands. In the case that this - information is provided, the light client server will then send the root - hashes for each bundle type that the client **does not** understand when - returning raw transaction data, so that the light client can correctly - recompute and validate the txid; also, the compact transactions can be pruned - to exclude bundles of bundle types. that the client will not understand. - TODO ==== @@ -2219,16 +2449,23 @@ References .. [#BCP14] `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 <https://www.rfc-editor.org/info/bcp14>`_ .. [#protocol] `Zcash Protocol Specification, Version 2025.6.3 [NU6.1] or later <protocol/protocol.pdf>`_ .. [#protocol-blockchain] `Zcash Protocol Specification, Version 2025.6.3 [NU6.1]. Section 3.3: The Block Chain <protocol/protocol.pdf#blockchain>`_ +.. [#protocol-transactions] `Zcash Protocol Specification, Version 2025.6.3 [NU6.1]. Section 3.4: Transactions and Treestates <protocol/protocol.pdf#transactions>`_ .. [#protocol-networks] `Zcash Protocol Specification, Version 2025.6.3 [NU6.1]. Section 3.12: Mainnet and Testnet <protocol/protocol.pdf#networks>`_ +.. [#protocol-saplingbalance] `Zcash Protocol Specification, Version 2025.6.3 [NU6.1]. Balance and Binding Signature (Sapling) <protocol/protocol.pdf#saplingbalance>`_ +.. [#protocol-orchardbalance] `Zcash Protocol Specification, Version 2025.6.3 [NU6.1] or later. Balance and Binding Signature (Orchard) <protocol/protocol.pdf#orchardbalance>`_ +.. [#protocol-chainvaluepoolbalances] `Zcash Protocol Specification, Version 2025.6.3 [NU6.1] or later. Chain Value Pool Balances <protocol/protocol.pdf#chainvaluepoolbalances>`_ +.. [#protocol-txnconsensus] `Zcash Protocol Specification, Version 2026.8.0 [NU6.3]. Section 7.1.2: Transaction Consensus Rules <protocol/protocol.pdf#txnconsensus>`_ .. [#protocol-subsidies] `Zcash Protocol Specification, Version 2025.6.3 [NU6.1]. Section 7.8: Block Subsidy and Founders' Reward <protocol/protocol.pdf#subsidies>`_ .. [#protocol-fundingstreams] `Zcash Protocol Specification, Version 2025.6.3 [NU6.1]. Section 7.10: Payment of Funding Streams, Deferred Lockbox, and Lockbox Disbursement <protocol/protocol.pdf#fundingstreams>`_ -.. [#zip-0203] `ZIP 203: Transaction Expiry <https://zips.z.cash/zip-0203>`_ -.. [#zip-0212] `ZIP 212: Allow Recipient to Derive Ephemeral Secret from Note Plaintext <https://zips.z.cash/zip-0212>`_ -.. [#zip-0225] `ZIP 225: Version 5 Transaction Format <https://zips.z.cash/zip-0225>`_ +.. [#zip-0203] `ZIP 203: Transaction Expiry <zip-0203.rst>`_ +.. [#zip-0212] `ZIP 212: Allow Recipient to Derive Ephemeral Secret from Note Plaintext <zip-0212.rst>`_ +.. [#zip-0225] `ZIP 225: Version 5 Transaction Format <zip-0225.rst>`_ .. [#zip-0229] `ZIP 229: Version 6 Transaction Format <zip-0229.md>`_ -.. [#zip-0239] `ZIP 239: Relay of Version 5 Transactions <https://zips.z.cash/zip-0239>`_ -.. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability <https://zips.z.cash/zip-0244>`_ -.. [#zip-0307] `ZIP 307: Light Client Protocol for Payment Detection <https://zips.z.cash/zip-0307>`_ +.. [#zip-0233] `ZIP 233: Network Sustainability Mechanism: Removing Funds From Circulation <zip-0233.md>`_ +.. [#zip-0239] `ZIP 239: Relay of Version 5 Transactions <zip-0239.rst>`_ +.. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability <zip-0244.rst>`_ +.. [#zip-0307] `ZIP 307: Light Client Protocol for Payment Detection <zip-0307.rst>`_ .. [#zip-2001] `ZIP 2001: Lockbox Funding Streams <zip-2001.rst>`_ +.. [#zip-2002] `ZIP 2002: Explicit Fees <zip-2002.rst>`_ .. [#zip-2006] `ZIP 2006: Restricting Transfers into the Orchard Pool <zip-2006.md>`_
zips/zip-2002.rst +36 −5
@@ -127,11 +127,42 @@ In § 7.1 'Transaction Encoding and Consensus' [#protocol-txnconsensus]_, add: Modifications to Digest Algorithms ---------------------------------- -The fee amount is committed to the transaction identifier and signature -digest via the ``value_pool_deltas_digest`` defined in ZIP 248 [#zip-0248]_. -Since the fee bundle (bundle type 5) has no effecting data and no authorizing -data, its only contribution to the transaction digest is through its entry -in ``mValuePoolDeltas``. +The fee amount is committed to the transaction identifier via +``value_pool_deltas_digest`` and to the v0 signature digest via +``value_pool_deltas_sig_digest``, as defined in ZIP 248 [#zip-0248]_. The fee +bundle's entry in ``mValuePoolDeltas``, if present, MUST be included in the +latter digest regardless of the transparent signature's ``hash_type``. The +absence of this entry commits to a zero fee. Since the fee bundle (bundle +type 5) has no effecting data and no authorizing data, its only contribution +to these digests is through its entry in ``mValuePoolDeltas``. + +The ``SIGHASH_ANYONECANPAY`` flag therefore permits other transparent inputs +to change, subject to the transaction's balance rules, but does not permit +the fee to change. In particular, ``SIGHASH_ALL | SIGHASH_ANYONECANPAY`` +commits to all transparent outputs and to the explicit fee; adding input +value cannot increase the fee without invalidating the signature. +``SIGHASH_NONE`` and ``SIGHASH_SINGLE`` also retain the fee commitment; any +changes to unsigned transparent outputs remain subject to the fixed fee +and all other bundles' value pool deltas. + +Rationale for the Explicit Fee Commitment +````````````````````````````````````````` + +.. raw:: html + + <details> + <summary>Click to show/hide</summary> + +Before V7, the fee was implicit: additional transparent input value not +allocated to an output increased the fee. The explicit fee is instead an +output of the transaction that every v0 signature commits to. Transparent +``hash_type`` rules affect only the transparent bundle, not the separate fee +bundle. Thus ``SIGHASH_ANYONECANPAY`` allows changes to funding inputs, but +not overpayment by increasing the agreed fee. + +.. raw:: html + + </details> Applicability