PR #1446proposed changes toZIP 207·ZIP 218·ZIP 234·ZIP 235·ZIP 237·ZIP 259·ZIP 2008

Protocol spec: Apply the NU7 ZIPs

[Revision 0: Canopy, Revision 1: NU6] Final, [Revision 2: NU7] Proposedby daira · updated 2026-11-06zips/zip-0207.rst @ d0e2420ffd · 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.

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 terms "block subsidy" and "halving" in this document are to be interpreted as described in sections 3.10 and 7.8 of the Zcash Protocol Specification. [2] [10]

The terms "consensus branch" and "network upgrade" in this document are to be interpreted as described in ZIP 200. [14]

The terms below are to be interpreted as follows:

Canopy

Code-name for the fifth Zcash network upgrade, also known as Network Upgrade 4.

Testnet

The Zcash test network, as defined in the Zcash Protocol Specification. [3]

Mainnet

The Zcash production network, as defined in the Zcash Protocol Specification. [3]

Abstract

This proposal specifies a mechanism to support funding streams, distributed from a portion of the block subsidy for a specified range of block heights.

This is intended as a means of implementing the Zcash Development Fund, using the funding stream definitions specified in ZIP 214 [19]. It should be read in conjunction with ZIP 1014 [25], which describes the high-level requirements for that fund.

Revision 2 preserves the approximate duration and value of each address period when NU7 reduces the target block spacing to 25 seconds.

Motivation

Motivation for the Zcash Development Fund is considered in ZIP 1014 [25].

This ZIP 207 was originally proposed for the Blossom network upgrade, as a means of splitting the original Founders’ Reward into several streams. It was then withdrawn when such splitting was judged to be unnecessary at the consensus level. Since the capabilities of the funding stream mechanism match the requirements for the Zcash Development Fund, the ZIP was reintroduced for that purpose in the Canopy upgrade in order to reuse specification, analysis, and implementation effort.

As of NU6, ZIP 1015 [26] directs part of the block subsidy to a reserve, the distribution of which is to be determined via a future ZIP. ZIP 2001 [27] modified this ZIP to augment the funding stream mechanism with a common mechanism to implement this proposal. ZIP 271 [24] specifies a one-time disbursement from this reserve at NU6.1 activation, which is deducted from the Deferred Development Fund Chain Value Pool Balance.

Requirements

The primary requirement of this ZIP is to provide a mechanism for specifying the funding streams that are used in ZIP 214 [19] to implement the Zcash Development Fund. It should be sufficiently expressive to handle both the main three "slices" (BP, ZF, and MG) defined in ZIP 1014 [25], and also (with additional funding stream definitions) the "direct grant option" described in that ZIP.

As for the original Founders’ Reward, a mechanism is provided to allow addresses for a given funding stream to be changed on a roughly-monthly basis, so that keys that are not yet needed may be kept off-line as a security measure.

Specification

Revisions

  • Revision 0: The initial version of this specification, as agreed upon by the Zcash community in ZIP 1014 [25].

  • Revision 2: Extends the remaining address period at NU7 activation and subsequent address periods in proportion to the change in target block spacing specified in ZIP 218 [20], and permits transparent P2PKH addresses per ZIP 2008 [28].

Definitions

We use the following constants and functions defined in [5], [9], and [10]:

  • 𝖡 𝗅 𝗈 𝗌 𝗌 𝗈 𝗆 𝖠 𝖼 𝗍 𝗂 𝗏 𝖺 𝗍 𝗂 𝗈 𝗇 𝖧 𝖾 𝗂 𝗀 𝗁 𝗍

  • 𝖯 𝗈 𝗌 𝗍 𝖡 𝗅 𝗈 𝗌 𝗌 𝗈 𝗆 𝖧 𝖺 𝗅 𝗏 𝗂 𝗇 𝗀 𝖨 𝗇 𝗍 𝖾 𝗋 𝗏 𝖺 𝗅

  • 𝖧 𝖺 𝗅 𝗏 𝗂 𝗇 𝗀 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 )

  • 𝖡 𝗅 𝗈 𝖼 𝗄 𝖲 𝗎 𝖻 𝗌 𝗂 𝖽 𝗒 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 )

We also define the following function:

  • 𝖧 𝖾 𝗂 𝗀 𝗁 𝗍 𝖥 𝗈 𝗋 𝖧 𝖺 𝗅 𝗏 𝗂 𝗇 𝗀 ( 𝗁 𝖺 𝗅 𝗏 𝗂 𝗇 𝗀 ) : Smallest 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 such that 𝖧 𝖺 𝗅 𝗏 𝗂 𝗇 𝗀 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 ) = 𝗁 𝖺 𝗅 𝗏 𝗂 𝗇 𝗀

Funding streams

A funding stream is defined by a block subsidy fraction (represented as a numerator and a denominator), a start height (inclusive), an end height (exclusive), and a sequence of recipients as defined below.

By defining the issuance as a proportion of the total block subsidy, rather than absolute zatoshis, this ZIP dovetails with any changes to both block target spacing and issuance-per-block rates. Such a change occurred at the Blossom network upgrade, for example. [15]

The value of a funding stream at a given block height is defined as:

𝖥 𝗎 𝗇 𝖽 𝗂 𝗇 𝗀 𝖲 𝗍 𝗋 𝖾 𝖺 𝗆 [ 𝖥 𝖴 𝖭 𝖣 ] . 𝖵 𝖺 𝗅 𝗎 𝖾 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 ) = 𝖿 𝗅 𝗈 𝗈 𝗋 ( 𝖡 𝗅 𝗈 𝖼 𝗄 𝖲 𝗎 𝖻 𝗌 𝗂 𝖽 𝗒 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 ) ⋅ 𝖥 𝗎 𝗇 𝖽 𝗂 𝗇 𝗀 𝖲 𝗍 𝗋 𝖾 𝖺 𝗆 [ 𝖥 𝖴 𝖭 𝖣 ] . 𝖵 𝖺 𝗅 𝗎 𝖾 𝖭 𝗎 𝗆 𝖾 𝗋 𝖺 𝗍 𝗈 𝗋 𝖥 𝗎 𝗇 𝖽 𝗂 𝗇 𝗀 𝖲 𝗍 𝗋 𝖾 𝖺 𝗆 [ 𝖥 𝖴 𝖭 𝖣 ] . 𝖵 𝖺 𝗅 𝗎 𝖾 𝖣 𝖾 𝗇 𝗈 𝗆 𝗂 𝗇 𝖺 𝗍 𝗈 𝗋 )

An active funding stream at a given block height is defined as a funding stream for which the block height is less than its end height, but not less than its start height.

The value of each funding stream is paid to one of a pre-defined set of recipients, depending on the block height.

As of Revision 0, each recipient MUST be the string encoding of a transparent P2SH address or Sapling address (as specified in [6] or [7]).

As of Revision 1, each recipient identifier MUST be either the string encoding of a transparent P2SH address or Sapling address (as specified in [6] or [7]) or the identifier 𝖣 𝖤 𝖥 𝖤 𝖱 𝖱 𝖤 𝖣 _ 𝖯 𝖮 𝖮 𝖫 . The latter, added in the NU6 network upgrade [22], indicates that the value is to be paid to a reserve to be used for development funding, the distribution of which is to be determined via a future ZIP.

As of Revision 2, each recipient identifier MUST be either the string encoding of a transparent P2PKH or P2SH address or of a Sapling address (as specified in [6] or [7]) or the identifier 𝖣 𝖤 𝖥 𝖤 𝖱 𝖱 𝖤 𝖣 _ 𝖯 𝖮 𝖮 𝖫 .

Each address is used for at most 1/48th of a halving interval, creating a roughly-monthly sequence of funding periods. The address to be used for a given block height is defined as follows:

\begin{array}{rcl}
    \mathsf{AddressChangeInterval} &=& \mathsf{PostBlossomHalvingInterval} / 48 \\
    \mathsf{AddressPeriod}(\mathsf{height}) &=&
        \mathsf{floor}\left(
            {\small\frac{\mathsf{height} + \mathsf{PostBlossomHalvingInterval} - \mathsf{HeightForHalving}(1)}{\mathsf{AddressChangeInterval}}}
        \right) \\
    \mathsf{FundingStream[FUND].AddressIndex}(\mathsf{height}) &=&
        \mathsf{AddressPeriod}(\mathsf{height}) - \\&&\hspace{2em} \mathsf{AddressPeriod}(\mathsf{FundingStream[FUND].StartHeight}) \\
    \mathsf{FundingStream[FUND].Address}(\mathsf{height}) &=& \mathsf{FundingStream[FUND].Addresses[} \\&&\hspace{2em} \mathsf{FundingStream[FUND].AddressIndex}(\mathsf{height})\mathsf{]}
\end{array}

This has the property that all active funding streams change the address they are using on the same block height schedule, aligned to the height of the first halving so that 48 funding periods fit cleanly within a halving interval. This can be leveraged to simplify implementations, by batching the necessary outputs for each funding period.

The sequence 𝖥 𝗎 𝗇 𝖽 𝗂 𝗇 𝗀 𝖲 𝗍 𝗋 𝖾 𝖺 𝗆 [ 𝖥 𝖴 𝖭 𝖣 ] . 𝖠 𝖽 𝖽 𝗋 𝖾 𝗌 𝗌 𝖾 𝗌 is indexed from 0, and MUST have 𝖥 𝗎 𝗇 𝖽 𝗂 𝗇 𝗀 𝖲 𝗍 𝗋 𝖾 𝖺 𝗆 [ 𝖥 𝖴 𝖭 𝖣 ] . 𝖠 𝖽 𝖽 𝗋 𝖾 𝗌 𝗌 𝖨 𝗇 𝖽 𝖾 𝗑 ( 𝖥 𝗎 𝗇 𝖽 𝗂 𝗇 𝗀 𝖲 𝗍 𝗋 𝖾 𝖺 𝗆 [ 𝖥 𝖴 𝖭 𝖣 ] . 𝖤 𝗇 𝖽 𝖧 𝖾 𝗂 𝗀 𝗁 𝗍 − 1 ) + 1 entries. (The protocol specification calls the same sequence 𝖿 𝗌 . 𝖱 𝖾 𝖼 𝗂 𝗉 𝗂 𝖾 𝗇 𝗍 𝗌 and indexes it from 1. [12])

For a funding stream 𝖿 𝗌 we write 𝖿 𝗌 . 𝖵 𝖺 𝗅 𝗎 𝖾 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 ) for 𝖥 𝗎 𝗇 𝖽 𝗂 𝗇 𝗀 𝖲 𝗍 𝗋 𝖾 𝖺 𝗆 [ 𝖿 𝗌 ] . 𝖵 𝖺 𝗅 𝗎 𝖾 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 ) and 𝖿 𝗌 . 𝖱 𝖾 𝖼 𝗂 𝗉 𝗂 𝖾 𝗇 𝗍 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 ) for 𝖥 𝗎 𝗇 𝖽 𝗂 𝗇 𝗀 𝖲 𝗍 𝗋 𝖾 𝖺 𝗆 [ 𝖿 𝗌 ] . 𝖠 𝖽 𝖽 𝗋 𝖾 𝗌 𝗌 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 ) at each block height.

As of Revision 2, the definition of 𝖠 𝖽 𝖽 𝗋 𝖾 𝗌 𝗌 𝖯 𝖾 𝗋 𝗂 𝗈 𝖽 above is replaced on each network by the following piecewise definition. Let A be the NU7 activation height on that network, let R = 𝖭 𝖴 𝟩 𝖯 𝗈 𝖶 𝖳 𝖺 𝗋 𝗀 𝖾 𝗍 𝖲 𝗉 𝖺 𝖼 𝗂 𝗇 𝗀 𝖱 𝖺 𝗍 𝗂 𝗈 = 3 and 𝖨 𝗌 𝖭 𝖴 𝟩 𝖠 𝖼 𝗍 𝗂 𝗏 𝖺 𝗍 𝖾 𝖽 be as defined in ZIP 218 [20], let C = 𝖠 𝖽 𝖽 𝗋 𝖾 𝗌 𝗌 𝖢 𝗁 𝖺 𝗇 𝗀 𝖾 𝖨 𝗇 𝗍 𝖾 𝗋 𝗏 𝖺 𝗅 , let I = 𝖯 𝗈 𝗌 𝗍 𝖡 𝗅 𝗈 𝗌 𝗌 𝗈 𝗆 𝖧 𝖺 𝗅 𝗏 𝗂 𝗇 𝗀 𝖨 𝗇 𝗍 𝖾 𝗋 𝗏 𝖺 𝗅 , and let H 1 = 𝖧 𝖾 𝗂 𝗀 𝗁 𝗍 𝖥 𝗈 𝗋 𝖧 𝖺 𝗅 𝗏 𝗂 𝗇 𝗀 ( 1 ) .

\mathsf{AddressPeriod}(\mathsf{height}) =
    \begin{cases}
        \mathsf{floor}\left(
            \dfrac{\mathsf{height} + I - H_1}{C}
        \right), &\textsf{if not } \mathsf{IsNU7Activated}(\mathsf{height}) \\
        \mathsf{floor}\left(
            \dfrac{R(A + I - H_1) + \mathsf{height} - A}{RC}
        \right), &\textsf{otherwise}
    \end{cases}

The 𝖥 𝗎 𝗇 𝖽 𝗂 𝗇 𝗀 𝖲 𝗍 𝗋 𝖾 𝖺 𝗆 [ 𝖥 𝖴 𝖭 𝖣 ] . 𝖠 𝖽 𝖽 𝗋 𝖾 𝗌 𝗌 𝖨 𝗇 𝖽 𝖾 𝗑 and 𝖥 𝗎 𝗇 𝖽 𝗂 𝗇 𝗀 𝖲 𝗍 𝗋 𝖾 𝖺 𝗆 [ 𝖥 𝖴 𝖭 𝖣 ] . 𝖠 𝖽 𝖽 𝗋 𝖾 𝗌 𝗌 calculations above MUST use this definition for funding streams active at or after NU7 activation, including when calculating the period at a stream's start height. This preserves the address index at activation. If NU7 activates partway through an address period, its remaining block count is tripled; each subsequent period lasts 105000 blocks. At the 25-second target spacing, each period therefore retains approximately its previous wall-clock duration and funding amount, subject to per-block rounding.

(The protocol specification [12] expresses this through 𝖯 𝗋 𝖾 𝖭 𝖴 𝟩 𝖤 𝗊 𝗎 𝗂 𝗏 𝖺 𝗅 𝖾 𝗇 𝗍 𝖧 𝖾 𝗂 𝗀 𝗁 𝗍 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 ) , the height that the block at 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 would have if the blocks from NU7 activation onward had been mined at the pre-NU7 target spacing: 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 if not 𝖨 𝗌 𝖭 𝖴 𝟩 𝖠 𝖼 𝗍 𝗂 𝗏 𝖺 𝗍 𝖾 𝖽 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 ) , and A + ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 − A ) / R otherwise. Its 𝖥 𝖲 𝖱 𝖾 𝖼 𝗂 𝗉 𝗂 𝖾 𝗇 𝗍 𝖯 𝖾 𝗋 𝗂 𝗈 𝖽 applies the pre-NU7 formula to this rational number in place of 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 , which is equal to the definition above after dividing the numerator and denominator of the second case by R .)

Below is a visual representation of how stream addresses align with funding periods:

Example height

Stream A

Stream B

Stream C

AddressChangeInterval - 2

A0

AddressChangeInterval - 1

A0

AddressChangeInterval

A1

B0

C0

AddressChangeInterval + 1

A1

B0

C0

...

2*AddressChangeInterval - 2

A1

B0

C0

2*AddressChangeInterval - 1

A1

B0

C0

2*AddressChangeInterval

A2

C1

2*AddressChangeInterval + 1

A2

C1

...

PostBlossomHalvingInterval - 2

A2

C1

PostBlossomHalvingInterval - 1

A2

C1

PostBlossomHalvingInterval

C2

PostBlossomHalvingInterval + 1

C2

...

PostBlossomHalvingInterval + AddressChangeInterval/2

C2

...

PostBlossomHalvingInterval + 2*AddressChangeInterval - 1

C2

PostBlossomHalvingInterval + 2*AddressChangeInterval

C3

...

PostBlossomHalvingInterval + 5*AddressChangeInterval - 1

C3

PostBlossomHalvingInterval + 5*AddressChangeInterval

C4

The last rows illustrate Revision 2 with NU7 activating halfway through the period of address C2, at height PostBlossomHalvingInterval + AddressChangeInterval/2: the remaining half of that period is tripled, and the period of C3 lasts 3*AddressChangeInterval blocks.

On Mainnet, Canopy activated exactly at the point when the Founders’ Reward expired, at block height 1046400. On Testnet, there was a shortened Founders’ Reward address period prior to Canopy activation.

Deferred Development Fund Chain Value Pool Balance

As of Revision 1 of this specification, full node implementations MUST track an additional 𝖢 𝗁 𝖺 𝗂 𝗇 𝖵 𝖺 𝗅 𝗎 𝖾 𝖯 𝗈 𝗈 𝗅 𝖡 𝖺 𝗅 𝖺 𝗇 𝖼 𝖾 𝖣 𝖾 𝖿 𝖾 𝗋 𝗋 𝖾 𝖽 chain value pool balance, in addition to the other chain value pool balances defined in [4] (see also ZIP 209 [16]).

Define $mathsf{totalDeferredOutput}(mathsf{height}) := sum_{mathsf{fs} in mathsf{DeferredFundingStreams}(mathsf{height})} mathsf{fs.Value}(mathsf{height})$ where 𝖣 𝖾 𝖿 𝖾 𝗋 𝗋 𝖾 𝖽 𝖥 𝗎 𝗇 𝖽 𝗂 𝗇 𝗀 𝖲 𝗍 𝗋 𝖾 𝖺 𝗆 𝗌 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 ) is the set of funding streams with recipient identifier 𝖣 𝖤 𝖥 𝖤 𝖱 𝖱 𝖤 𝖣 _ 𝖯 𝖮 𝖮 𝖫 in the block at height 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 .

Define 𝗍 𝗈 𝗍 𝖺 𝗅 𝖣 𝖾 𝖿 𝖾 𝗋 𝗋 𝖾 𝖽 𝖨 𝗇 𝗉 𝗎 𝗍 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 ) as in [10]: it is 𝖹 𝖨 𝖯 𝟤𝟩𝟣 𝖣 𝗂 𝗌 𝖻 𝗎 𝗋 𝗌 𝖾 𝗆 𝖾 𝗇 𝗍 𝖠 𝗆 𝗈 𝗎 𝗇 𝗍 at the height 𝖹 𝖨 𝖯 𝟤𝟩𝟣 𝖠 𝖼 𝗍 𝗂 𝗏 𝖺 𝗍 𝗂 𝗈 𝗇 𝖧 𝖾 𝗂 𝗀 𝗁 𝗍 of the one-time lockbox disbursement specified in ZIP 271 [24], and zero at every other height.

The 𝖢 𝗁 𝖺 𝗂 𝗇 𝖵 𝖺 𝗅 𝗎 𝖾 𝖯 𝗈 𝗈 𝗅 𝖡 𝖺 𝗅 𝖺 𝗇 𝖼 𝖾 𝖣 𝖾 𝖿 𝖾 𝗋 𝗋 𝖾 𝖽 chain value pool balance for a given block chain is the sum of the values of payments to 𝖣 𝖤 𝖥 𝖤 𝖱 𝖱 𝖤 𝖣 _ 𝖯 𝖮 𝖮 𝖫 for transactions in the block chain, minus the lockbox disbursement from it in that block chain.

Equivalently, 𝖢 𝗁 𝖺 𝗂 𝗇 𝖵 𝖺 𝗅 𝗎 𝖾 𝖯 𝗈 𝗈 𝗅 𝖡 𝖺 𝗅 𝖺 𝗇 𝖼 𝖾 𝖣 𝖾 𝖿 𝖾 𝗋 𝗋 𝖾 𝖽 for a block chain up to and including height 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 is given by $sum_{mathsf{h} = 0}^{mathsf{height}} left(mathsf{totalDeferredOutput}(mathsf{h}) - mathsf{totalDeferredInput}(mathsf{h})right)$.

Note: 𝗍 𝗈 𝗍 𝖺 𝗅 𝖣 𝖾 𝖿 𝖾 𝗋 𝗋 𝖾 𝖽 𝖮 𝗎 𝗍 𝗉 𝗎 𝗍 ( 𝗁 ) is necessarily zero for heights 𝗁 prior to NU6 activation, and 𝗍 𝗈 𝗍 𝖺 𝗅 𝖣 𝖾 𝖿 𝖾 𝗋 𝗋 𝖾 𝖽 𝖨 𝗇 𝗉 𝗎 𝗍 ( 𝗁 ) is necessarily zero for heights 𝗁 prior to NU6.1 activation.

Consensus rules

Prior to activation of the Canopy network upgrade, the existing consensus rule for payment of the original Founders’ Reward is enforced. [11]

Once the Canopy network upgrade activates:

  1. The existing consensus rule for payment of the Founders’ Reward [11] is no longer active. (This would be the case under the preexisting consensus rules for Mainnet, but not for Testnet.)

  2. The coinbase transaction in each block MUST contain at least one output per active funding stream that pays the stream's value in the prescribed way to the stream's recipient address for the block's height.

  3. The recipient 𝖿 𝗌 . 𝖱 𝖾 𝖼 𝗂 𝗉 𝗂 𝖾 𝗇 𝗍 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 ) of a funding stream 𝖿 𝗌 at block height 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 is as defined in Funding streams.

  4. The "prescribed way" to pay a transparent P2SH address is to use a standard P2SH script of the form OP_HASH160 RedeemScriptHash OP_EQUAL as the scriptPubKey [29], where RedeemScriptHash is the 20-byte script hash in the raw encoding of the address [6].

    As of Revision 2, the "prescribed way" to pay a transparent P2PKH address is to use OP_DUP OP_HASH160 <keyHash> OP_EQUALVERIFY OP_CHECKSIG as the output's scriptPubKey, where <keyHash> is the direct push of the 20-byte public-key hash decoded from the recipient's Base58Check address. No other script encoding satisfies this funding-stream payment rule.

  5. The "prescribed way" to pay a Sapling address is as defined in [18]. That is, all Sapling outputs in coinbase transactions (including, but not limited to, outputs for funding streams) MUST have valid note commitments when recovered using a 32-byte array of zeroes as the outgoing viewing key. In this case the note plaintext lead byte MUST be 𝟎 𝐱 𝟎𝟐 , as specified in [17].

Once the NU6 network upgrade activates:

  • Rule 2 above is replaced by: In each block with coinbase transaction 𝖼 𝖻 at block height 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 , for each funding stream 𝖿 𝗌 active at that block height with a recipient identifier other than 𝖣 𝖤 𝖥 𝖤 𝖱 𝖱 𝖤 𝖣 _ 𝖯 𝖮 𝖮 𝖫 given by 𝖿 𝗌 . 𝖱 𝖾 𝖼 𝗂 𝗉 𝗂 𝖾 𝗇 𝗍 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 ) , 𝖼 𝖻 MUST contain at least one output that pays 𝖿 𝗌 . 𝖵 𝖺 𝗅 𝗎 𝖾 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 ) zatoshi in the prescribed way to the address represented by that recipient identifier, distinct from the outputs counted for every other such funding stream and for the lockbox disbursement outputs required by ZIP 271 [24].

Note: The outputs required by rule 2 before NU6 activation are likewise distinct for each funding stream. In particular, a single output cannot be counted for two active funding streams that have the same recipient and the same value.

Rule 5 has subsequently been clarified as follows:

  • The "prescribed way" to pay a Sapling or Orchard address is as defined in [18], using the post-Heartwood consensus rules specified for shielded outputs of coinbase transactions in [8]. A Sapling address is paid by a Sapling-pool output. An Orchard address is paid by an Orchard-pool output before NU6.3 activation, and by an Ironwood-pool output from NU6.3 activation onward, since coinbase transactions can then contain no Orchard-pool component [18].

Note: The recipient identifiers permitted above do not include Orchard addresses; the "prescribed way" to pay an Orchard address is defined in anticipation of a future change. Up to and including NU7 there have been no funding streams defined with a shielded payment address as a recipient. That might change in future, so implementations are encouraged to support Sapling and Orchard addresses as recipients, as permitted by [18].

These rules are reproduced in [12].

The effect of the definition of 𝖢 𝗁 𝖺 𝗂 𝗇 𝖵 𝖺 𝗅 𝗎 𝖾 𝖯 𝗈 𝗈 𝗅 𝖡 𝖺 𝗅 𝖺 𝗇 𝖼 𝖾 𝖣 𝖾 𝖿 𝖾 𝗋 𝗋 𝖾 𝖽 above is that payments to the 𝖣 𝖤 𝖥 𝖤 𝖱 𝖱 𝖤 𝖣 _ 𝖯 𝖮 𝖮 𝖫 cause 𝖥 𝗎 𝗇 𝖽 𝗂 𝗇 𝗀 𝖲 𝗍 𝗋 𝖾 𝖺 𝗆 [ 𝖥 𝖴 𝖭 𝖣 ] . 𝖵 𝖺 𝗅 𝗎 𝖾 ( 𝗁 𝖾 𝗂 𝗀 𝗁 𝗍 ) to be added to 𝖢 𝗁 𝖺 𝗂 𝗇 𝖵 𝖺 𝗅 𝗎 𝖾 𝖯 𝗈 𝗈 𝗅 𝖡 𝖺 𝗅 𝖺 𝗇 𝖼 𝖾 𝖣 𝖾 𝖿 𝖾 𝗋 𝗋 𝖾 𝖽 for the block chain including that block, and that the lockbox disbursement specified in ZIP 271 [24] causes 𝖹 𝖨 𝖯 𝟤𝟩𝟣 𝖣 𝗂 𝗌 𝖻 𝗎 𝗋 𝗌 𝖾 𝗆 𝖾 𝗇 𝗍 𝖠 𝗆 𝗈 𝗎 𝗇 𝗍 to be subtracted from it.

For the funding stream definitions activated at Canopy, NU6, and NU6.1, and their changes at NU7, see ZIP 214. [19] Funding stream definitions can be added, changed, or deleted in ZIPs associated with subsequent network upgrades, subject to the ZIP process. [13]

Deployment

This proposal was initially deployed with Canopy. [21]

Changes to support deferred funding streams were deployed with NU6. [22]

Revision 2 is intended to activate with NU7 as specified in ZIP 259 [23].

Backward compatibility

This proposal intentionally creates what is known as a "bilateral consensus rule change". Use of this mechanism requires that all network participants upgrade their software to a compatible version within the upgrade window. Older software will treat post-upgrade blocks as invalid, and will follow any pre-upgrade consensus branch that persists.

Reference Implementation

Change History

2026-10-13

  • Defined fs.Value and fs.Recipient, and required each address list to cover its funding stream's height range.

  • Clarified that each funding stream requires a distinct output.

  • Defined the "prescribed way" to pay any P2SH address, and applied the P2PKH payment rule of ZIP 2008 [28] to Revision 2.

  • Clarified the "prescribed way" to pay an Orchard address from NU6.3, and that Orchard addresses are not permitted recipients.

  • Deducted the ZIP 271 lockbox disbursement from the deferred development fund chain value pool balance.

  • Corrected the address-period example table, section numbers, reference titles, and tense.

  • Added the reference implementation of Revision 2, and updated the protocol specification citations.

2026-09-30

  • Applied ZIP 2008 [28] to Revision 2 of this ZIP.

2026-09-24

  • Drafted Revision 2 for the NU7 address-period schedule.

2025-08-19

  • Defined Revision 0 and Revision 1 explicitly.

2024-10-31

  • Released Revision 1.

2024-09-26

  • Applied ZIP 2001 [27] to this ZIP (implicitly defining Revision 1).

2020-05-30

  • Released Revision 0 (status changed from Draft to Proposed).

References

Changes

protocol/Makefile +30 −14
@@ -55,10 +55,10 @@ protocol: $(PDFDIR)/protocol.pdf protocol-dark: $(PDFDIR)/protocol-dark.pdf all-pdfs: .Makefile.uptodate - $(MAKE) $(PDFDIR)/protocol.pdf $(PDFDIR)/protocol-dark.pdf $(PDFDIR)/nu6_2.pdf $(PDFDIR)/nu6_1.pdf $(PDFDIR)/nu6.pdf $(PDFDIR)/nu5.pdf $(PDFDIR)/canopy.pdf $(PDFDIR)/heartwood.pdf $(PDFDIR)/blossom.pdf $(PDFDIR)/sapling.pdf + $(MAKE) $(PDFDIR)/protocol.pdf $(PDFDIR)/protocol-dark.pdf $(PDFDIR)/nu6_3.pdf $(PDFDIR)/nu6_2.pdf $(PDFDIR)/nu6_1.pdf $(PDFDIR)/nu6.pdf $(PDFDIR)/nu5.pdf $(PDFDIR)/canopy.pdf $(PDFDIR)/heartwood.pdf $(PDFDIR)/blossom.pdf $(PDFDIR)/sapling.pdf all-specs: .Makefile.uptodate - $(MAKE) nu6_3 nu6_3-dark nu6_2 nu6_1 nu6 nu5 canopy heartwood blossom sapling + $(MAKE) nu7 nu7-dark nu6_3 nu6_2 nu6_1 nu6 nu5 canopy heartwood blossom sapling discard: git checkout -- "$(PDFDIR)/*.pdf" @@ -91,14 +91,17 @@ $(PDFDIR)/nu6_1.pdf: protocol.tex zcash.bib jubjub.png key_components_sapling.pn $(PDFDIR)/nu6_2.pdf: protocol.tex zcash.bib jubjub.png key_components_sapling.png key_components_orchard.png incremental_merkle.png $(MAKE) nu6_2 +$(PDFDIR)/nu6_3.pdf: protocol.tex zcash.bib jubjub.png key_components_sapling.png key_components_orchard.png incremental_merkle.png + $(MAKE) nu6_3 + # protocol.pdf and protocol-dark.pdf are symbolic links to the PDFs for the most recent # settled network upgrade, so that links to that upgrade's own PDF remain valid when # a later upgrade becomes the default. $(PDFDIR)/protocol.pdf: protocol.tex zcash.bib jubjub.png key_components_sapling.png key_components_orchard.png incremental_merkle.png - $(MAKE) nu6_3 + $(MAKE) nu7 $(PDFDIR)/protocol-dark.pdf: protocol.tex zcash.bib jubjub.png key_components_sapling.png key_components_orchard_dark.png incremental_merkle_dark.png - $(MAKE) nu6_3-dark + $(MAKE) nu7-dark .PHONY: auxsapling sapling auxsapling: @@ -216,21 +219,34 @@ nu6_3: $(MAKE) auxnu6_3 mkdir -p $(PDFDIR) mv -f aux/nu6_3.pdf $(PDFDIR) - ln -sf nu6_3.pdf $(PDFDIR)/protocol.pdf -.PHONY: auxnu6_3-dark nu6_3-dark -auxnu6_3-dark: - printf '\\toggletrue{darkmode}\\toggletrue{isnusixthree}\n\\renewcommand{\\docversion}{Version %s [\\NUSixThreeSpec]}\n' "$$(git describe --tags --abbrev=6 |sed 's/-1-g.*//;s/-auto//')" |tee protocol.ver +.PHONY: auxnu7 nu7 +auxnu7: + printf '\\toggletrue{isnuseven}\n\\renewcommand{\\docversion}{Version %s [\\NUSevenSpec]}\n' "$$(git describe --tags --abbrev=6 |sed 's/-1-g.*//;s/-auto//')" |tee protocol.ver + mkdir -p aux + rm -f aux/nu7.* + cp mymakeindex.sh aux + $(LATEXMK) -jobname=nu7 -auxdir=aux -outdir=aux $(EXTRAOPT) protocol $(NOCRUFT) + +nu7: + $(MAKE) auxnu7 + mkdir -p $(PDFDIR) + mv -f aux/nu7.pdf $(PDFDIR) + ln -sf nu7.pdf $(PDFDIR)/protocol.pdf + +.PHONY: auxnu7-dark nu7-dark +auxnu7-dark: + printf '\\toggletrue{darkmode}\\toggletrue{isnuseven}\n\\renewcommand{\\docversion}{Version %s [\\NUSevenSpec]}\n' "$$(git describe --tags --abbrev=6 |sed 's/-1-g.*//;s/-auto//')" |tee protocol.ver mkdir -p aux - rm -f aux/nu6_3-dark.* + rm -f aux/nu7-dark.* cp mymakeindex.sh aux - $(LATEXMK) -jobname=nu6_3-dark -auxdir=aux -outdir=aux $(EXTRAOPT) protocol $(NOCRUFT) + $(LATEXMK) -jobname=nu7-dark -auxdir=aux -outdir=aux $(EXTRAOPT) protocol $(NOCRUFT) -nu6_3-dark: - $(MAKE) auxnu6_3-dark +nu7-dark: + $(MAKE) auxnu7-dark mkdir -p $(PDFDIR) - mv -f aux/nu6_3-dark.pdf $(PDFDIR) - ln -sf nu6_3-dark.pdf $(PDFDIR)/protocol-dark.pdf + mv -f aux/nu7-dark.pdf $(PDFDIR) + ln -sf nu7-dark.pdf $(PDFDIR)/protocol-dark.pdf .PHONY: clean clean:
protocol/README.rst +5 −5
@@ -24,13 +24,13 @@ Building Use: -* ``make nu6_3`` to make the specification for NU6.3 (``nu6_3.pdf``), which is +* ``make nu7`` to make the specification for NU7 (``nu7.pdf``), which is the default (``protocol.pdf`` is a link to it); -* ``make nu6_3-dark`` to make its dark mode version (``nu6_3-dark.pdf``, linked +* ``make nu7-dark`` to make its dark mode version (``nu7-dark.pdf``, linked as ``protocol-dark.pdf``); -* ``make nu6_2``, ``make nu6_1``, ``make nu6``, ``make nu5``, ``make canopy``, - ``make heartwood``, ``make blossom``, or ``make sapling`` to make the - specification for an earlier network upgrade (``nu6_2.pdf``, etc.); +* ``make nu6_3``, ``make nu6_2``, ``make nu6_1``, ``make nu6``, ``make nu5``, + ``make canopy``, ``make heartwood``, ``make blossom``, or ``make sapling`` to + make the specification for an earlier network upgrade (``nu6_3.pdf``, etc.); * ``make all-specs`` to make all of the above; * ``make linkcheck`` (in the root of the repo) to build everything and also perform link checking. This will access the network.
protocol/protocol.tex +450 −58
@@ -84,6 +84,7 @@ \newcommand{\NUSixOneSpec}{NU6.1} \newcommand{\NUSixTwoSpec}{NU6.2} \newcommand{\NUSixThreeSpec}{NU6.3} +\newcommand{\NUSevenSpec}{NU7} \newtoggle{issapling} \togglefalse{issapling} \newtoggle{isblossom} @@ -647,6 +648,7 @@ \colorlet{pink}{magenta!70} \definecolor{burgundy}{RGB}{210,20,80} \definecolor{brown}{RGB}{160,50,50} + \definecolor{teal}{RGB}{40,190,190} \colorlet{warningred}{BrickRed} \colorlet{cream}{yellow!20} @@ -662,6 +664,7 @@ \colorlet{pink}{magenta!75} \definecolor{burgundy}{RGB}{200,18,75} \colorlet{brown}{Sepia} + \definecolor{teal}{RGB}{0,135,135} \colorlet{warningred}{BrickRed} \colorlet{cream}{yellow!20} @@ -691,10 +694,21 @@ \newcommand{\nusixtwocolorname}{\nusixtwocolor} \newcommand{\nusixthreecolor}{blue} \newcommand{\nusixthreecolorname}{bright blue} +\newcommand{\nusevencolor}{teal} +\newcommand{\nusevencolorname}{\nusevencolor} \newcommand{\labelcolor}{cream} \iftoggle{isnuseven}{ - \errmessage{NU7 is not defined yet} + \iftoggle{darkmode}{ + \providecommand{\baseurl}{https://zips.z.cash/protocol/nu7-dark.pdf} + }{ + \providecommand{\baseurl}{https://zips.z.cash/protocol/nu7.pdf} + } + \toggletrue{isnusixthree} + \newcommand{\setnuseven}{\color{\nusevencolor}} + \newcommand{\nuseven}[1]{\texorpdfstring{{\setnuseven{#1}}}{#1}} + \newcommand{\notnuseven}[1]{} + \newcommand{\notbeforenuseven}[1]{#1} } { \newcommand{\setnuseven}{} \newcommand{\nuseven}[1]{} @@ -703,11 +717,7 @@ } \iftoggle{isnusixthree}{ - \iftoggle{darkmode}{ - \providecommand{\baseurl}{https://zips.z.cash/protocol/nu6_3-dark.pdf} - }{ - \providecommand{\baseurl}{https://zips.z.cash/protocol/nu6_3.pdf} - } + \providecommand{\baseurl}{https://zips.z.cash/protocol/nu6_3.pdf} \toggletrue{isnusixtwo} \newcommand{\setnusixthree}{\color{\nusixthreecolor}} \newcommand{\nusixthree}[1]{\texorpdfstring{{\setnusixthree{#1}}}{#1}} @@ -2228,9 +2238,12 @@ \newcommand{\fsRecipientIndex}{\fs\mathsf{.RecipientIndex}} \newcommand{\fsNumRecipients}{\fs\mathsf{.NumRecipients}} \newcommand{\fsRedeemScriptHash}{\fs\mathsf{.RedeemScriptHash}} +\newcommand{\fsPubKeyHash}{\fs\mathsf{.PubKeyHash}} \newcommand{\SlowStartInterval}{\mathsf{SlowStartInterval}} \newcommand{\SlowStartShift}{\mathsf{SlowStartShift}} \newcommand{\SlowStartRate}{\mathsf{SlowStartRate}} +\newcommand{\BlossomAdjustment}{\mathsf{BlossomAdjustment}} +\newcommand{\NUSevenAdjustment}{\mathsf{NU7Adjustment}} \newcommand{\PreBlossomHalvingInterval}{\mathsf{\notbeforeblossom{PreBlossom}HalvingInterval}} \newcommand{\PostBlossomHalvingInterval}{\mathsf{PostBlossomHalvingInterval}} \newcommand{\MaxBlockSubsidy}{\mathsf{MaxBlockSubsidy}} @@ -2239,6 +2252,7 @@ \newcommand{\FoundersFraction}{\mathsf{FoundersFraction}} \newcommand{\FSRecipientChangeInterval}{\mathsf{FSRecipientChangeInterval}} \newcommand{\FSRecipientPeriod}{\mathsf{FSRecipientPeriod}} +\newcommand{\PreNUSevenEquivalentHeight}{\mathsf{PreNU7EquivalentHeight}} \newcommand{\BlockHeight}{\mathsf{height}} \newcommand{\FounderAddressAdjustedHeight}{\mathsf{FounderAddressAdjustedHeight}} \newcommand{\FoundersRewardLastBlockHeight}{\mathsf{FoundersRewardLastBlockHeight}} @@ -2252,6 +2266,18 @@ \newcommand{\heightBytes}{\mathsf{heightBytes}} \newcommand{\ChainValuePoolBalance}[1]{\ensuremath{\mathsf{ChainValuePoolBalance}^{#1}}} \newcommand{\IssuedSupply}{\mathsf{IssuedSupply}} +\newcommand{\TransactionFees}{\mathsf{TransactionFees}} +\newcommand{\NSMFeeContribution}{\mathsf{NSMFeeContribution}} +\newcommand{\MinerFees}{\mathsf{MinerFees}} +\newcommand{\ScheduledBlockSubsidy}{\mathsf{ScheduledBlockSubsidy}} +\newcommand{\AdditionalBlockSubsidy}{\mathsf{AdditionalBlockSubsidy}} +\newcommand{\HalvingIntervalFunc}{\mathsf{HalvingInterval}} +\newcommand{\BlockSubsidyFraction}{\mathsf{BLOCK\_SUBSIDY\_FRACTION}} +\newcommand{\LNTwoScaled}{\mathsf{LN2\_SCALED}} +\newcommand{\InitialNSMValueBalance}{\mathsf{INITIAL\_NSM\_VALUE\_BALANCE}} +\newcommand{\NSMReissuanceHeight}{\mathsf{NSM\_REISSUANCE\_HEIGHT}} +\newcommand{\NSMValueBalance}{\mathsf{NSMValueBalance}} +\newcommand{\NSMValueRemoved}{\mathsf{NSMValueRemoved}} \newcommand{\blockSubsidy}{\term{block subsidy}} \newcommand{\minerSubsidy}{\term{miner subsidy}} @@ -2272,6 +2298,9 @@ \newcommand{\BlossomActivationHeight}{\mathsf{BlossomActivationHeight}} \newcommand{\IsBlossomActivated}{\mathsf{IsBlossomActivated}} +\newcommand{\NUSevenActivationHeight}{\mathsf{NU7ActivationHeight}} +\newcommand{\IsNUSevenActivated}{\mathsf{IsNU7Activated}} +\newcommand{\PostNUSevenHalvingInterval}{\mathsf{PostNU7HalvingInterval}} \newcommand{\CanopyActivationHeight}{\mathsf{CanopyActivationHeight}} \newcommand{\ZIPTwoOneTwoGracePeriod}{\mathsf{ZIP212GracePeriod}} \newcommand{\ZIPTwoSevenOneActivationHeight}{\mathsf{ZIP271ActivationHeight}} @@ -2281,13 +2310,22 @@ \newcommand{\PoWLimit}{\mathsf{PoWLimit}} \newcommand{\PoWAveragingWindow}{\mathsf{PoWAveragingWindow}} +\newcommand{\PreNUSevenPoWAveragingWindow}{\mathsf{PreNU7PoWAveragingWindow}} +\newcommand{\PostNUSevenPoWAveragingWindow}{\mathsf{PostNU7PoWAveragingWindow}} +\newcommand{\GlobalShieldedBudget}{\mathsf{GlobalShieldedBudget}} +\newcommand{\OrchardProtocolBlockActionLimit}{\mathsf{OrchardProtocolBlockActionLimit}} +\newcommand{\SaplingBlockIOLimit}{\mathsf{SaplingBlockIOLimit}} +\newcommand{\SproutBlockJoinSplitLimit}{\mathsf{SproutBlockJoinSplitLimit}} \newcommand{\PoWMedianBlockSpan}{\mathsf{PoWMedianBlockSpan}} \newcommand{\PoWMaxAdjustDown}{\mathsf{PoWMaxAdjustDown}} \newcommand{\PoWMaxAdjustUp}{\mathsf{PoWMaxAdjustUp}} \newcommand{\PoWDampingFactor}{\mathsf{PoWDampingFactor}} \newcommand{\PreBlossomPoWTargetSpacing}{\mathsf{\notbeforeblossom{PreBlossom}PoWTargetSpacing}} \newcommand{\PostBlossomPoWTargetSpacing}{\mathsf{PostBlossomPoWTargetSpacing}} \newcommand{\BlossomPoWTargetSpacingRatio}{\mathsf{BlossomPoWTargetSpacingRatio}} +\newcommand{\PostNUSevenPoWTargetSpacing}{\mathsf{PostNU7PoWTargetSpacing}} +\newcommand{\NUSevenPoWTargetSpacingRatio}{\mathsf{NU7PoWTargetSpacingRatio}} +\newcommand{\CombinedPoWTargetSpacingRatio}{\mathsf{CombinedPoWTargetSpacingRatio}} \newcommand{\PoWTargetSpacingFunc}{\mathsf{PoWTargetSpacing}} \newcommand{\MeanTarget}{\mathsf{MeanTarget}} \newcommand{\MedianTime}{\mathsf{MedianTime}} @@ -2523,6 +2561,7 @@ \newcommand{\saplingtype}[1]{\textcolor{\saplingcolor}{\type{#1}}} \newcommand{\nufivetype}[1]{\textcolor{\nufivecolor}{\type{#1}}} \newcommand{\nusixthreetype}[1]{\textcolor{\nusixthreecolor}{\type{#1}}} +\newcommand{\nuseventype}[1]{\textcolor{\nusevencolor}{\type{#1}}} \newcommand{\typecodeField}{\mathtt{typecode}} \newcommand{\lengthField}{\mathtt{length}} \newcommand{\addrField}{\mathtt{addr}} @@ -3069,7 +3108,8 @@ \notnusixone{\nusix{\thisspecdefines{\NUOverwinter, \NUSapling, \NUBlossom, \NUHeartwood, \NUCanopy, \NUFive, and \NUSix}}}% \notnusixtwo{\nusixone{\thisspecdefines{\NUOverwinter, \NUSapling, \NUBlossom, \NUHeartwood, \NUCanopy, \NUFive, \NUSix, and \NUSixOne}}}% \notnusixthree{\nusixtwo{\thisspecdefines{\NUOverwinter, \NUSapling, \NUBlossom, \NUHeartwood, \NUCanopy, \NUFive, \NUSix, \NUSixOne, and \NUSixTwo}}}% -\nusixthree{\thisspecdefines{\NUOverwinter, \NUSapling, \NUBlossom, \NUHeartwood, \NUCanopy, \NUFive, \NUSix, \NUSixOne, \NUSixTwo, and \NUSixThree}}% +\notnuseven{\nusixthree{\thisspecdefines{\NUOverwinter, \NUSapling, \NUBlossom, \NUHeartwood, \NUCanopy, \NUFive, \NUSix, \NUSixOne, \NUSixTwo, and \NUSixThree}}}% +\nuseven{\thisspecdefines{\NUOverwinter, \NUSapling, \NUBlossom, \NUHeartwood, \NUCanopy, \NUFive, \NUSix, \NUSixOne, \NUSixTwo, \NUSixThree, and \NUSeven}}% It is a work in progress. Protocol differences from \Zerocash and \Bitcoin are also explained. \vspace{2ex} @@ -3151,6 +3191,9 @@ \notbeforenusixthree{Changes specific to the \NUSixThree upgrade following \NUSixTwo are highlighted in \nusixthree{\nusixthreecolorname}.} +\notbeforenuseven{Changes specific to the \NUSeven upgrade following \NUSixThree +are highlighted in \nuseven{\nusevencolorname}.} + All of these are also changes from \Zerocash. The name ``Sprout'' refers to the \Zcash protocol prior to \NUSapling @@ -3537,10 +3580,12 @@ $\PRFOutputLengthNfSapling$,} $\NoteCommitRandLengthSprout$, $\RandomSeedLength$, $\AuthPrivateLength$, $\NoteUniquePreRandLength$,\sapling{ $\SpendingKeyLength$, $\DiversifierLength$,\nufive{ $\DiversifierKeyLength$,}\nusixthree{ $\QuantumSpendingKeyLength$, $\QuantumIntermediateKeyLength$,} $\InViewingKeyLength{Sapling}$, $\OutViewingKeyLength$, $\ScalarLength{Sapling}$,\nufive{ $\ScalarLength{Orchard}$, $\BaseLength{Orchard}$,}} - $\MAXMONEY$,\blossom{ $\BlossomActivationHeight$,}\strut\canopy{ $\CanopyActivationHeight$, $\ZIPTwoOneTwoGracePeriod$,} + $\MAXMONEY$,\blossom{ $\BlossomActivationHeight$,}\strut\canopy{ $\CanopyActivationHeight$, $\ZIPTwoOneTwoGracePeriod$,}\nuseven{ $\NUSevenActivationHeight$,} $\SlowStartInterval$, $\PreBlossomHalvingInterval$, $\MaxBlockSubsidy$, $\NumFounderAddresses$, - $\PoWLimit$, $\PoWAveragingWindow$, $\PoWMedianBlockSpan$, $\PoWDampingFactor$, - \notblossom{and }$\PreBlossomPoWTargetSpacing$\blossom{, and $\PostBlossomPoWTargetSpacing$}. + $\PoWLimit$, \notnuseven{$\PoWAveragingWindow$}\nuseven{$\PreNUSevenPoWAveragingWindow$, $\PostNUSevenPoWAveragingWindow$}, $\PoWMedianBlockSpan$, $\PoWDampingFactor$, + \notblossom{and }$\PreBlossomPoWTargetSpacing$\blossom{, \notnuseven{and }$\PostBlossomPoWTargetSpacing$}\nuseven{, $\PostNUSevenPoWTargetSpacing$, + $\GlobalShieldedBudget$, $\OrchardProtocolBlockActionLimit$, $\SaplingBlockIOLimit$, $\SproutBlockJoinSplitLimit$, + $\LNTwoScaled$, $\InitialNSMValueBalance$, and $\NSMReissuanceHeight$}. \end{flushleft} \end{formulae} @@ -4111,13 +4156,17 @@ \vspace{-2ex} As in \Bitcoin, the remaining value in the \transparentTxValuePool of a non-coinbase \transaction -is available to miners as a \defining{\transactionFee}. That is, the sum of those values for non-coinbase \transactions -in each \block is treated as an implicit input to the \transparentTxValuePool balance of the -\block's \coinbaseTransaction (in addition to the implicit input created by issuance). +is a \defining{\transactionFee}. The sum of those values for non-coinbase \transactions in each +\block\nuseven{ (pre-\NUSeven), or $\MinerFees(\BlockHeight)$ for the \block at \blockHeight +$\BlockHeight$ (\NUSeven onward),} is available to miners: it is treated as an implicit input to +the \transparentTxValuePool balance of the \block's \coinbaseTransaction (in addition to the +implicit input created by issuance).\nuseven{ $\MinerFees$ is defined in \shortcrossref{subsidies}.} The remaining value in the \transparentTxValuePool of \coinbaseTransactions\nusix{ in \blocks -prior to \NUSix} is destroyed. \nusix{From \NUSix, this remaining value is required to be zero; -that is, all of the available balance \MUST be consumed by outputs of the \coinbaseTransaction.} +prior to \NUSix} is left unclaimed and is not added to any \chainValuePool. \nusix{From \NUSix, this +remaining value is required to be zero; that is, all of the available balance \MUST be consumed by +outputs of the \coinbaseTransaction.} \nusevenonward{This unclaimed value is included in +$\InitialNSMValueBalance$, and so is reissued as specified in \shortcrossref{subsidies}.} \vspace{-1ex} \consensusrule{ @@ -4412,21 +4461,26 @@ \canopyonward{The \blockSubsidy is composed of a \minerSubsidy and a series of \defining{\fundingStreams}.} -As in \Bitcoin, the miner of a \block also receives \defining{\transactionFees}. +As in \Bitcoin, the miner of a \block also receives \defining{\transactionFees}\nuseven{ +(pre-\NUSeven), or $\MinerFees(\BlockHeight)$ (\NUSeven onward)}. The calculations of the \blockSubsidy, \minerSubsidy, \notcanopy{and }\foundersReward\canopy{, and \fundingStreams} depend on the \blockHeight, as defined in \crossref{blockchain}. \crossref{subsidies}\notbeforenusixone{\\} describes these calculations. +\nusevenonward{From $\NSMReissuanceHeight$, the \blockSubsidy also includes value reissued from the +NSM Value Balance defined in \crossref{chainvaluepoolbalances}, and so depends on the NSM Value +Balance after the preceding \block as well as on the \blockHeight.} + \lsubsection{Coinbase Transactions}{coinbasetransactions} A \transaction that has a single \transparentInput with a null \prevoutField{} field, is called a \defining{\coinbaseTransaction}. Every \block has a single \coinbaseTransaction as the first \transaction in the \block. The purpose of this \coinbaseTransaction is to -collect and spend any \minerSubsidy, and \transactionFees paid by other \transactions included -in the \block. +collect and spend any \minerSubsidy, and the \transactionFees paid by other \transactions +included in the \block\nuseven{ (pre-\NUSeven) or $\MinerFees(\BlockHeight)$ (\NUSeven onward)}. \precanopy{\crossref{foundersreward} specifies that the \coinbaseTransaction \MUST also pay the \foundersReward.} @@ -4458,6 +4512,8 @@ \Mainnet \NUSixThree \activationBlock: $\mathtt{00000000001a8b54bbde4e8996373417a6b33ee2bd984bcf02882e5d8128d761}$ +\Mainnet \NUSeven \activationBlock: $\mathtt{0000000000246a2b1fecb3f465770894d146f6b7044e46b13ffb65e57e4ccd4a}$ + \introlist There is also a public test \network called \defining{\Testnet}. It supports a \TAZ token which is intended to have no monetary value. By convention, \Testnet normally activates \networkUpgrades (as described @@ -4469,6 +4525,8 @@ \Testnet \NUSixThree \activationBlock: $\mathtt{000003943e1a2c60c17b69ed4d448ea9296019a247f1134b507917941957fccd}$ +\Testnet \NUSeven \activationBlock: $\mathtt{000089ba27100beede16d64b34e3d1b626b428cb7ee9fe6dcfdc217ce24e78af}$ + We call the smallest units of currency (on either \network) \zatoshi.\footnote{\definingquotedterm{tazoshi} may be used for the smallest units of currency on Testnet, but it is usually more convenient to use a \network-independent term.} @@ -7132,6 +7190,8 @@ as defined in \cite{ZIP-257}.} \nusixthreeonlyitem{All \transactions \MUST use the \NUSixThree \consensusBranchID \hexint{37A5165B} as defined in \cite{ZIP-258}.} + \nusevenonlyitem{All \transactions \MUST use the \NUSeven \consensusBranchID \hexint{77190AD9} + as defined in \cite{ZIP-259}.} \end{consensusrules} @@ -7863,6 +7923,47 @@ created as a result of accepting a \block, then all nodes \MUST reject the block as invalid.} } %nusixthree +\nuseven{ +\vspace{1.5ex} +Let $\InitialNSMValueBalance$ and $\NUSevenActivationHeight$ be as defined in \crossref{constants}, +and let $\NSMFeeContribution$ and $\AdditionalBlockSubsidy$ be as defined in \shortcrossref{subsidies}. + +\cite{ZIP-237} specifies a Network Sustainability Mechanism that tracks value removed from +circulation and reissues it through the \blockSubsidy. The value removed from circulation in the +\block at \blockHeight $\BlockHeight$ is $\NSMValueRemoved(\BlockHeight) := \NSMFeeContribution(\BlockHeight)$, +the part of the \transactionFees specified by \cite{ZIP-235}, which is the only removal mechanism +deployed in \NUSeven. + +The \defining{NSM Value Balance} of a \blockChain up to and including \blockHeight $\BlockHeight$ +is given by: + +\begin{formulae} + \item $\NSMValueBalance(\BlockHeight \typecolon \Nat) :=$ + \vspace{-0.5ex} + \item \tab $\begin{cases} + 0,&\caseif \BlockHeight < \NUSevenActivationHeight - 1 \\[0.6ex] + \InitialNSMValueBalance,&\caseif \BlockHeight = \NUSevenActivationHeight - 1 \\[0.6ex] + \NSMValueBalance(\BlockHeight - 1) - \AdditionalBlockSubsidy(\BlockHeight) \\[-0.4ex] + \hspace{1.5em} +\, \NSMValueRemoved(\BlockHeight),&\caseotherwise + \end{cases}$ +\end{formulae} + +\vspace{-2ex} +\consensusrule{\nusevenonward{If $\NSMValueBalance(\BlockHeight)$ would become negative in the \blockChain +created as a result of accepting a \block at \blockHeight $\BlockHeight$, then all nodes \MUST reject +the block as invalid.}} + +\begin{pnotes} + \item The NSM Value Balance is tracked as consensus state alongside the \chainValuePools. It is + not a spendable \chainValuePool and is not included in $\IssuedSupply(\BlockHeight)$: it + counts \ZEC (or \TAZ) that is not in circulation. Reissuance moves value from the NSM Value + Balance into the \totalIssuedSupply through the \blockSubsidy. + \item As \cite{ZIP-2003} clarifies, the \SproutChainValuePool balance at \NUSeven activation + remains issued, and so is included in $\IssuedSupply(\BlockHeight)$ for the purposes of + \cite{ZIP-237}. +\end{pnotes} +} %nuseven + \vspace{2ex} The \defining{\totalIssuedSupply} of a \blockChain at \blockHeight $\BlockHeight$ is given by the function: @@ -9290,6 +9391,12 @@ \end{cases}$ \item $\ZIPTwoOneTwoGracePeriod \typecolon \Nat := 32256$ } %canopy +\nuseven{ + \item $\NUSevenActivationHeight \typecolon \Nat := \begin{cases} + 3543405,&\squash\text{for \Mainnet} \\ + 4465026,&\squash\text{for \Testnet} + \end{cases}$ \cite{ZIP-259} +} %nuseven \item $\SlowStartInterval \typecolon \Nat := 20000$ \item $\PreBlossomHalvingInterval \typecolon \Nat := 840000$ \item $\MaxBlockSubsidy \typecolon \Nat := 1.25 \smult 10^9$ (\zatoshi) @@ -9299,7 +9406,13 @@ 2^{243} - 1,&\squash\text{for \Mainnet} \\ 2^{251} - 1,&\squash\text{for \Testnet} \end{cases}$ +\notnuseven{ \item $\PoWAveragingWindow \typecolon \Nat := 17$ +} %notnuseven +\nuseven{ + \item $\PreNUSevenPoWAveragingWindow \typecolon \Nat := 17$ + \item $\PostNUSevenPoWAveragingWindow \typecolon \Nat := 102$ +} %nuseven \item $\PoWMedianBlockSpan \typecolon \Nat := 11$ \item $\PoWMaxAdjustDown \typecolon \Rat := \frac{32}{100}$ \item $\PoWMaxAdjustUp \typecolon \Rat := \frac{16}{100}$ @@ -9308,8 +9421,34 @@ \blossom{ \item $\PostBlossomPoWTargetSpacing \typecolon \Nat := 75$ (seconds). } %blossom +\nuseven{ + \item $\PostNUSevenPoWTargetSpacing \typecolon \Nat := 25$ (seconds). + \item $\GlobalShieldedBudget \typecolon \Nat := 330$ + \item $\OrchardProtocolBlockActionLimit \typecolon \Nat := 330$ + \item $\SaplingBlockIOLimit \typecolon \Nat := 300$ + \item $\SproutBlockJoinSplitLimit \typecolon \Nat := 0$ + \item $\LNTwoScaled \typecolon \Nat := 6931680000$ + \item $\InitialNSMValueBalance \typecolon \range{0}{\MAXMONEY} := \begin{cases} + 36858445520,&\squash\text{for \Mainnet} \\ + 55768414957,&\squash\text{for \Testnet} + \end{cases}$ (\zatoshi) + \item $\NSMReissuanceHeight \typecolon \Nat := \begin{cases} + 8939664,&\squash\text{for \Mainnet} \\ + 7305222,&\squash\text{for \Testnet} + \end{cases}$ \cite{ZIP-259} +} %nuseven \end{formulae} +\nuseven{ +\vspace{-1.5ex} +\pnote{$\InitialNSMValueBalance$ is the \blockSubsidy and \transactionFees left unclaimed by +\coinbaseTransactions before \NUSix, which \cite{ZIP-237} derives for each \network from the +scheduled issuance and the \totalIssuedSupply at the last pre-\NUSix \blockHeight. +$\NSMReissuanceHeight$ is the height at which reissuance begins. \cite{ZIP-237} specifies how +it is calculated from the scheduled issuance curve, and \cite{ZIP-259} gives the resulting value +for each \network.} +} %nuseven + \introsection \lsubsection{Concrete Cryptographic Schemes}{concreteschemes} @@ -13548,11 +13687,16 @@ and rationale is given in \cite{ZODL-Ironwood}. Specifications relating to wallet support and migration to the \IronwoodPool are in \cite{ZIP-318} and \cite{ZIP-326}.} +\nuseven{An eleventh upgrade, called \defining{\NUSeven}, activated on \Mainnet on 6~November, 2026 +at \blockHeight $3543405$ \cite{ZIP-259}. Its specifications are described in this document, +\cite{ZIP-259}, \cite{ZIP-218}, \cite{ZIP-235}, \cite{ZIP-237}, \cite{ZIP-2003}, and \cite{ZIP-2008}, +with updates to \cite{ZIP-207} and \cite{ZIP-214}.} + \introlist \vspace{1.5ex} This section summarizes the strategy for upgrading from the Sprout epoch to subsequent epochs of the protocol (\NUOverwinter, \NUSapling, \NUBlossom, \NUHeartwood, \NUCanopy, \NUFive, \NUSix, -\NUSixOne, \NUSixTwo, and \NUSixThree), and for future upgrades. +\NUSixOne, \NUSixTwo, \NUSixThree, and \NUSeven), and for future upgrades. \defining{The \networkUpgrade mechanism is described in \cite{ZIP-200}.} @@ -13932,7 +14076,8 @@ be $\hexint{03C48270}$.} \saplingprenufiveitem{The \transactionVersionNumber{} \MUST be $4$.} \nufiveprenusixthreeitem{The \transactionVersionNumber \MUST be $4$ or $5$.} - \nusixthreeonwarditem{The \transactionVersionNumber \MUST be $4$ or $5$ or $6$.} + \nusixthreeonlyitem{The \transactionVersionNumber \MUST be $4$ or $5$ or $6$.} + \nusevenonwarditem{The \transactionVersionNumber \MUST be $5$ or $6$.} \saplingonwarditem{If the \transactionVersionNumber{} is $4$ then the \versionGroupID \MUST be $\hexint{892F2085}$.} \nufiveonwarditem{If the \transactionVersionNumber{} is $5$ then the \versionGroupID \MUST be $\hexint{26A7270A}$.} \nusixthreeonwarditem{If the \transactionVersionNumber{} is $6$ then the \versionGroupID \MUST be $\hexint{D884B698}$.} @@ -14015,14 +14160,16 @@ \end{itemize}} \vspace{-1ex} \item \nusix{Let $\totalDeferredOutput$\nusixone{ and $\totalDeferredInput$} be as defined in \shortcrossref{subsidies}.} + \nuseven{Let $\MinerFees$ be as defined in \shortcrossref{subsidies}.} For the \block at \blockHeight $\mathsf{height}$: \begin{itemize} \item define the \totalOutputValue of its \coinbaseTransaction to be the total value in \zatoshi of its \transparentOutputs\heartwood{, minus $\vBalance{\SaplingPoolId}$}\nufive{, minus $\vBalance{\OrchardPoolId}$}\nusix{, plus $\totalDeferredOutput(\mathsf{height})$}; \item define the \totalInputValue of its \coinbaseTransaction to be the value in \zatoshi - of the \blockSubsidy, plus the \transactionFees paid by \transactions in the - \block\nusixone{, plus $\totalDeferredInput(\mathsf{height})$}. + of the \blockSubsidy, plus \prenuseven{the \transactionFees paid by \transactions in the + \block}\nuseven{ or }\nusevenonward{$\MinerFees(\mathsf{height})$}\nusixone{, plus + $\totalDeferredInput(\mathsf{height})$}. \end{itemize} \vspace{-1ex} \prenusix{The \totalOutputValue of a \coinbaseTransaction \MUSTNOT be greater than its \totalInputValue.} @@ -14558,6 +14705,18 @@ $653606$ or greater on \Testnet, $\nTimeField$ \MUST be less than or equal to the \medianTimePast of that \block plus $90 \mult 60$ seconds. \item The size of a \block \MUST be less than or equal to $2000000$ bytes. + \nusevenonwarditem{Let $\nActionsField{Orchard}$, $\nActionsField{Ironwood}$, $\nSpendsSapling$, + $\nOutputsSapling$, and $\nJoinSplit$ be the fields of a \transaction specified in + \crossref{txnencoding}, each taken as $0$ for a \transaction version that does not have + the field. Summed over the \transactions in the \block: + \begin{itemize} + \item $\nActionsField{Orchard}$ \MUSTNOT exceed $\OrchardProtocolBlockActionLimit$; + \item $\nActionsField{Ironwood}$ \MUSTNOT exceed $\OrchardProtocolBlockActionLimit$; + \item $\nSpendsSapling + \nOutputsSapling$ \MUSTNOT exceed $\SaplingBlockIOLimit$; + \item $\nJoinSplit$ \MUSTNOT exceed $\SproutBlockJoinSplitLimit$; and + \item $\nActionsField{Orchard} + \nActionsField{Ironwood} + \nSpendsSapling + \nOutputsSapling + 2 \mult \nJoinSplit$ + \MUSTNOT exceed $\GlobalShieldedBudget$. + \end{itemize}} \notheartwood{ \saplingonwarditem{$\hashFinalSaplingRoot$ \MUST be $\LEBStoOSPOf{256}{\rt{\SaplingPoolId}}$ where $\rt{\SaplingPoolId}$ is the \merkleRoot of the \SaplingPoolAdj \noteCommitmentTree for the final @@ -14847,10 +15006,14 @@ the desired \blockTargetSpacing. Unlike \Bitcoin, the difficulty adjustment occurs after every \block. -\notbeforeblossom{The constants }$\PoWLimit$, $\PreBlossomHalvingInterval$, $\PoWAveragingWindow$, +\notbeforenuseven{\begingroup\raggedright} +\notbeforeblossom{The constants }$\PoWLimit$, $\PreBlossomHalvingInterval$, \notnuseven{$\PoWAveragingWindow$}\nuseven{$\PreNUSevenPoWAveragingWindow$, +$\PostNUSevenPoWAveragingWindow$}, $\PoWMaxAdjustDown$, $\PoWMaxAdjustUp$, $\PoWDampingFactor$,\notblossom{ and} -$\PreBlossomPoWTargetSpacing$\blossom{, and $\PostBlossomPoWTargetSpacing$} +$\PreBlossomPoWTargetSpacing$\blossom{, \notnuseven{and }$\PostBlossomPoWTargetSpacing$}\nuseven{, $\PostNUSevenPoWTargetSpacing$, +and $\NUSevenActivationHeight$} are specified in section \crossref{constants}. +\notbeforenuseven{\par\endgroup} Let $\ToCompact$ and $\ToTarget$ be as defined in \crossref{nbits}. @@ -14879,25 +15042,53 @@ \item $\IsBlossomActivated(\BlockHeight \typecolon \Nat) := (\BlockHeight \geq \BlossomActivationHeight)$ \item $\BlossomPoWTargetSpacingRatio := \hfrac{\PreBlossomPoWTargetSpacing}{\PostBlossomPoWTargetSpacing}$ \item $\PostBlossomHalvingInterval := \floor{\PreBlossomHalvingInterval \mult \BlossomPoWTargetSpacingRatio}$ - \item $\PoWTargetSpacingFunc(\BlockHeight \typecolon \Nat) := \begin{cases} +\nuseven{ + \item $\IsNUSevenActivated(\BlockHeight \typecolon \Nat) := (\BlockHeight \geq \NUSevenActivationHeight)$ + \item $\NUSevenPoWTargetSpacingRatio := \hfrac{\PostBlossomPoWTargetSpacing}{\PostNUSevenPoWTargetSpacing}$ + \item $\CombinedPoWTargetSpacingRatio := \BlossomPoWTargetSpacingRatio \mult \NUSevenPoWTargetSpacingRatio$ + \item $\PostNUSevenHalvingInterval := \floor{\PostBlossomHalvingInterval \mult \NUSevenPoWTargetSpacingRatio}$ +} %nuseven + \item $\PoWTargetSpacingFunc(\BlockHeight \typecolon \Nat) :=$ + \vspace{-0.5ex} + \item \tab $\begin{cases} \PreBlossomPoWTargetSpacing,&\caseif \text{not } \IsBlossomActivated(\BlockHeight) \\ - \PostBlossomPoWTargetSpacing,&\caseotherwise + \PostBlossomPoWTargetSpacing,&\notnuseven{\caseotherwise}\notbeforenuseven{\nuseven{\caseif \IsBlossomActivated(\BlockHeight)} \\[-0.8ex] + &\nuseven{\text{ and not } \IsNUSevenActivated(\BlockHeight)}\! \\ + \nuseven{\PostNUSevenPoWTargetSpacing,}&\nuseven{\caseotherwise}} + \end{cases}$ +\nuseven{ + \item $\PoWAveragingWindow(\BlockHeight \typecolon \Nat) :=$ + \vspace{-0.5ex} + \item \tab $\begin{cases} + \PreNUSevenPoWAveragingWindow,&\caseif \text{not } \IsNUSevenActivated(\BlockHeight) \\ + \PostNUSevenPoWAveragingWindow,&\caseotherwise \end{cases}$ +} %nuseven } %blossom - \item $\AveragingWindowTimespan\blossom{(\BlockHeight \typecolon \Nat)} := \PoWAveragingWindow \mult \PoWTargetSpacingFunc\blossom{(\BlockHeight)}$ + \item $\AveragingWindowTimespan\blossom{(\BlockHeight \typecolon \Nat)} :=\notnuseven{ \PoWAveragingWindow \mult \PoWTargetSpacingFunc\blossom{(\BlockHeight)}}$ +\notbeforenuseven{ + \vspace{-0.8ex} + \item \tab $\PoWAveragingWindow(\BlockHeight) \mult \PoWTargetSpacingFunc(\BlockHeight)$ +} %notbeforenuseven \item $\MinActualTimespan\blossom{(\BlockHeight \typecolon \Nat)} := \floor{\AveragingWindowTimespan\blossom{(\BlockHeight)} \mult (1 - \PoWMaxAdjustUp)}$ \item $\MaxActualTimespan\blossom{(\BlockHeight \typecolon \Nat)} := \floor{\AveragingWindowTimespan\blossom{(\BlockHeight)} \mult (1 + \PoWMaxAdjustDown)}$ \item $\MedianTime(\BlockHeight \typecolon \Nat) := \median(\listcomp{\nTime(i) \for i \from \maximum(0, \BlockHeight - \PoWMedianBlockSpan) \upto \BlockHeight - 1})$ - \item $\ActualTimespan(\BlockHeight \typecolon \Nat) := \MedianTime(\BlockHeight) - \MedianTime(\BlockHeight - \PoWAveragingWindow)$ + \item $\ActualTimespan(\BlockHeight \typecolon \Nat) :=\notnuseven{ \MedianTime(\BlockHeight) - \MedianTime(\BlockHeight - \PoWAveragingWindow)}$ +\notbeforenuseven{ + \vspace{-0.8ex} + \item \tab $\MedianTime(\BlockHeight) - \MedianTime(\BlockHeight - \PoWAveragingWindow(\BlockHeight))$ +} %notbeforenuseven \item $\ActualTimespanDamped(\BlockHeight \typecolon \Nat) :=$ \vspace{-0.8ex} \item \tab $\AveragingWindowTimespan\blossom{(\BlockHeight)} + \trunc{\hfrac{\ActualTimespan(\BlockHeight) - \AveragingWindowTimespan\blossom{(\BlockHeight)}}{\PoWDampingFactor}}$ \item $\ActualTimespanBounded(\BlockHeight \typecolon \Nat) := \bound{\MinActualTimespan\blossom{(\BlockHeight)}}{\MaxActualTimespan\blossom{(\BlockHeight)}}(\ActualTimespanDamped(\BlockHeight))$ - \item $\MeanTarget(\BlockHeight \typecolon \Nat) := \!\begin{cases} - \PoWLimit, \hspace{16em}\text{if } \BlockHeight \leq \PoWAveragingWindow \\ - \mean(\listcomp{\!\ToTarget(\nBits(i)\kern-0.1em) \for i \from \BlockHeight\!-\!\PoWAveragingWindow \upto \BlockHeight\!-\!1\!}),\\ + \item $\MeanTarget(\BlockHeight \typecolon \Nat) :=$ + \vspace{-0.5ex} + \item \tab $\begin{cases} + \PoWLimit, \hspace{16em}\text{if } \BlockHeight \leq \PoWAveragingWindow\nuseven{(\BlockHeight)} \\ + \mean(\listcomp{\!\ToTarget(\nBits(i)\kern-0.1em) \for i \from \BlockHeight\!-\!\PoWAveragingWindow\nuseven{(\BlockHeight)} \upto \BlockHeight\!-\!1\!}),\\ \hspace{20.7em}\text{otherwise.} \end{cases}$ \end{formulae} @@ -14906,9 +15097,11 @@ The \targetThreshold for a given \blockHeight $\BlockHeight$ is then calculated as: \begin{formulae} - \item $\Threshold(\BlockHeight \typecolon \Nat) \hspace{0.43em} := \hspace{0.3em} \begin{cases} + \item $\Threshold(\BlockHeight \typecolon \Nat) :=$ + \vspace{-0.5ex} + \item \tab $\begin{cases} \PoWLimit, \hspace{16em}\text{if } \BlockHeight = 0 \\ - \minimum(\PoWLimit, \floor{\hfrac{\MeanTarget(\BlockHeight)}{\AveragingWindowTimespan}} + \minimum(\PoWLimit, \floor{\hfrac{\MeanTarget(\BlockHeight)}{\AveragingWindowTimespan\blossom{(\BlockHeight)}}} \mult \ActualTimespanBounded(\BlockHeight)),\\ \hspace{20.7em}\text{otherwise} \end{cases}$ @@ -14922,7 +15115,7 @@ is that these functions use only information from \blocks \emph{preceding} the given \blockHeight. \introlist \item When the $\median$ function is applied to a sequence of even length (which only happens - in the definition of $\MedianTime$ during the first $\PoWAveragingWindow - 1$ \blocks of + in the definition of $\MedianTime$ during the first $\PoWAveragingWindow\nuseven{(\BlockHeight)} - 1$ \blocks of the \blockChain), the element that begins the second half of the sequence is taken. This corresponds to the \zcashd implementation, but was not specified correctly in versions of this specification prior to \historyref{2019.0.0}. @@ -14932,6 +15125,8 @@ is changed to allow minimum-difficulty \blocks, as described in \cite{ZIP-205}. \blossom{The \NUBlossom \networkUpgrade changes the minimum-difficulty time threshold to $6$ times the \blockTargetSpacing, as described in \cite{ZIP-208}.} +\nuseven{The \NUSeven \networkUpgrade changes it to $18$ times the \blockTargetSpacing, as described +in \cite{ZIP-218}, so that it remains $450$ seconds at the $25$-second \blockTargetSpacing.} \notbeforeblossom{These changes do}\notblossom{This change does} not apply to \Mainnet. @@ -14958,10 +15153,10 @@ \end{formulae} \introlist -\vspace{-2ex} +\vspace{0.5ex} \lsubsubsection{Definition of Work}{workdef} -\vspace{-0.5ex} +\vspace{0.5ex} As explained in \crossref{blockchain}, a node chooses the ``best'' \blockChain visible to it by finding the chain of valid \blocks with the greatest total work. @@ -14972,58 +15167,102 @@ \introlist -\vspace{-1.5ex} +\vspace{0.5ex} \lsubsection{Calculating Block Subsidy\notbeforecanopy{, Funding Streams,}\notbeforenusixone{ Lockbox Disbursement,} and Founders' Reward}{subsidies} -\vspace{-0.5ex} +\vspace{0.5ex} In \crossref{subsidyconcepts} the \blockSubsidy, \minerSubsidy,\notcanopy{ and} \foundersReward\canopy{, and \fundingStreams} are defined. Their amounts in \zatoshi are calculated from the \blockHeight using the formulae below. +\notbeforenuseven{\begingroup\raggedright} Let\notbeforeblossom{ the constants} $\SlowStartInterval$,\, $\PreBlossomHalvingInterval$,\, -\blossom{$\PostBlossomHalvingInterval$,\, $\BlossomActivationHeight$,\, }$\MaxBlockSubsidy$, +\blossom{$\PostBlossomHalvingInterval$,\, $\BlossomActivationHeight$,\, }\nuseven{$\PostNUSevenHalvingInterval$,\, +$\NUSevenActivationHeight$,\, $\LNTwoScaled$,\, $\NSMReissuanceHeight$,\, }$\MaxBlockSubsidy$, and $\FoundersFraction$ be as defined in \crossref{constants}. +\notbeforenuseven{\par\endgroup} \canopy{Let $\FundingStreams$ be as specified in \crossref{zip214fundingstreams}.} +\nuseven{Let $\NSMValueBalance$ be as defined in \crossref{chainvaluepoolbalances}.} + \nusixone{Let $\ZIPTwoSevenOneActivationHeight$ and $\ZIPTwoSevenOneDisbursementAmount$ be as defined in \cite{ZIP-271}.} \vspace{1ex} \begin{formulae} \item $\SlowStartShift \typecolon \Nat := \hfrac{\SlowStartInterval}{2}$ \item $\SlowStartRate \typecolon \Nat := \hfrac{\MaxBlockSubsidy}{\SlowStartInterval}$ +\blossom{ + \vspace{0.5ex} + \item $\BlossomAdjustment \typecolon \Rat := \hfrac{\BlossomActivationHeight - \SlowStartShift}{\PreBlossomHalvingInterval}$ +} %blossom +\nuseven{ \vspace{0.5ex} - \item $\Halving(\BlockHeight \typecolon \Nat) := \begin{cases} + \item $\NUSevenAdjustment \typecolon \Rat := \BlossomAdjustment + \hfrac{\NUSevenActivationHeight - \BlossomActivationHeight}{\PostBlossomHalvingInterval}$ +} %nuseven + \vspace{0.5ex} + \needspace{26ex} + \item $\Halving(\BlockHeight \typecolon \Nat) :=$ + \vspace{-0.5ex} + \item \tab $\begin{cases} 0,&\caseif \BlockHeight < \SlowStartShift \\ \notblossom{ \floor{\hfrac{\BlockHeight - \SlowStartShift}{\PreBlossomHalvingInterval}}\kern-0.25em,&\caseotherwise } %notblossom \notbeforeblossom{ - \floor{\hfrac{\BlockHeight - \SlowStartShift}{\PreBlossomHalvingInterval}}\kern-0.25em,&\blossom{\caseif \text{not } \IsBlossomActivated(\BlockHeight)} \\[1.6ex] - \multicolumn{2}{@{}l}{\blossom{\floor{\hfrac{\BlossomActivationHeight - \SlowStartShift}{\PreBlossomHalvingInterval} + - \hfrac{\BlockHeight - \BlossomActivationHeight}{\PostBlossomHalvingInterval}}\kern-0.3em,\hspace{0.85em}\caseotherwise}} + \floor{\hfrac{\BlockHeight - \SlowStartShift}{\PreBlossomHalvingInterval}}\kern-0.25em,&\blossom{\caseif \text{not } \IsBlossomActivated(\BlockHeight)} \\[1.2ex] + \blossom{\floor{\BlossomAdjustment + \hfrac{\BlockHeight - \BlossomActivationHeight}{\PostBlossomHalvingInterval}}\kern-0.3em,}&\blossom{\notnuseven{\caseotherwise}\nuseven{\caseif \IsBlossomActivated(\BlockHeight)}}\notbeforenuseven{ \\[-1.8ex] + &\nuseven{\text{ and not } \IsNUSevenActivated(\BlockHeight)}\! \\[1.2ex] + \nuseven{\floor{\NUSevenAdjustment + \hfrac{\BlockHeight - \NUSevenActivationHeight}{\PostNUSevenHalvingInterval}}\kern-0.3em,}&\nuseven{\caseotherwise}} } %notbeforeblossom \end{cases}$ \vspace{1ex} - \item $\BlockSubsidy(\BlockHeight \typecolon \Nat) := \begin{cases} + \needspace{32ex} + \item $\notnuseven{\BlockSubsidy}\nuseven{\ScheduledBlockSubsidy}(\BlockHeight \typecolon \Nat) :=$ + \vspace{-0.5ex} + \item \tab $\begin{cases} \SlowStartRate \mult \BlockHeight,&\caseif \BlockHeight < \SlowStartShift \\[1.2ex] \SlowStartRate \mult (\BlockHeight + 1),&\caseif \SlowStartShift \leq \BlockHeight \\[-0.8ex] &\text{ and } \BlockHeight < \SlowStartInterval \\[1.2ex] \floor{\hfrac{\MaxBlockSubsidy}{2^{\Halving(\BlockHeight)}}}\kern-0.25em,&\notblossom{\caseotherwise}\notbeforeblossom{\caseif \SlowStartInterval \leq \BlockHeight} \\[-1.4ex] \notbeforeblossom { &\blossom{\text{ and not } \IsBlossomActivated(\BlockHeight)}\! \\[1.2ex] - \blossom{\floor{\hfrac{\MaxBlockSubsidy}{\BlossomPoWTargetSpacingRatio \mult 2^{\Halving(\BlockHeight)}}}\kern-0.25em,}&\blossom{\caseotherwise} + \blossom{\floor{\hfrac{\MaxBlockSubsidy}{\BlossomPoWTargetSpacingRatio \mult 2^{\Halving(\BlockHeight)}}}\kern-0.25em,}&\blossom{\notnuseven{\caseotherwise}\nuseven{\caseif \IsBlossomActivated(\BlockHeight)}}\notbeforenuseven{ \\[-1.8ex] + &\nuseven{\text{ and not } \IsNUSevenActivated(\BlockHeight)}\! \\[1.2ex] + \nuseven{\floor{\hfrac{\MaxBlockSubsidy}{\CombinedPoWTargetSpacingRatio \mult 2^{\Halving(\BlockHeight)}}}\kern-0.25em,}&\nuseven{\caseotherwise}} } %notbeforeblossom \end{cases}$ +\nuseven{ + \vspace{1ex} + \item $\HalvingIntervalFunc(\BlockHeight \typecolon \Nat) := \begin{cases} + \PostBlossomHalvingInterval,&\caseif \text{not } \IsNUSevenActivated(\BlockHeight) \\ + \PostNUSevenHalvingInterval,&\caseotherwise + \end{cases}$ + \vspace{0.5ex} + \item $\BlockSubsidyFraction(\BlockHeight \typecolon \Nat) \typecolon \Rat := + \hfrac{\floor{\LNTwoScaled / \HalvingIntervalFunc(\BlockHeight)}}{10^{10}}$ \vspace{0.5ex} + \item $\AdditionalBlockSubsidy(\BlockHeight \typecolon \Nat) :=$ + \vspace{-0.5ex} + \item \tab $\begin{cases} + 0,&\caseif \BlockHeight < \NSMReissuanceHeight \\[1ex] + \mathsf{ceiling}\big(\BlockSubsidyFraction(\BlockHeight) \mult \\[-0.4ex] + \hspace{4em} \NSMValueBalance(\BlockHeight - 1)\big),&\caseotherwise + \end{cases}$ + \vspace{0.5ex} + \item $\BlockSubsidy(\BlockHeight \typecolon \Nat) := \ScheduledBlockSubsidy(\BlockHeight) + \AdditionalBlockSubsidy(\BlockHeight)$ +} %nuseven + \vspace{1ex} \item $\FoundersReward(\BlockHeight \typecolon \Nat) := \begin{cases} \BlockSubsidy(\BlockHeight) \mult \FoundersFraction,&\caseif \Halving(\BlockHeight) < 1 \\ 0,&\caseotherwise \end{cases}$ + \vspace{0.5ex} \canopy { \vspace{0.5ex} + \needspace{14ex} \item for $\fs \in \FundingStreams$,\, $\fsValue(\BlockHeight) :=$ \vspace{-0.5ex} \item \tab $\begin{cases} @@ -15049,8 +15288,27 @@ \item $\MinerSubsidy(\BlockHeight) := \BlockSubsidy(\BlockHeight) - \FoundersReward(\BlockHeight) \canopy{\,- \ssum{\fs\, \in\, \FundingStreams}{} \fsValue(\BlockHeight)}$. +\nuseven{ + \vspace{1ex} + \item $\TransactionFees(\BlockHeight \typecolon \Nat) \typecolon \range{0}{\MAXMONEY} :=$ the total + value in \zatoshi of the \transactionFees paid by the non-coinbase \transactions in the + \block at \blockHeight $\BlockHeight$ + \vspace{0.5ex} + \item $\NSMFeeContribution(\BlockHeight \typecolon \Nat) := \floor{\hfrac{6 \mult \TransactionFees(\BlockHeight)}{10}}$ + \vspace{0.5ex} + \item $\MinerFees(\BlockHeight \typecolon \Nat) := \TransactionFees(\BlockHeight) - \NSMFeeContribution(\BlockHeight)$. +} %nuseven \end{formulae} +\nuseven{ +\vspace{-3ex} +\nnote{\cite{ZIP-235} writes $\NSMFeeContribution(\BlockHeight)$ as $6 \mult q + \floor{6 \mult r / 10}$, +with $q$ and $r$ the quotient and remainder of $\TransactionFees(\BlockHeight)$ divided by $10$. +That is equal to the definition above, and avoids forming $6 \mult \TransactionFees(\BlockHeight)$, +which can exceed $\MAXMONEY$ in an implementation whose amounts are bounded by it. $\NSMFeeContribution(\BlockHeight)$ +is removed from circulation into the NSM Value Balance defined in \crossref{chainvaluepoolbalances}.} +} %nuseven + \vspace{-2ex} \lsubsection{Payment of Founders' Reward}{foundersreward} @@ -15249,10 +15507,38 @@ \item $\HeightForHalving(\HalvingNum \typecolon \PosInt) := \minimum\Of{\setof{\BlockHeight \typecolon \Nat \suchthat \Halving(\BlockHeight) = \HalvingNum}}$ \item $\FSRecipientChangeInterval := \PostBlossomHalvingInterval / 48$ +\nuseven{ + \item $\PreNUSevenEquivalentHeight(\BlockHeight \typecolon \Nat) :=$ + \vspace{-0.5ex} + \item \tab $\begin{cases} + \BlockHeight,&\caseif \text{not } \IsNUSevenActivated(\BlockHeight) \\[1ex] + \NUSevenActivationHeight + \hfrac{\BlockHeight - \NUSevenActivationHeight}{\NUSevenPoWTargetSpacingRatio},&\caseotherwise + \end{cases}$ +} %nuseven +\notnuseven{ \item $\FSRecipientPeriod(\BlockHeight) := \floor{\hfrac{\BlockHeight - (\HeightForHalving(1) - \PostBlossomHalvingInterval)}{\FSRecipientChangeInterval}}$. +} %notnuseven +\notbeforenuseven{ + \item \nuseven{$\FSRecipientPeriod(\BlockHeight) :=$} + \vspace{-0.5ex} + \item \tab \nuseven{$\floor{\hfrac{\PreNUSevenEquivalentHeight(\BlockHeight) - (\HeightForHalving(1) - \PostBlossomHalvingInterval)}{\FSRecipientChangeInterval}}$.} +} %notbeforenuseven \end{formulae} +\nuseven{ +\pnote{$\PreNUSevenEquivalentHeight(\BlockHeight)$ is a rational number: the \blockHeight that the +\block at \blockHeight $\BlockHeight$ would have if the \blocks from \NUSeven activation onward had +been mined at the pre-\NUSeven \blockTargetSpacing. Revision 2 of \cite{ZIP-207} writes the +\NUSeven case of $\FSRecipientPeriod$ as $\floor{\hfrac{R \mult (A + I - H_1) + \BlockHeight - A}{R \mult C}}$, +where $A$ is $\NUSevenActivationHeight$, $R$ is $\NUSevenPoWTargetSpacingRatio$, $C$ is +$\FSRecipientChangeInterval$, $I$ is $\PostBlossomHalvingInterval$, and $H_1$ is $\HeightForHalving(1)$. +Dividing its numerator and denominator by $R$ gives the definition above. This preserves the +recipient index at \NUSeven activation. The remaining \blocks of the period in which \NUSeven +activates are tripled in number, and each later period lasts $3 \mult \FSRecipientChangeInterval$ +\blocks, so that each period keeps approximately its previous duration and total value.} +} %nuseven + \introlist For each \fundingStream $\fs$, define: @@ -15263,9 +15549,12 @@ \end{formulae} $\fsRecipients$ \MUST be of length $\fsNumRecipients$. Each element of $\fsRecipients$ -\MUST represent either a \transparentPtoSHAddress as specified in \crossref{transparentaddrencoding}, -or a \Sapling \shieldedPaymentAddress as specified in \crossref{saplingpaymentaddrencoding}\nusix{, -or the identifier $\DeferredPoolRecipient$}. +\MUST represent either a \transparentPtoSHAddress\nuseven{ or \transparentPtoPKHAddress} as specified +in \crossref{transparentaddrencoding}, or a \Sapling \shieldedPaymentAddress as specified in +\crossref{saplingpaymentaddrencoding}\nuseven{, or a Unified Address \cite{ZIP-316} containing only +an \Orchard Receiver and no other Items}\nusix{, or the identifier $\DeferredPoolRecipient$}. +\nuseven{A Unified Address recipient identifier represents its \Orchard Receiver, which is paid by +an \IronwoodPoolAdj output as specified below.} A \fundingStream $\fs$ is ``active'' at \blockHeight $\BlockHeight$ when $\fsValue(\BlockHeight) > 0$, where $\fsValue$ is defined in \crossref{subsidies}. @@ -15299,6 +15588,15 @@ \defining{\xStandardRedeemScript} hashes are defined in \cite{ZIP-48} for \PtoSHMultisigAddresses, or \cite{Bitcoin-P2SH} for other \PtoSHAddresses. +\nuseven{ + \vspace{0.5ex} + \item The \defining{\prescribedWay} to pay a \transparentPtoPKHAddress is to use a script of + the form $\ScriptOP{DUP}$ $\ScriptOP{HASH160}$ $\fsPubKeyHash(\BlockHeight)\; + \ScriptOP{EQUALVERIFY}$ $\ScriptOP{CHECKSIG}$ as the $\scriptPubKey$, where + $\fsPubKeyHash(\BlockHeight)$ is the direct push of the $20$-byte public key hash in the + raw encoding (\crossref{transparentaddrencoding}) of the recipient address for + $\fsRecipient(\BlockHeight)$. No other script encoding satisfies this rule. +} %nuseven \vspace{0.5ex} \item The \defining{\prescribedWay} to pay a \SaplingOrOrchard \paymentAddress is defined in \cite{ZIP-213}, using the post-\NUHeartwood consensus rules in @@ -15329,8 +15627,9 @@ \SaplingAndOrchard \shieldedPaymentAddresses as recipients. \cite{ZIP-213} permits \shieldedOutputs of \coinbaseTransactions to such addresses.\nufive{ The recipient identifiers permitted above do not include \Orchard - \shieldedPaymentAddresses before Revision 2 of \cite{ZIP-207}. The \prescribedWay - to pay one is defined in anticipation of that revision.} + \shieldedPaymentAddresses before Revision 2 of \cite{ZIP-207}\nuseven{, which applies + from \NUSeven}.\notnuseven{ The \prescribedWay to pay one was already defined, in + anticipation of that revision.}} \end{pnotes} \vspace{-1ex} @@ -15420,8 +15719,8 @@ \item \begin{tabular}{|l|c|c|c|c|} \hline Stream & Numerator & Denominator & Start height & End height \\\hline\raisedstrut -\texttt{FS\_FPF\_ZCG\_H3}& $8$ & $100$ & $3146400$ & $4406400$ \\ -\texttt{FS\_CCF\_H3} & $12$ & $100$ & $3146400$ & $4406400$ \\\hline +\texttt{FS\_FPF\_ZCG\_H3}& $8$ & $100$ & $3146400$ & $\notnuseven{4406400}\nuseven{6132390}$ \\ +\texttt{FS\_CCF\_H3} & $12$ & $100$ & $3146400$ & $\notnuseven{4406400}\nuseven{6132390}$ \\\hline \end{tabular} \end{formulae} @@ -15431,10 +15730,20 @@ \item \begin{tabular}{|l|c|c|c|c|} \hline Stream & Numerator & Denominator & Start height & End height \\\hline\raisedstrut -\texttt{FS\_FPF\_ZCG\_H3}& $8$ & $100$ & $3536500$ & $4476000$ \\ -\texttt{FS\_CCF\_H3} & $12$ & $100$ & $3536500$ & $4476000$ \\\hline +\texttt{FS\_FPF\_ZCG\_H3}& $8$ & $100$ & $3536500$ & $\notnuseven{4476000}\nuseven{4497948}$ \\ +\texttt{FS\_CCF\_H3} & $12$ & $100$ & $3536500$ & $\notnuseven{4476000}\nuseven{4497948}$ \\\hline \end{tabular} \end{formulae} + +\nuseven{ +\vspace{1ex} +\cite{ZIP-214} Revision 3, which applies from \NUSeven activation, changes the end height of each +Revision 2 \fundingStream to $\HeightForHalving(3)$ under the \NUSeven definition of $\Halving$, +as shown above; before \NUSeven the end heights were $4406400$ on \Mainnet and $4476000$ on +\Testnet. It also changes the recipients of \texttt{FS\_FPF\_ZCG\_H3} on \Mainnet for the +recipient periods after the one that contains the last pre-\NUSeven \block, as specified in +\cite{ZIP-2008}. +} %nuseven } %nusixone @@ -16167,8 +16476,12 @@ David Campbell, Elena Giralt, Francisco Gindre, Joseph Van~Geffen, Josh Swihart, Kevin Gorham, Larry Ruane, Marshall Gaucher, Ryan Taylor, Sasha Meyer, Conrado Gouvêa, Aditya Bharadwaj, Andrew Arnott, Arya, Andrea Kobrlova, -Lukáš Korba, Honza Rychnovský, Schell Scivally, Julian Abraham, and no doubt -others. +Lukáš Korba, Honza Rychnovský, Schell Scivally, @Peacemonger, Nicolas Gailly, Danny Willems, +Jason McGee, Mark Henderson, Tomek Piotrowski, Mariusz Pilarek, Paul Dann, Dev Ojha, Evan Forbes, +Anna Rose, Jens Groth, Judah Caruso, Pablo Kogan, Vivek Arte, Daniel Benarroch, Aurelien Nicolas, +Alexey Koren, Antoine Rondelet, Constance Beguier, Georgios Konstantopoulos, Matt Luongo, +Alex Bornstein, @dontbeevil, @GGuy, @mistfpga, Gordon Mohr, Dimitris Apostolou, Gregory Maxwell, +Pieter Wuille, Julian Abraham, and no doubt others. We would also like to thank the designers and developers of \Bitcoin and \BitcoinCore. @@ -16196,6 +16509,8 @@ The 2019 Soundness vulnerability in \BCTV \cite{Gabizon2019} was found by Ariel Gabizon. +The 2026 \Orchard Action circuit soundness vulnerability was found by Taylor Hornby. + The design of \Sapling is primarily due to Matthew Green, Ian Miers, \nh{Daira-Emma} Hopwood, Sean Bowe, Jack Grigg, and Jack Gavigan. A potential attack linking \diversifiedPaymentAddresses, avoided in the adopted design, was @@ -16222,7 +16537,7 @@ Amit Sahai. We thank the organizers of the ZKProof standardization effort and workshops; -and also Anna Rose, Fredrik Harrysson, Terun Chitra, James Prestwich, +and also Anna Rose, Fredrik Harrysson, Tarun Chitra, James Prestwich, Josh Cincinnati, Tanya Karsou, Henrik Jose, Chris Ward, and others for their work on the Zero Knowledge Podcast, ZK Summits, and ZK Study Club. These efforts have enriched the zero knowledge community immeasurably. @@ -16242,7 +16557,7 @@ \xShieldedPool names are set in Raleway Italic, by Matt McInerney, Pablo Impallari, and Rodrigo Fuenzalida. The {\schoolbook New Century Schoolbook} font by URW Type Foundry, based on -Century Schoolbook designed by Morris Fuller, is used for \emph{italics}\!. +Century Schoolbook designed by Morris Fuller Benton, is used for \emph{italics}\!. Finally, we would like to thank the Internet Archive for their scan of Peter Newell's illustration of the Jubjub bird, from \cite{Carroll1902}. @@ -16251,6 +16566,83 @@ \intropart \lsection{Change History}{changehistory} +\historyentry{2026.9.0}{2026-11-06} + +\begin{itemize} +\nuseven{ + \item Describe \NUSeven as having activated on \Mainnet at \blockHeight $3543405$ in + \shortcrossref{networkupgrades}, give its \activationBlock hashes in + \shortcrossref{networks}, and add the consensus rule that \transactions \MUST use the + \NUSeven \consensusBranchID. + \item Apply the change described in \cite{ZIP-2003}: from \NUSeven, the + \transactionVersionNumber \MUST be $5$ or $6$ (\shortcrossref{txnconsensus}). + \item Apply the changes described in \cite{ZIP-218}: + \vspace{0.5ex} + \begin{itemize} + \item Add $\NUSevenActivationHeight$, $\PostNUSevenPoWTargetSpacing$, the averaging + window constants, and the shielded limit constants to \shortcrossref{constants} + and \shortcrossref{notation}. + \item In \shortcrossref{diffadjustment}, make $\PoWTargetSpacingFunc$ return $25$ + seconds from \NUSeven, make $\PoWAveragingWindow$ a function of \blockHeight that + returns $102$ from \NUSeven, define $\CombinedPoWTargetSpacingRatio$ and + $\PostNUSevenHalvingInterval$, and change the \Testnet minimum-difficulty + threshold to $18$ times the \blockTargetSpacing. + \item In \shortcrossref{subsidies}, define $\BlossomAdjustment$ and $\NUSevenAdjustment$, + and add the \NUSeven cases of $\Halving$ and $\BlockSubsidy$. + \item In \shortcrossref{blockheader}, add the per-pool limits and the global shielded + budget on the shielded components of the \transactions in a \block. + \end{itemize} + \vspace{-1.5ex} + \item Apply Revision 2 of \cite{ZIP-207}, \cite{ZIP-2008}, and Revision 3 of \cite{ZIP-214}: + \vspace{0.5ex} + \begin{itemize} + \item In \shortcrossref{fundingstreams}, add the \NUSeven case of $\FSRecipientPeriod$, + expressed through $\PreNUSevenEquivalentHeight$. + \item Permit transparent \PtoPKHAddresses and Unified Addresses containing only an + \Orchard Receiver as \fundingStream recipients, and define the \prescribedWay to + pay a \transparentPtoPKHAddress. + \item In \shortcrossref{zip214fundingstreams}, give the \NUSeven end heights of the + Revision 2 \fundingStreams, and note the \NUSeven change of recipients of + \texttt{FS\_FPF\_ZCG\_H3} on \Mainnet. + \end{itemize} + \vspace{-1.5ex} + \item Apply the changes described in \cite{ZIP-235}: define $\TransactionFees$, + $\NSMFeeContribution$, and $\MinerFees$ in \shortcrossref{subsidies}; from \NUSeven, the + \totalInputValue of a \coinbaseTransaction in \shortcrossref{txnconsensus} includes + $\MinerFees(\BlockHeight)$ in place of the \transactionFees, and \shortcrossref{transactions}, + \shortcrossref{subsidyconcepts}, and \shortcrossref{coinbasetransactions} say so. + \item Apply the changes described in \cite{ZIP-237}: + \vspace{0.5ex} + \begin{itemize} + \item Add $\LNTwoScaled$, $\InitialNSMValueBalance$, and $\NSMReissuanceHeight$ to + \shortcrossref{constants} and \shortcrossref{notation}. + \item In \shortcrossref{subsidies}, rename $\BlockSubsidy$ to $\ScheduledBlockSubsidy$. + \item In \shortcrossref{subsidies}, define $\HalvingIntervalFunc$, + $\BlockSubsidyFraction$, and $\AdditionalBlockSubsidy$, and redefine + $\BlockSubsidy$ as the sum of $\ScheduledBlockSubsidy$ and $\AdditionalBlockSubsidy$. + \item In \shortcrossref{chainvaluepoolbalances}, define $\NSMValueRemoved$ and the + NSM Value Balance, with the consensus rule that it \MUSTNOT become negative, and + note that the \SproutChainValuePool balance remains issued (\cite{ZIP-2003}). + \item In \shortcrossref{transactions}, say that the value left unclaimed by + \coinbaseTransactions before \NUSix is reissued, and in + \shortcrossref{subsidyconcepts} that the \blockSubsidy includes reissued value + from $\NSMReissuanceHeight$. + \end{itemize} + \vspace{-1.5ex} +} %nuseven + \item Add an acknowledgement to Taylor Hornby for finding the 2026 \Orchard Action + circuit soundness vulnerability. + \item Add acknowledgements to @Peacemonger, Nicolas Gailly, Danny Willems, Jason McGee, + Mark Henderson, Tomek Piotrowski, Mariusz Pilarek, Paul Dann, Dev Ojha, Evan Forbes, + Anna Rose, Jens Groth, Judah Caruso, Pablo Kogan, Vivek Arte, Daniel Benarroch, + Aurelien Nicolas, Alexey Koren, Antoine Rondelet, Constance Beguier, + Georgios Konstantopoulos, Matt Luongo, Alex Bornstein, @dontbeevil, @GGuy, @mistfpga, + Gordon Mohr, Dimitris Apostolou, Gregory Maxwell, and Pieter Wuille for discussions on + the Zcash protocol. + \item Correct the names of Tarun Chitra and Morris Fuller Benton in the Acknowledgements. +\end{itemize} + + \historyentry{2026.8.0}{2026-11-06} \begin{itemize}
protocol/zcash.bib +54 −0
@@ -1390,6 +1390,15 @@ @misc{ZIP-216 urldate={2021-02-25} } +@misc{ZIP-218, + presort={ZIP-0218}, + author={Dev Ojha and Evan Forbes}, + title={25-second Block Target Spacing}, + howpublished={Zcash Improvement Proposal 218. Created March~13, 2026.}, + url={https://zips.z.cash/zip-0218}, + urldate={2026-11-06} +} + @misc{ZIP-221, presort={ZIP-0221}, author={{Ying~Tong} Lai and James Prestwich and Georgios Konstantopoulos and Jack Grigg}, @@ -1435,6 +1444,15 @@ @misc{ZIP-229 urldate={2026-07-03} } +@misc{ZIP-235, + presort={ZIP-0235}, + author={Jason McGee and Zooko Wilcox and Mark Henderson and Tomek Piotrowski and Mariusz Pilarek and Paul Dann}, + title={Remove 60\% of Transaction Fees From Circulation}, + howpublished={Zcash Improvement Proposal 235. Created September~21, 2023.}, + url={https://zips.z.cash/zip-0235}, + urldate={2026-11-06} +} + @misc{ZIP-236, presort={ZIP-0236}, author={{Daira\nbh{}Emma} Hopwood}, @@ -1444,6 +1462,15 @@ @misc{ZIP-236 urldate={2024-09-24} } +@misc{ZIP-237, + presort={ZIP-0237}, + author={Judah Caruso and Jason McGee and Zooko Wilcox and Mark Henderson and Tomek Piotrowski and Mariusz Pilarek and Paul Dann}, + title={Network Sustainability Mechanism: Halving-Preserving Issuance}, + howpublished={Zcash Improvement Proposal 237. Created August~19, 2026.}, + url={https://zips.z.cash/zip-0237}, + urldate={2026-11-06} +} + @misc{ZIP-239, presort={ZIP-0239}, author={{Daira\nbh{}Emma} Hopwood and Jack Grigg}, @@ -1552,6 +1579,15 @@ @misc{ZIP-258 urldate={2026-06-16} } +@misc{ZIP-259, + presort={ZIP-0259}, + author={Dev Ojha}, + title={Deployment of the {NU7} Network Upgrade}, + howpublished={Zcash Improvement Proposal 259. Created September~15, 2026.}, + url={https://zips.z.cash/zip-0259}, + urldate={2026-11-06} +} + @misc{ZIP-271, presort={ZIP-0271}, author={Daira\nbh{}Emma Hopwood and Kris Nuttycombe and Jack Grigg}, @@ -1660,6 +1696,15 @@ @misc{ZIP-312 urldate={2026-09-06} } +@misc{ZIP-2003, + presort={ZIP-2003}, + author={Daira\nbh{}Emma Hopwood}, + title={Disallow version 4 transactions}, + howpublished={Zcash Improvement Proposal 2003. Created October~31, 2024.}, + url={https://zips.z.cash/zip-2003}, + urldate={2026-11-06} +} + @misc{ZIP-2005, presort={ZIP-2005}, author={Daira\nbh{}Emma Hopwood and Jack Grigg}, @@ -1678,6 +1723,15 @@ @misc{ZIP-2006 urldate={2026-07-03} } +@misc{ZIP-2008, + presort={ZIP-2008}, + author={Jack Grigg}, + title={Update to {FS\_FPF\_ZCG\_H3} address list}, + howpublished={Zcash Improvement Proposal 2008. Created September~24, 2026.}, + url={https://zips.z.cash/zip-2008}, + urldate={2026-11-06} +} + @misc{DigiByte-PoW, presort={DigiByte-PoW}, author={DigiByte Core Developers},
zips/zip-0207.rst +9 −0
@@ -237,6 +237,15 @@ period, its remaining block count is tripled; each subsequent period lasts retains approximately its previous wall-clock duration and funding amount, subject to per-block rounding. +(The protocol specification [#protocol-fundingstreams]_ expresses this through +$\mathsf{PreNU7EquivalentHeight}(\mathsf{height})$, the height that the block at +$\mathsf{height}$ would have if the blocks from NU7 activation onward had been +mined at the pre-NU7 target spacing: $\mathsf{height}$ if not +$\mathsf{IsNU7Activated}(\mathsf{height})$, and $A + (\mathsf{height} - A)/R$ +otherwise. Its $\mathsf{FSRecipientPeriod}$ applies the pre-NU7 formula to this +rational number in place of $\mathsf{height}$, which is equal to the definition +above after dividing the numerator and denominator of the second case by $R$.) + Below is a visual representation of how stream addresses align with funding periods:
zips/zip-0218.md +19 −8
@@ -379,23 +379,31 @@ consideration. ### Halving interval and block subsidy -Define: +In § 7.7.3 'Difficulty adjustment', define: +$$\mathsf{CombinedPoWTargetSpacingRatio} : \mathbb{N} := \mathsf{BlossomPoWTargetSpacingRatio} \cdot \mathsf{NU7PoWTargetSpacingRatio} = 6$$ $$\mathsf{PostNU7HalvingInterval} : \mathbb{N} := \lfloor \mathsf{PostBlossomHalvingInterval} \cdot \mathsf{NU7PoWTargetSpacingRatio} \rfloor = 5{,}040{,}000$$ -Redefine $\mathsf{Halving}$ as a function of type $\mathbb{N} \to \mathbb{N}$: +In § 7.8 'Calculating Block Subsidy, Funding Streams, Lockbox Disbursement, and +Founders' Reward' [^protocol-subsidies], define: + +$$\mathsf{BlossomAdjustment} : \mathbb{Q} := \dfrac{\mathsf{BlossomActivationHeight} - \mathsf{SlowStartShift}}{\mathsf{PreBlossomHalvingInterval}}$$ +$$\mathsf{NU7Adjustment} : \mathbb{Q} := \mathsf{BlossomAdjustment} + \dfrac{\mathsf{NU7ActivationHeight} - \mathsf{BlossomActivationHeight}}{\mathsf{PostBlossomHalvingInterval}}$$ + +$\mathsf{BlossomAdjustment}$ is the first term of the existing Blossom case of +$\mathsf{Halving}$, which is rewritten to use it. Redefine $\mathsf{Halving}$ as +a function of type $\mathbb{N} \to \mathbb{N}$: $$ \mathsf{Halving}(\mathsf{height}) := \begin{cases} 0, &\textsf{if } \mathsf{height} < \mathsf{SlowStartShift} \\\\[1.5ex] \left\lfloor \dfrac{\mathsf{height} - \mathsf{SlowStartShift}}{\mathsf{PreBlossomHalvingInterval}} \right\rfloor, &\textsf{if not } \mathsf{IsBlossomActivated}(\mathsf{height}) \\\\[1.5ex] - \left\lfloor \dfrac{\mathsf{BlossomActivationHeight} - \mathsf{SlowStartShift}}{\mathsf{PreBlossomHalvingInterval}} + \left\lfloor \mathsf{BlossomAdjustment} + \dfrac{\mathsf{height} - \mathsf{BlossomActivationHeight}}{\mathsf{PostBlossomHalvingInterval}} \right\rfloor, &\textsf{if } \mathsf{IsBlossomActivated}(\mathsf{height}) \textsf{ and not } \mathsf{IsNU7Activated}(\mathsf{height}) \\\\[1.5ex] - \left\lfloor \dfrac{\mathsf{BlossomActivationHeight} - \mathsf{SlowStartShift}}{\mathsf{PreBlossomHalvingInterval}} - + \dfrac{\mathsf{NU7ActivationHeight} - \mathsf{BlossomActivationHeight}}{\mathsf{PostBlossomHalvingInterval}} + \left\lfloor \mathsf{NU7Adjustment} + \dfrac{\mathsf{height} - \mathsf{NU7ActivationHeight}}{\mathsf{PostNU7HalvingInterval}} \right\rfloor, &\textsf{otherwise} \end{cases} @@ -412,8 +420,8 @@ $$ \mathsf{BlockSubsidy}(\mathsf{height}) := \begin{cases} \ldots &\text{(prior cases, with the Blossom case amended as above)} \\\\[1ex] - \mathsf{floor}\left(\dfrac{\mathsf{MaxBlockSubsidy}}{\mathsf{BlossomPoWTargetSpacingRatio} \cdot \mathsf{NU7PoWTargetSpacingRatio} \cdot 2^{\mathsf{Halving}(\mathsf{height})}}\right), - &\textsf{if } \mathsf{IsNU7Activated}(\mathsf{height}) + \mathsf{floor}\left(\dfrac{\mathsf{MaxBlockSubsidy}}{\mathsf{CombinedPoWTargetSpacingRatio} \cdot 2^{\mathsf{Halving}(\mathsf{height})}}\right), + &\textsf{otherwise} \end{cases} $$ @@ -512,7 +520,8 @@ fields specified in § 7.1 'Transaction Encoding and Consensus' by ZIP 229 [^zip-0229]. Each is taken as 0 for a transaction version that does not have the field. -For each block at height $\mathsf{height}$ where +In § 7.6 'Block Header Encoding and Consensus' [^protocol-blockheader], add a +consensus rule that for each block at height $\mathsf{height}$ where $\mathsf{IsNU7Activated}(\mathsf{height})$, the following limits MUST be satisfied: @@ -993,6 +1002,8 @@ consensus branch ID. [^protocol-txnconsensus]: [Zcash Protocol Specification, Version 2025.6.3. Section 7.1.2: Transaction Consensus Rules](protocol/protocol.pdf#txnconsensus) +[^protocol-blockheader]: [Zcash Protocol Specification, Version 2025.6.3. Section 7.6: Block Header Encoding and Consensus](protocol/protocol.pdf#blockheader) + [^protocol-subsidies]: [Zcash Protocol Specification, Version 2025.6.3. Section 7.8: Calculating Block Subsidy, Funding Streams, Lockbox Disbursement, and Founders' Reward](protocol/protocol.pdf#subsidies) [^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst)
zips/zip-0234.md +6 −0
@@ -16,6 +16,12 @@ License: BSD-2-Clause Discussions-To: <https://github.com/zcash/zips/issues/923> ``` +<div class="note"></div> + +This ZIP was replaced by ZIP 237 ("Network Sustainability Mechanism: +Halving-Preserving Issuance" [^zip-0237]), which Network Upgrade 7 deploys +instead. [^zip-0259] + # Terminology
zips/zip-0235.md +10 −0
@@ -143,6 +143,14 @@ $\mathsf{floor}(6 \cdot \mathsf{TransactionFees}(\mathsf{height}) / 10)$, but avoids multiplying the aggregate fee value by 6. It uses the aggregate fees of the block, not the fees of each transaction. +In § 7.8 ‘Calculating Block Subsidy, Funding Streams, Lockbox Disbursement, and +Founders' Reward’ [^protocol-subsidies], add the definitions of +$\mathsf{TransactionFees}$, $\mathsf{NSMFeeContribution}$, and +$\mathsf{MinerFees}$. The protocol specification defines +$\mathsf{NSMFeeContribution}(\mathsf{height})$ directly as +$\mathsf{floor}(6 \cdot \mathsf{TransactionFees}(\mathsf{height}) / 10)$, and +gives the form above in a non-normative note. + In § 7.1.2 ‘Transaction Consensus Rules’ [^protocol-txnconsensus], change the definition of the total input value of a coinbase transaction to: @@ -291,6 +299,8 @@ require the activation of ZIP 233 ("NSM: Removing Funds From Circulation" [^zip- [^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 2026.8.0 [NU6.3]. Section 7.8: Calculating Block Subsidy, Funding Streams, Lockbox Disbursement, and Founders' Reward](protocol/protocol.pdf#subsidies) + [^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) [^zip-0233]: [ZIP 233: Network Sustainability Mechanism: Removing Funds From Circulation](zip-0233.md)
zips/zip-0237.md +26 −22
@@ -146,7 +146,7 @@ satisfies the following requirements: 1. The issuance can be summarized into a reasonably simple explanation. 2. If the NSM Value Balance is zero, block subsidies are identical to the existing halving schedule. -3. From $\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT}$ onward, if the NSM Value Balance +3. From $\mathsf{NSM\_REISSUANCE\_HEIGHT}$ onward, if the NSM Value Balance is greater than 0, then the additional block subsidy must be non-zero, so that funds removed from circulation are eventually fully reissued. @@ -191,7 +191,7 @@ This is $4126 / 10\_000\_000\_000 = 0.0000004126$ with $\mathsf{PostBlossomHalvingInterval} = 1\_680\_000$, the value specified by ZIP 234 [^zip-0234], and $1375 / 10\_000\_000\_000$ with $\mathsf{PostNU7HalvingInterval} = 5\_040\_000$. Since -$\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT}$ is not before NU7 activation, only the latter +$\mathsf{NSM\_REISSUANCE\_HEIGHT}$ is not before NU7 activation, only the latter value is used by $\mathsf{AdditionalBlockSubsidy}$. See the BLOCK_SUBSIDY_FRACTION section below. @@ -222,10 +222,9 @@ value pool balances that a full node reports at that height. | Mainnet | 1,575,000,000,000,000 | 1,574,963,141,554,480 | | Testnet | 1,603,125,000,000,000 | 1,603,069,231,585,043 | -$\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT} ⦂ \mathbb{N} :=$ the height at which reissuance begins +$\mathsf{NSM\_REISSUANCE\_HEIGHT} ⦂ \mathbb{N} :=$ the height at which reissuance begins on the relevant network, calculated in [NSM reissuance height](#nsmreissuanceheight) -below. It is named $\mathsf{NSM\_REISSUANCE\_HEIGHT}$ in the NU7 deployment -ZIP [^zip-0259]. +below. ## NSM reissuance height @@ -241,7 +240,7 @@ through height $h$, excluding additional NSM subsidies and amounts removed from circulation. Let $H_3$ and $H_4$ be the first heights at which the ZIP 218 $\mathsf{Halving}$ function equals 3 and 4, respectively. -$\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT}$ SHALL be the first height $h$ with +$\mathsf{NSM\_REISSUANCE\_HEIGHT}$ SHALL be the first height $h$ with $\max(A, H_3 + 1) \leq h < H_4$ for which $$\mathsf{ceiling}\left(\frac{1375\,(\mathsf{MAX\_MONEY} - S_A(h - 1))}{10^{10}}\right) < B_A(h).$$ @@ -273,7 +272,7 @@ $R_0 = 262{,}499{,}975{,}638{,}334 - (A - H_2^{(75)})$ zatoshi. Consequently $\mathsf{ceiling}((R_0 - R_{\max})/b) = 2{,}807{,}273$ throughout the range. Including the one-block offset from $H_3$ to $h_0$ gives -$\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT} = H_3 + 2{,}807{,}274$: +$\mathsf{NSM\_REISSUANCE\_HEIGHT} = H_3 + 2{,}807{,}274$: | Network | Second halving | Third halving after NU7 | Reissuance height | |---------|---------------:|-------------------------:|------------------:| @@ -299,17 +298,19 @@ Add the following definition, where $\mathsf{NSMValueBalance}$ is as defined in § 4.17 ‘Chain Value Pool Balances’ [^protocol-chainvaluepoolbalances] below: $$\mathsf{AdditionalBlockSubsidy}(\mathsf{height} ⦂ \mathbb{N}) := \begin{cases} -0, & \text{if } \mathsf{height} < \mathsf{DEPLOYMENT\_BLOCK\_HEIGHT} \\ +0, & \text{if } \mathsf{height} < \mathsf{NSM\_REISSUANCE\_HEIGHT} \\ \mathsf{ceiling}(\mathsf{BLOCK\_SUBSIDY\_FRACTION}(\mathsf{height}) \cdot \mathsf{NSMValueBalance}(\mathsf{height} - 1)), & \text{otherwise} \end{cases}$$ Define $\mathsf{BlockSubsidy}(\mathsf{height})$ as: $\mathsf{BlockSubsidy}(\mathsf{height}) := \mathsf{ScheduledBlockSubsidy}(\mathsf{height}) + \mathsf{AdditionalBlockSubsidy}(\mathsf{height})$ -Add $\mathsf{LN2\_SCALED}$ and $\mathsf{INITIAL\_NSM\_VALUE\_BALANCE}$ to § 5.3 -‘Constants’ [^protocol-constants], and $\mathsf{HalvingInterval}$ and -$\mathsf{BLOCK\_SUBSIDY\_FRACTION}$, as given under Parameters above, to § 7.8. +Add $\mathsf{LN2\_SCALED}$, $\mathsf{INITIAL\_NSM\_VALUE\_BALANCE}$, and +$\mathsf{NSM\_REISSUANCE\_HEIGHT}$ to § 5.3 ‘Constants’ [^protocol-constants] +and to the list of integer constants in § 2 ‘Notation’ [^protocol-notation], +and $\mathsf{HalvingInterval}$ and $\mathsf{BLOCK\_SUBSIDY\_FRACTION}$, as given +under Parameters above, to § 7.8. All other uses of $\mathsf{BlockSubsidy}(\mathsf{height})$ in the protocol specification ($\mathsf{FoundersReward}$, $\mathsf{fsValue}$ and hence @@ -322,6 +323,9 @@ NSM Value Balance after block $\mathsf{height} - 1$, and not only on $\mathsf{height}$. In § 4.17 ‘Chain Value Pool Balances’ [^protocol-chainvaluepoolbalances], add +the definition of $\mathsf{NSMValueRemoved}(\mathsf{height})$ from +[Mechanisms for removal from circulation](#mechanismsforremovalfromcirculation) +above, which as of NU7 is $\mathsf{NSMFeeContribution}(\mathsf{height})$, and the following definition. Let $\mathsf{NU7ActivationHeight}$ be the NU7 activation height on the relevant network. [^zip-0259] @@ -347,17 +351,17 @@ Add the consensus rule: In § 3.10 ‘Block Subsidy, Funding Streams, and Founders' Reward’ [^protocol-subsidyconcepts], add: -> [NU7 onward] From $\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT}$, the block subsidy -> also includes value reissued from the NSM Value Balance (§ 4.17), and so -> depends on the NSM Value Balance after the preceding block as well as on the -> block height. +> [NU7 onward] From $\mathsf{NSM\_REISSUANCE\_HEIGHT}$, the block subsidy +> also includes value reissued from the NSM Value Balance defined in § 4.17 +> ‘Chain Value Pool Balances’, and so depends on the NSM Value Balance after +> the preceding block as well as on the block height. In § 3.4 ‘Transactions and Treestates’ [^protocol-transactions], where the remaining value in the transparent transaction value pool of coinbase transactions in blocks prior to NU6 is said to be destroyed, say instead that it is left unclaimed and is not added to any chain value pool, and add: -> [NU7 onward] This value is included in +> [NU7 onward] This unclaimed value is included in > $\mathsf{INITIAL\_NSM\_VALUE\_BALANCE}$, and so is reissued as specified in > § 7.8. @@ -372,11 +376,11 @@ All of these changes apply identically to Mainnet and Testnet. function only to the NSM Value Balance satisfies **Requirements 1**, **2** and **4** above. * No reissuance occurs between NU7 activation and - $\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT}$, so the NSM Value Balance accumulates + $\mathsf{NSM\_REISSUANCE\_HEIGHT}$, so the NSM Value Balance accumulates during that interval. The reissuance height is chosen as described in [NSM reissuance height](#nsmreissuanceheight) and ZIP 259 [^zip-0259]. * We round up to the next zatoshi to satisfy **Requirement 3** above from - $\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT}$ onward. Since + $\mathsf{NSM\_REISSUANCE\_HEIGHT}$ onward. Since $\mathsf{BLOCK\_SUBSIDY\_FRACTION} < 1$ and the NSM Value Balance is a non-negative integer number of zatoshi, the additional subsidy never exceeds the balance it is calculated from, so from NU7 activation the sum of the @@ -402,8 +406,8 @@ Balance at that point ($\mathsf{INITIAL\_NSM\_VALUE\_BALANCE}$ plus anything removed from circulation since NU7 activation) at $\mathsf{BLOCK\_SUBSIDY\_FRACTION}$ per block. For example, if a total of 100,000 ZEC were removed from circulation between NU7 activation and -$\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT}$, then at -$\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT}$ the issuance would be larger than the +$\mathsf{NSM\_REISSUANCE\_HEIGHT}$, then at +$\mathsf{NSM\_REISSUANCE\_HEIGHT}$ the issuance would be larger than the Scheduled Block Subsidy by $100\_000\textsf{ ZEC} \cdot \mathsf{BLOCK\_SUBSIDY\_FRACTION}$, which equals $0.01375$ ZEC under the post-NU7 schedule. This example is chosen to demonstrate @@ -437,7 +441,7 @@ approximation within $\pm 0.003\%$. ZIP 218 [^zip-0218] does not change $\mathsf{PostBlossomHalvingInterval}$; it defines a separate $\mathsf{PostNU7HalvingInterval} = 5\_040\_000$ for its 25-second blocks, and with that interval the numerator is 1375, which is the value applied from -$\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT}$: $(1 - 1375/10^{10})^{5\_040\_000} \approx 0.50007$, +$\mathsf{NSM\_REISSUANCE\_HEIGHT}$: $(1 - 1375/10^{10})^{5\_040\_000} \approx 0.50007$, within $+0.015\%$. A numerator fixed at 4126 would instead halve the balance about every 1.33 years under ZIP 218, because it would apply three times as often. @@ -476,7 +480,7 @@ constraint. This ZIP is proposed to activate with Network Upgrade 7 [^zip-0259], with reissuance beginning at -$\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT}$. It MUST NOT be deployed together with +$\mathsf{NSM\_REISSUANCE\_HEIGHT}$. It MUST NOT be deployed together with ZIP 234. [^zip-0234] It does not depend on ZIP 233 ("NSM: Removing Funds From Circulation" [^zip-0233]): funds removed from circulation by ZIP 233, or by any other mechanism, are credited to the NSM Value Balance if and when that
zips/zip-0259.md +2 −2
@@ -119,8 +119,8 @@ NSM_REISSUANCE_HEIGHT : Testnet: 7305222 : Mainnet: 8939664 -Each NSM_REISSUANCE_HEIGHT is $\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT}$ for the -corresponding network, as calculated in ZIP 237 [^zip-0237]. The Testnet +Each NSM_REISSUANCE_HEIGHT is as calculated in ZIP 237 [^zip-0237] for the +corresponding network. The Testnet ACTIVATION_HEIGHT (NU7) $A = 4{,}465{,}026$ lies between the second and third pre-NU7 Testnet halvings (2,796,000 and 4,476,000). The ZIP 218 third halving is therefore at $H_3 = 13{,}428{,}000 - 2A = 4{,}497{,}948$, and the Testnet
zips/zip-2008.md +15 −5
@@ -67,11 +67,19 @@ In "References" [^zip-0207], add: ## Changes to the Zcash Protocol Specification -In § 7.10 'Payment of Funding Streams, Deferred Lockbox, and Lockbox Disbursement', -from NU7 activation, extend the permitted funding-stream recipient types to -include transparent P2PKH addresses. Add the P2PKH prescribed payment rule above -alongside the existing P2SH and shielded payment rules. The amount and distinct -output requirements are unchanged. +In § 7.10 'Payment of Funding Streams, Deferred Lockbox, and Lockbox Disbursement' +[^protocol-fundingstreams], from NU7 activation, extend the permitted +funding-stream recipient types to include transparent P2PKH addresses, and add +the following alongside the existing P2SH and shielded prescribed ways: + +> The prescribed way to pay a transparent P2PKH address is to use a script of +> the form `OP_DUP OP_HASH160 fs.PubKeyHash(height) OP_EQUALVERIFY OP_CHECKSIG` +> as the `scriptPubKey`, where $\mathsf{fs.PubKeyHash}(\mathsf{height})$ is the +> direct push of the 20-byte public key hash in the raw encoding of the +> recipient address for $\mathsf{fs.Recipient}(\mathsf{height})$. No other +> script encoding satisfies this rule. + +The amount and distinct output requirements are unchanged. ## Changes to ZIP 214 @@ -166,6 +174,8 @@ This ZIP is proposed to be deployed with NU7 [^zip-0259]. [^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-fundingstreams]: [Zcash Protocol Specification, Version 2026.8.0 [NU6.3]. Section 7.10: Payment of Funding Streams, Deferred Lockbox, and Lockbox Disbursement](protocol/protocol.pdf#fundingstreams) + [^zip-0207]: [ZIP 207: Funding Streams](zip-0207.rst) [^zip-0214]: [ZIP 214: Consensus rules for a Zcash Development Fund](zip-0214.rst)