diff --git a/protocol/Makefile b/protocol/Makefile index 7bff76ba..6052bf74 100644 --- a/protocol/Makefile +++ b/protocol/Makefile @@ -57,7 +57,7 @@ auxblossom: $(LATEXMK) -jobname=blossom -auxdir=aux -outdir=aux protocol .PHONY: blossom -sapling: +blossom: $(MAKE) auxblossom mv -f aux/blossom.pdf . diff --git a/protocol/protocol.tex b/protocol/protocol.tex index 431a8318..f909c07c 100644 --- a/protocol/protocol.tex +++ b/protocol/protocol.tex @@ -1238,16 +1238,30 @@ electronic commerce and payment, financial privacy, proof of work, zero knowledg \newcommand{\BlockSubsidy}{\mathsf{BlockSubsidy}} \newcommand{\MinerSubsidy}{\mathsf{MinerSubsidy}} \newcommand{\FoundersReward}{\mathsf{FoundersReward}} +\newcommand{\FundingStreamFund}[1]{\mathsf{FundingStream}_{#1}} +\newcommand{\FundingStreamFraction}[1]{\FundingStreamFund{#1}\mathsf{.Fraction}} +\newcommand{\FundingStreamStartHeight}[1]{\FundingStreamFund{#1}\mathsf{.StartHeight}} +\newcommand{\FundingStreamEndHeight}[1]{\FundingStreamFund{#1}\mathsf{.EndHeight}} +\newcommand{\FundingStreamValue}[1]{\FundingStreamFund{#1}\mathsf{.Value}} +\newcommand{\FundingStreamAddressList}[1]{\FundingStreamFund{#1}\mathsf{.AddressList}} +\newcommand{\FundingStreamAddressIndex}[1]{\FundingStreamFund{#1}\mathsf{.AddressIndex}} +\newcommand{\FundingStreamNumAddresses}[1]{\FundingStreamFund{#1}\mathsf{.NumAddresses}} +\newcommand{\MaxFundingStreams}{\mathsf{MaxFundingStreams}} \newcommand{\SlowStartInterval}{\mathsf{SlowStartInterval}} \newcommand{\SlowStartShift}{\mathsf{SlowStartShift}} \newcommand{\SlowStartRate}{\mathsf{SlowStartRate}} -\newcommand{\HalvingInterval}{\mathsf{HalvingInterval}} +\newcommand{\PreBlossomHalvingInterval}{\mathsf{\notbeforeblossom{PreBlossom}HalvingInterval}} +\newcommand{\PostBlossomHalvingInterval}{\mathsf{PostBlossomHalvingInterval}} \newcommand{\MaxBlockSubsidy}{\mathsf{MaxBlockSubsidy}} \newcommand{\NumFounderAddresses}{\mathsf{NumFounderAddresses}} \newcommand{\FounderAddressChangeInterval}{\mathsf{FounderAddressChangeInterval}} \newcommand{\FoundersFraction}{\mathsf{FoundersFraction}} +\newcommand{\FundingStreamAddressChangeInterval}{\mathsf{FundingStreamAddressChangeInterval}} +\newcommand{\FundingStreamAddressPeriod}{\mathsf{FundingStreamAddressPeriod}} \newcommand{\BlockHeight}{\mathsf{height}} \newcommand{\Halving}{\mathsf{Halving}} +\newcommand{\HalvingNum}{\mathsf{halving}} +\newcommand{\HeightForHalving}{\mathsf{HeightForHalving}} \newcommand{\FounderAddress}{\mathsf{FounderAddress}} \newcommand{\FounderAddressList}{\mathsf{FounderAddressList}} \newcommand{\FounderAddressIndex}{\mathsf{FounderAddressIndex}} @@ -1255,17 +1269,24 @@ electronic commerce and payment, financial privacy, proof of work, zero knowledg \newcommand{\blockSubsidy}{\term{block subsidy}} \newcommand{\minerSubsidy}{\term{miner subsidy}} +\newcommand{\fundingStream}{\term{funding stream}} +\newcommand{\fundingStreams}{\term{funding streams}} \newcommand{\foundersReward}{\term{Founders' Reward}} \newcommand{\slowStartPeriod}{\term{slow-start period}} \newcommand{\halvingInterval}{\term{halving interval}} +\newcommand{\BlossomActivationHeight}{\mathsf{BlossomActivationHeight}} +\newcommand{\IsBlossomActivated}{\mathsf{IsBlossomActivated}} \newcommand{\PoWLimit}{\mathsf{PoWLimit}} \newcommand{\PoWAveragingWindow}{\mathsf{PoWAveragingWindow}} \newcommand{\PoWMedianBlockSpan}{\mathsf{PoWMedianBlockSpan}} \newcommand{\PoWMaxAdjustDown}{\mathsf{PoWMaxAdjustDown}} \newcommand{\PoWMaxAdjustUp}{\mathsf{PoWMaxAdjustUp}} \newcommand{\PoWDampingFactor}{\mathsf{PoWDampingFactor}} -\newcommand{\PoWTargetSpacing}{\mathsf{PoWTargetSpacing}} +\newcommand{\PreBlossomPoWTargetSpacing}{\mathsf{\notbeforeblossom{PreBlossom}PoWTargetSpacing}} +\newcommand{\PostBlossomPoWTargetSpacing}{\mathsf{PostBlossomPoWTargetSpacing}} +\newcommand{\BlossomPoWTargetSpacingRatio}{\mathsf{BlossomPoWTargetSpacingRatio}} +\newcommand{\PoWTargetSpacingFunc}{\mathsf{PoWTargetSpacing}} \newcommand{\MeanTarget}{\mathsf{MeanTarget}} \newcommand{\MedianTime}{\mathsf{MedianTime}} \newcommand{\AveragingWindowTimespan}{\mathsf{AveragingWindowTimespan}} @@ -1732,6 +1753,8 @@ electronic commerce and payment, financial privacy, proof of work, zero knowledg \newcommand{\overwinteronlyitem}[1]{\overwinter{\item {[\Overwinter only, pre-\Sapling\!]}\, {#1}}} \newcommand{\overwinteronwarditem}[1]{\overwinter{\item {[\Overwinter onward]}\, {#1}}} \newcommand{\sproutspecific}[1]{\notsprout{[\Sprout\!]\,} {#1}} +\newcommand{\preblossom}[1]{\notbeforeblossom{[Pre-\Blossom\!]\,} {#1}} +\newcommand{\blossomonward}[1]{\blossom{[\Blossom onward]\, {#1}}} \newcommand{\presapling}[1]{\notsprout{[Pre-\Sapling\!]\,} {#1}} \newcommand{\saplingonward}[1]{\sapling{[\Sapling onward]\, {#1}}} \newcommand{\preoverwinter}[1]{\notsprout{[Pre-\Overwinter\!]\,} {#1}} @@ -2245,9 +2268,10 @@ The following integer constants will be instantiated in \crossref{constants}: $\NoteCommitRandLength$, \changed{$\RandomSeedLength$,} $\AuthPrivateLength$, \changed{$\NoteAddressPreRandLength$,}\sapling{ $\SpendingKeyLength$, $\DiversifierLength$, $\InViewingKeyLength$, $\OutViewingKeyLength$, $\ScalarLength$,} - $\MAXMONEY$, $\SlowStartInterval$, $\HalvingInterval$, $\MaxBlockSubsidy$, + $\MAXMONEY$, $\SlowStartInterval$, $\PreBlossomHalvingInterval$, \blossom{$\PostBlossomHalvingInterval$,} + $\MaxBlockSubsidy$, $\NumFounderAddresses$, $\PoWLimit$, $\PoWAveragingWindow$, $\PoWMedianBlockSpan$, - $\PoWDampingFactor$, and $\PoWTargetSpacing$. + $\PoWDampingFactor$, \notblossom{and }$\PreBlossomPoWTargetSpacing$\blossom{, and $\PostBlossomPoWTargetSpacing$}. \end{flushleft} \end{formulae} @@ -2760,24 +2784,34 @@ considered disjoint, even if they have the same bit pattern.} } -\subsection{Block Subsidy and Founders' Reward} \label{subsidyconcepts} +\subsection{Block Subsidy\blossom{, Funding Streams,} and Founders' Reward} \label{subsidyconcepts} Like \Bitcoin, \Zcash creates currency when \blocks are mined. The value created on -mining a \block is called the \blockSubsidy. It is composed of a \minerSubsidy and a -\foundersReward. As in \Bitcoin, the miner of a \block also receives \transactionFees. +mining a \block is called the \blockSubsidy. -The calculations of the \blockSubsidy, \minerSubsidy, and \foundersReward depend on -the \blockHeight, as defined in \crossref{blockchain}. +\preblossom{The \blockSubsidy is composed of a \minerSubsidy and a \foundersReward.} -These calculations are described in \crossref{subsidies}. +\blossomonward{The \blockSubsidy is composed of a \minerSubsidy and a series of \fundingStreams. +The \fundingStreams introduced in the Blossom upgrade correspond exactly to the \foundersReward.} + +As in \Bitcoin, the miner of a \block also receives \transactionFees. + +The calculations of the \blockSubsidy, \minerSubsidy,\blossom{ \fundingStreams,} and \foundersReward +depend on the \blockHeight, as defined in \crossref{blockchain}. These calculations are described in \\ +\crossref{subsidies}. -\subsection{\CoinbaseTransactions} +\subsection{\CoinbaseTransactions} \label{coinbasetransactions} The first (and only the first) \transaction in a block is a \coinbaseTransaction, which collects and spends any \minerSubsidy and \transactionFees paid by \transactions -included in this \block. The \coinbaseTransaction{} \MUST also pay the \foundersReward -as described in \crossref{foundersreward}. +included in this \block. + +\preblossom{The \coinbaseTransaction{} \MUST also pay the \foundersReward as described in \\ +\crossref{foundersreward}.} + +\blossomonward{The \coinbaseTransaction \MUST also pay the \fundingStreams as described in \\ +\crossref{fundingstreams}.} \intropart @@ -5583,11 +5617,17 @@ Define: \item $\UncommittedSapling \typecolon \bitseq{\MerkleHashLengthSapling} := \ItoLEBSPOf{\MerkleHashLengthSapling}{1}$ } %sapling \item $\MAXMONEY \typecolon \Nat := \changed{2.1 \smult 10^{15}}$ (\zatoshi) +\blossom{ + \item $\BlossomActivationHeight \typecolon \Nat := 640000$ +} %blossom \item $\SlowStartInterval \typecolon \Nat := 20000$ - \item $\HalvingInterval \typecolon \Nat := 840000$ + \item $\PreBlossomHalvingInterval \typecolon \Nat := 840000$ \item $\MaxBlockSubsidy \typecolon \Nat := 1.25 \smult 10^9$ (\zatoshi) \item $\NumFounderAddresses \typecolon \Nat := 48$ \item $\FoundersFraction \typecolon \Rat := \frac{1}{5}$ +\blossom{ + \item $\MaxFundingStreams \typecolon \Nat := 8$ +} %blossom \item $\PoWLimit \typecolon \Nat := \begin{cases} 2^{243} - 1,&\squash\text{for the production network} \\ 2^{251} - 1,&\squash\text{for the test network} @@ -5597,7 +5637,10 @@ Define: \item $\PoWMaxAdjustDown \typecolon \Rat := \frac{32}{100}$ \item $\PoWMaxAdjustUp \typecolon \Rat := \frac{16}{100}$ \item $\PoWDampingFactor \typecolon \Nat := 4$ - \item $\PoWTargetSpacing \typecolon \Nat := 150$ (seconds). + \item $\PreBlossomPoWTargetSpacing \typecolon \Nat := 150$ (seconds). +\blossom{ + \item $\PostBlossomPoWTargetSpacing \typecolon \Nat := 75$ (seconds). +} %blossom \end{formulae} @@ -8956,8 +8999,10 @@ with simplifications and altered parameters, to adjust difficulty to target the desired 2.5-minute block time. Unlike \Bitcoin, the difficulty adjustment occurs after every block. -The constants $\PoWLimit$, $\PoWAveragingWindow$, $\PoWMaxAdjustDown$, $\PoWMaxAdjustUp$, -$\PoWDampingFactor$, and $\PoWTargetSpacing$ are instantiated in \crossref{constants}. +\notbeforeblossom{The constants }$\PoWLimit$, $\PreBlossomHalvingInterval$, $\PoWAveragingWindow$, +$\PoWMaxAdjustDown$, $\PoWMaxAdjustUp$, $\PoWDampingFactor$,\notblossom{ and} +$\PreBlossomPoWTargetSpacing$\blossom{, and $\PostBlossomPoWTargetSpacing$} +are specified in section \crossref{constants}. Let $\ToCompact$ and $\ToTarget$ be as defined in \crossref{nbits}. @@ -8982,15 +9027,26 @@ Define: \floor{x},&\caseif x \geq 0 \\ -\floor{-x},&\caseotherwise \end{cases}$ +\blossom{ + \item $\IsBlossomActivated(\BlockHeight) := (\BlockHeight \geq \BlossomActivationHeight)$ + \item $\BlossomPoWTargetSpacingRatio := \hfrac{\PreBlossomPoWTargetSpacing}{\PostBlossomPoWTargetSpacing}$ + \item $\PostBlossomHalvingInterval := \floor{\PreBlossomHalvingInterval \mult \BlossomPoWTargetSpacingRatio}$ + \item $\PoWTargetSpacingFunc(\BlockHeight) := \begin{cases} + \PreBlossomPoWTargetSpacing,&\caseif \text{not } \IsBlossomActivated(\BlockHeight) \\ + \PostBlossomPoWTargetSpacing,&\caseotherwise + \end{cases}$ +} %blossom - \item $\AveragingWindowTimespan := \PoWAveragingWindow \mult \PoWTargetSpacing$ - \item $\MinActualTimespan := \floor{\AveragingWindowTimespan \mult (1 - \PoWMaxAdjustUp)}$ - \item $\MaxActualTimespan := \floor{\AveragingWindowTimespan \mult (1 + \PoWMaxAdjustDown)}$ + \item $\AveragingWindowTimespan\blossom{(\BlockHeight)} := \PoWAveragingWindow \mult \PoWTargetSpacingFunc\blossom{(\BlockHeight)}$ + \item $\MinActualTimespan\blossom{(\BlockHeight)} := \floor{\AveragingWindowTimespan\blossom{(\BlockHeight)} \mult (1 - \PoWMaxAdjustUp)}$ + \item $\MaxActualTimespan\blossom{(\BlockHeight)} := \floor{\AveragingWindowTimespan\blossom{(\BlockHeight)} \mult (1 + \PoWMaxAdjustDown)}$ \item $\MedianTime(\BlockHeight) := \median(\listcomp{\nTime(i) \for i \from \maximum(0, \BlockHeight - \PoWMedianBlockSpan) \upto \BlockHeight - 1})$ \item $\ActualTimespan(\BlockHeight) := \MedianTime(\BlockHeight) - \MedianTime(\BlockHeight - \PoWAveragingWindow)$ - \item $\ActualTimespanDamped(\BlockHeight) := \AveragingWindowTimespan + \trunc{\scalebox{0.98}{\hfrac{\ActualTimespan(\BlockHeight) - \AveragingWindowTimespan}{\PoWDampingFactor}}}$ - \item $\ActualTimespanBounded(\BlockHeight) := \bound{\MinActualTimespan}{\MaxActualTimespan}(\ActualTimespanDamped(\BlockHeight))$ + \item $\ActualTimespanDamped(\BlockHeight) :=$ + \vspace{-0.5ex} + \item \tab $\AveragingWindowTimespan\blossom{(\BlockHeight)} + \trunc{\scalebox{0.98}{\hfrac{\ActualTimespan(\BlockHeight) - \AveragingWindowTimespan\blossom{(\BlockHeight)}}{\PoWDampingFactor}}}$ + \item $\ActualTimespanBounded(\BlockHeight) := \bound{\MinActualTimespan\blossom{(\BlockHeight)}}{\MaxActualTimespan\blossom{(\BlockHeight)}}(\ActualTimespanDamped(\BlockHeight))$ \item $\MeanTarget(\BlockHeight) := \begin{cases} \PoWLimit, \hspace{16em}\text{if } \BlockHeight \leq \PoWAveragingWindow \\ \mean(\listcomp{\ToTarget(\nBits(i)) \for i \from \BlockHeight - \PoWAveragingWindow \upto \BlockHeight - 1}),\\ @@ -9056,29 +9112,63 @@ in its \blockHeader is defined as $\floor{\hfrac{2^{256}}{\ToTarget(\nBits) + 1} \introlist -\subsection{Calculation of Block Subsidy and Founders' Reward} \label{subsidies} +\subsection{Calculation of Block Subsidy\blossom{, Funding Streams,} and Founders' Reward} \label{subsidies} -\crossref{subsidyconcepts} defines the \blockSubsidy, \minerSubsidy, and \foundersReward. -Their amounts in \zatoshi are calculated from the \blockHeight using -the formulae below. The constants $\SlowStartInterval$, $\HalvingInterval$, -$\MaxBlockSubsidy$, and $\FoundersFraction$ are instantiated in \crossref{constants}. +\crossref{subsidyconcepts} defines the \blockSubsidy, \minerSubsidy,\blossom{ \fundingStreams,} and +\foundersReward. Their amounts in \zatoshi are calculated from the \blockHeight using +the formulae below.\notbeforeblossom{ +}The constants $\SlowStartInterval$, $\MaxBlockSubsidy$, $\FoundersFraction$,\notblossom{ and} $\PreBlossomHalvingInterval$, +\blossom{$\MaxFundingStreams$, $\PostBlossomHalvingInterval$, and $\BlossomActivationHeight$} are instantiated in \crossref{constants}. +\blossom{The per \fundingStream constants $\FundingStreamFraction{i}$, $\FundingStreamStartHeight{i}$, +and $\FundingStreamEndHeight{i}$ are instantiated in \crossref{fundingstreams}.} + +\vspace{1ex} \begin{formulae} \item $\SlowStartShift \typecolon \Nat := \hfrac{\SlowStartInterval}{2}$ \item $\SlowStartRate \typecolon \Nat := \hfrac{\MaxBlockSubsidy}{\SlowStartInterval}$ - \item $\Halving(\BlockHeight) := \floor{\hfrac{\BlockHeight - \SlowStartShift}{\HalvingInterval}}$ + \vspace{0.5ex} + \item $\Halving(\BlockHeight) := \notblossom{\floor{\hfrac{\BlockHeight - \SlowStartShift}{\PreBlossomHalvingInterval}}} + \notbeforeblossom{\begin{cases} + \floor{\hfrac{\BlockHeight - \SlowStartShift}{\PreBlossomHalvingInterval}},\hspace{1em}\blossom{\caseif \text{not } \IsBlossomActivated(\BlockHeight)} \\[1.4ex] + \blossom{\floor{\hfrac{\BlossomActivationHeight - \SlowStartShift}{\PreBlossomHalvingInterval} + \hfrac{\BlockHeight - \BlossomActivationHeight}{\PostBlossomHalvingInterval}},}&\blossom{\caseotherwise} + \end{cases}}$ + \vspace{0.5ex} \item $\BlockSubsidy(\BlockHeight) := \begin{cases} \SlowStartRate \mult \BlockHeight,&\caseif \BlockHeight < \hfrac{\SlowStartInterval}{2} \\[1.4ex] - \SlowStartRate \mult (\BlockHeight + 1),&\caseif \hfrac{\SlowStartInterval}{2} \leq \BlockHeight < \SlowStartInterval \\[1.4ex] - \floor{\hfrac{\MaxBlockSubsidy}{2^{\Halving(\BlockHeight)}}},&\caseotherwise + \SlowStartRate \mult (\BlockHeight + 1),&\caseif \hfrac{\SlowStartInterval}{2} \leq \BlockHeight \\[1.4ex] + &\text{ and } \BlockHeight < \SlowStartInterval \\[1.4ex] + \floor{\hfrac{\MaxBlockSubsidy}{2^{\Halving(\BlockHeight)}}},&\notblossom{\caseotherwise}\notbeforeblossom{\caseif \SlowStartInterval \leq \BlockHeight} \\ +\notbeforeblossom { + &\blossom{\text{ and not } \IsBlossomActivated(\BlockHeight}) \\[1.4ex] + \blossom{\floor{\hfrac{\MaxBlockSubsidy}{\BlossomPoWTargetSpacingRatio \mult 2^{\Halving(\BlockHeight)}}},}&\blossom{\caseotherwise} +} %notbeforeblossom \end{cases}$ +\blossom { + \vspace{0.5ex} + \item $\FundingStreamValue{i}(\BlockHeight) :=$ + \vspace{-0.5ex} + \item \tab $\begin{cases} + 0,&\caseif \BlockHeight < \BlossomActivationHeight \\ + \floor{\BlockSubsidy(\BlockHeight) \mult \FundingStreamFraction{i}},&\caseif \FundingStreamStartHeight{i} \leq \BlockHeight \\ + &\text{ and } \BlockHeight < \FundingStreamEndHeight{i} \\ + 0,&\caseotherwise + \end{cases}$ +} %blossom + \item $\FoundersReward(\BlockHeight) := \begin{cases} - \BlockSubsidy(\BlockHeight) \mult \FoundersFraction,&\caseif \BlockHeight < \SlowStartShift + \HalvingInterval \\ + \BlockSubsidy(\BlockHeight) \mult \FoundersFraction,&\caseif \Halving(\BlockHeight) = 0 \\ +\notbeforeblossom { + &\blossom{\text{ and } \BlockHeight < \BlossomActivationHeight} \\ +} %notbeforeblossom 0,&\caseotherwise \end{cases}$ - \item $\MinerSubsidy(\BlockHeight) := \BlockSubsidy(\BlockHeight) - \FoundersReward(\BlockHeight)$. + \item $\MinerSubsidy(\BlockHeight) :=$ + \vspace{-1.5ex} + \item \tab $\BlockSubsidy(\BlockHeight) - \FoundersReward(\BlockHeight) + \blossom{\,- \ssum{i = 1}{\MaxFundingStreams} \FundingStreamValue{i}(\BlockHeight)}$. \end{formulae} \introsection @@ -9168,33 +9258,418 @@ Let $\SlowStartShift$ be defined as in the previous section. Define: \begin{formulae} - \item $\FounderAddressChangeInterval := \ceiling{\hfrac{\SlowStartShift + \HalvingInterval}{\NumFounderAddresses}}$ + \item $\FounderAddressChangeInterval := \ceiling{\hfrac{\SlowStartShift + \PreBlossomHalvingInterval}{\NumFounderAddresses}}$ \item $\FounderAddressIndex(\BlockHeight) := 1 + \floor{\hfrac{\BlockHeight}{\FounderAddressChangeInterval}}$. \end{formulae} Let $\RedeemScriptHash(\BlockHeight)$ be the standard redeem script hash, as defined in -\cite{Bitcoin-Multisig}, for the P2SH multisig address with Base58Check representation +\cite{Bitcoin-Multisig}, for the P2SH multisig address with Base58Check form given by $\FounderAddressList_{\,\FounderAddressIndex(\BlockHeight)}$. \consensusrule{ -A \coinbaseTransaction for \blockHeight $\BlockHeight \in \range{1}{\SlowStartShift + \HalvingInterval - 1}$ +A \coinbaseTransaction for \blockHeight $\BlockHeight \in \range{1}{\notblossom{\SlowStartShift + \PreBlossomHalvingInterval}\blossom{\BlossomActivationHeight} - 1}$ \MUST include at least one output that pays exactly $\FoundersReward(\BlockHeight)$ \zatoshi with a standard P2SH script of the form \ScriptOP{HASH160} \;$\RedeemScriptHash(\BlockHeight)$\; \ScriptOP{EQUAL} as its $\scriptPubKey$. } \begin{pnotes} - \item No \foundersReward is required to be paid for $\BlockHeight \geq \SlowStartShift + \HalvingInterval$ - (i.e.\ after the first halving), or for $\BlockHeight = 0$ (i.e.\ the \genesisBlock). + \item No \foundersReward is required to be paid for $\BlockHeight \geq$ + \notblossom{$\SlowStartShift + \PreBlossomHalvingInterval$ + (i.e.\ after the first halving)}\blossom{$\BlossomActivationHeight$}, + or for $\BlockHeight = 0$ (i.e.\ the \genesisBlock). \item The \foundersReward addresses are not treated specially in any other way, and there can be other outputs to them, in \coinbaseTransactions or otherwise. In particular, it is valid for a \coinbaseTransaction with - $\BlockHeight \in \range{1}{\SlowStartShift + \HalvingInterval - 1}$ to have + $\BlockHeight \in \range{1}{\SlowStartShift + \PreBlossomHalvingInterval - 1}$ to have other outputs, possibly to the same address, that do not meet the criterion in the above consensus rule, as long as at least one output meets it. \end{pnotes} +\blossom{ +\subsection{Payment of Funding Streams} \label{fundingstreams} + +The \fundingStreams are paid by \transparent outputs in the \coinbaseTransaction, to +one of a pre-defined set of \transparent addresses, depending on the \blockHeight. + +The $i$th \fundingStream is defined by three constants: + +\begin{formulae} + \item $\FundingStreamFraction{i} \typecolon \Rat$ + \item $\FundingStreamStartHeight{i} \typecolon \Nat$ + \item $\FundingStreamEndHeight{i} \typecolon \Nat$. +\end{formulae} + +Define $\HeightForHalving(\HalvingNum)$ so that $\HeightForHalving(\HalvingNum) = \BlockHeight$ +where $\BlockHeight$ is the least \blockHeight such that $\Halving(\BlockHeight) = \HalvingNum$. + +Define: + +\begin{formulae} + \item $\FundingStreamAddressChangeInterval := \PostBlossomHalvingInterval / 48$ + \item $\FundingStreamAddressPeriod(\BlockHeight) := + \floor{\hfrac{\BlockHeight - (\HeightForHalving(1) - \PostBlossomHalvingInterval)}{\FundingStreamAddressChangeInterval}}$ + \item $\FundingStreamAddressIndex{i}(\BlockHeight) :=$ + \vspace{-0.5ex} + \item \tab $1 + \FundingStreamAddressPeriod(\BlockHeight) - \FundingStreamAddressPeriod(\FundingStreamStartHeight{i})$. +\end{formulae} + +The number of \transparent addresses per \fundingStream is therefore: + +\begin{formulae} + \item $\FundingStreamNumAddresses{i} := \FundingStreamAddressIndex{i}(\FundingStreamEndHeight{i})$. +\end{formulae} + +Let $\FundingStreamAddressList{i}_j$ be the $j$th address for the $i$th \fundingStream. +Each address representation in $\FundingStreamAddressList{i}_{\oneto{\FundingStreamNumAddresses{i}}}$ +denotes a \transparent P2SH multisig address. + +Let $\RedeemScriptHash_i(\BlockHeight)$ be the standard redeem script hash, as defined in +\cite{Bitcoin-Multisig}, for the P2SH multisig address with Base58Check form +given by $\FundingStreamAddressList{i}_{\,\FundingStreamAddressIndex{i}(\BlockHeight)}$. + +Recall from \crossref{subsidies} the definition of $\FundingStreamValue{i}$. + +\consensusrule{ +In each \coinbaseTransaction for \blockHeight $\BlockHeight$, for every +$i \in \range{1}{\MaxFundingStreams}$ such that $\FundingStreamValue{i}(\BlockHeight) \neq 0$, +the \transaction{} \MUST include at least one output that pays exactly +$\FundingStreamValue{i}(\BlockHeight)$ \zatoshi with a standard P2SH script +of the form \ScriptOP{HASH160} \;$\RedeemScriptHash_i(\BlockHeight)$\; \ScriptOP{EQUAL} +as its $\scriptPubKey$. +} + +\begin{pnotes} + \item The \fundingStream addresses are not treated specially in any other way, and + there can be other outputs to them, in \coinbaseTransactions or otherwise. + In particular, it is valid for a \coinbaseTransaction to have + other outputs, possibly to the same address, that do not meet the criterion + in the above consensus rule, as long as at least one output meets it. +\end{pnotes} + +\subsubsection{ZIP 207 Funding Streams} \label{zip207fundingstreams} + +\cite{ZIP-207} defined eight \fundingStreams. They are reproduced below. + +\renewcommand{\arraystretch}{1} + +\introsection +\subsubsubsection{Funding Stream 1} \label{zip207fundingstream1} + +\begin{formulae} + \item $\FundingStreamFraction{1} := \frac{3}{40}$ + \item $\FundingStreamStartHeight{1} := \BlossomActivationHeight$ + \item $\FundingStreamEndHeight{1} := \HeightForHalving(1)$. +\end{formulae} + +\vspace{1ex} +\introlist +For the production network, $\FundingStreamAddressList{1}_{\oneto{\FundingStreamNumAddresses{1}}}$ is: + +\scalebox{0.95}{ +\begin{tabular}{@{\hskip 2.5em}l@{\;}l} +[& \ascii{tFS1INVALIDADDRESS00}, \ascii{tFS1INVALIDADDRESS01}, \\ + & \ascii{tFS1INVALIDADDRESS02}, \ascii{tFS1INVALIDADDRESS03}, \\ + & \ascii{tFS1INVALIDADDRESS04}, \ascii{tFS1INVALIDADDRESS05}, \\ + & \ascii{tFS1INVALIDADDRESS06}, \ascii{tFS1INVALIDADDRESS07}, \\ + & \ascii{tFS1INVALIDADDRESS08}, \ascii{tFS1INVALIDADDRESS09}, \\ + & \ascii{tFS1INVALIDADDRESS10}, \ascii{tFS1INVALIDADDRESS11}\, ] +\end{tabular} +} %scalebox + +\vspace{1ex} +\introlist +For the test network, $\FundingStreamAddressList{1}_{\oneto{\FundingStreamNumAddresses{1}}}$ is: + +\scalebox{0.96}{ +\begin{tabular}{@{\hskip 2.5em}l@{\;}l} +[& \ascii{tFS1INVALIDADDRESS00}, \ascii{tFS1INVALIDADDRESS01}, \\ + & \ascii{tFS1INVALIDADDRESS02}, \ascii{tFS1INVALIDADDRESS03}, \\ + & \ascii{tFS1INVALIDADDRESS04}, \ascii{tFS1INVALIDADDRESS05}, \\ + & \ascii{tFS1INVALIDADDRESS06}, \ascii{tFS1INVALIDADDRESS07}, \\ + & \ascii{tFS1INVALIDADDRESS08}, \ascii{tFS1INVALIDADDRESS09}, \\ + & \ascii{tFS1INVALIDADDRESS10}, \ascii{tFS1INVALIDADDRESS11}\, ] +\end{tabular} +} %scalebox + +\introsection +\subsubsubsection{Funding Stream 2} \label{zip207fundingstream2} + +\begin{formulae} + \item $\FundingStreamFraction{2} := \frac{1}{25}$ + \item $\FundingStreamStartHeight{2} := \BlossomActivationHeight$ + \item $\FundingStreamEndHeight{2} := \HeightForHalving(1)$. +\end{formulae} + +\vspace{1ex} +\introlist +For the production network, $\FundingStreamAddressList{2}_{\oneto{\FundingStreamNumAddresses{2}}}$ is: + +\scalebox{0.95}{ +\begin{tabular}{@{\hskip 2.5em}l@{\;}l} +[& \ascii{tFS2INVALIDADDRESS00}, \ascii{tFS2INVALIDADDRESS01}, \\ + & \ascii{tFS2INVALIDADDRESS02}, \ascii{tFS2INVALIDADDRESS03}, \\ + & \ascii{tFS2INVALIDADDRESS04}, \ascii{tFS2INVALIDADDRESS05}, \\ + & \ascii{tFS2INVALIDADDRESS06}, \ascii{tFS2INVALIDADDRESS07}, \\ + & \ascii{tFS2INVALIDADDRESS08}, \ascii{tFS2INVALIDADDRESS09}, \\ + & \ascii{tFS2INVALIDADDRESS10}, \ascii{tFS2INVALIDADDRESS11}\, ] +\end{tabular} +} %scalebox + +\vspace{1ex} +\introlist +For the test network, $\FundingStreamAddressList{2}_{\oneto{\FundingStreamNumAddresses{2}}}$ is: + +\scalebox{0.96}{ +\begin{tabular}{@{\hskip 2.5em}l@{\;}l} +[& \ascii{tFS2INVALIDADDRESS00}, \ascii{tFS2INVALIDADDRESS01}, \\ + & \ascii{tFS2INVALIDADDRESS02}, \ascii{tFS2INVALIDADDRESS03}, \\ + & \ascii{tFS2INVALIDADDRESS04}, \ascii{tFS2INVALIDADDRESS05}, \\ + & \ascii{tFS2INVALIDADDRESS06}, \ascii{tFS2INVALIDADDRESS07}, \\ + & \ascii{tFS2INVALIDADDRESS08}, \ascii{tFS2INVALIDADDRESS09}, \\ + & \ascii{tFS2INVALIDADDRESS10}, \ascii{tFS2INVALIDADDRESS11}\, ] +\end{tabular} +} %scalebox + +\introsection +\subsubsubsection{Funding Stream 3} \label{zip207fundingstream3} + +\begin{formulae} + \item $\FundingStreamFraction{3} := \frac{1}{40}$ + \item $\FundingStreamStartHeight{3} := \BlossomActivationHeight$ + \item $\FundingStreamEndHeight{3} := \HeightForHalving(1)$. +\end{formulae} + +\vspace{1ex} +\introlist +For the production network, $\FundingStreamAddressList{3}_{\oneto{\FundingStreamNumAddresses{3}}}$ is: + +\scalebox{0.95}{ +\begin{tabular}{@{\hskip 2.5em}l@{\;}l} +[& \ascii{tFS3INVALIDADDRESS00}, \ascii{tFS3INVALIDADDRESS01}, \\ + & \ascii{tFS3INVALIDADDRESS02}, \ascii{tFS3INVALIDADDRESS03}, \\ + & \ascii{tFS3INVALIDADDRESS04}, \ascii{tFS3INVALIDADDRESS05}, \\ + & \ascii{tFS3INVALIDADDRESS06}, \ascii{tFS3INVALIDADDRESS07}, \\ + & \ascii{tFS3INVALIDADDRESS08}, \ascii{tFS3INVALIDADDRESS09}, \\ + & \ascii{tFS3INVALIDADDRESS10}, \ascii{tFS3INVALIDADDRESS11}\, ] +\end{tabular} +} %scalebox + +\vspace{1ex} +\introlist +For the test network, $\FundingStreamAddressList{3}_{\oneto{\FundingStreamNumAddresses{3}}}$ is: + +\scalebox{0.96}{ +\begin{tabular}{@{\hskip 2.5em}l@{\;}l} +[& \ascii{tFS3INVALIDADDRESS00}, \ascii{tFS3INVALIDADDRESS01}, \\ + & \ascii{tFS3INVALIDADDRESS02}, \ascii{tFS3INVALIDADDRESS03}, \\ + & \ascii{tFS3INVALIDADDRESS04}, \ascii{tFS3INVALIDADDRESS05}, \\ + & \ascii{tFS3INVALIDADDRESS06}, \ascii{tFS3INVALIDADDRESS07}, \\ + & \ascii{tFS3INVALIDADDRESS08}, \ascii{tFS3INVALIDADDRESS09}, \\ + & \ascii{tFS3INVALIDADDRESS10}, \ascii{tFS3INVALIDADDRESS11}\, ] +\end{tabular} +} %scalebox + +\introsection +\subsubsubsection{Funding Stream 4} \label{zip207fundingstream4} + +\begin{formulae} + \item $\FundingStreamFraction{4} := \frac{1}{50}$ + \item $\FundingStreamStartHeight{4} := \BlossomActivationHeight$ + \item $\FundingStreamEndHeight{4} := \HeightForHalving(1)$. +\end{formulae} + +\vspace{1ex} +\introlist +For the production network, $\FundingStreamAddressList{4}_{\oneto{\FundingStreamNumAddresses{4}}}$ is: + +\scalebox{0.95}{ +\begin{tabular}{@{\hskip 2.5em}l@{\;}l} +[& \ascii{tFS4INVALIDADDRESS00}, \ascii{tFS4INVALIDADDRESS01}, \\ + & \ascii{tFS4INVALIDADDRESS02}, \ascii{tFS4INVALIDADDRESS03}, \\ + & \ascii{tFS4INVALIDADDRESS04}, \ascii{tFS4INVALIDADDRESS05}, \\ + & \ascii{tFS4INVALIDADDRESS06}, \ascii{tFS4INVALIDADDRESS07}, \\ + & \ascii{tFS4INVALIDADDRESS08}, \ascii{tFS4INVALIDADDRESS09}, \\ + & \ascii{tFS4INVALIDADDRESS10}, \ascii{tFS4INVALIDADDRESS11}\, ] +\end{tabular} +} %scalebox + +\vspace{1ex} +\introlist +For the test network, $\FundingStreamAddressList{4}_{\oneto{\FundingStreamNumAddresses{4}}}$ is: + +\scalebox{0.96}{ +\begin{tabular}{@{\hskip 2.5em}l@{\;}l} +[& \ascii{tFS4INVALIDADDRESS00}, \ascii{tFS4INVALIDADDRESS01}, \\ + & \ascii{tFS4INVALIDADDRESS02}, \ascii{tFS4INVALIDADDRESS03}, \\ + & \ascii{tFS4INVALIDADDRESS04}, \ascii{tFS4INVALIDADDRESS05}, \\ + & \ascii{tFS4INVALIDADDRESS06}, \ascii{tFS4INVALIDADDRESS07}, \\ + & \ascii{tFS4INVALIDADDRESS08}, \ascii{tFS4INVALIDADDRESS09}, \\ + & \ascii{tFS4INVALIDADDRESS10}, \ascii{tFS4INVALIDADDRESS11}\, ] +\end{tabular} +} %scalebox + +\introsection +\subsubsubsection{Funding Stream 5} \label{zip207fundingstream5} + +\begin{formulae} + \item $\FundingStreamFraction{5} := \frac{1}{80}$ + \item $\FundingStreamStartHeight{5} := \BlossomActivationHeight$ + \item $\FundingStreamEndHeight{5} := \HeightForHalving(1)$. +\end{formulae} + +\vspace{1ex} +\introlist +For the production network, $\FundingStreamAddressList{5}_{\oneto{\FundingStreamNumAddresses{5}}}$ is: + +\scalebox{0.95}{ +\begin{tabular}{@{\hskip 2.5em}l@{\;}l} +[& \ascii{tFS5INVALIDADDRESS00}, \ascii{tFS5INVALIDADDRESS01}, \\ + & \ascii{tFS5INVALIDADDRESS02}, \ascii{tFS5INVALIDADDRESS03}, \\ + & \ascii{tFS5INVALIDADDRESS04}, \ascii{tFS5INVALIDADDRESS05}, \\ + & \ascii{tFS5INVALIDADDRESS06}, \ascii{tFS5INVALIDADDRESS07}, \\ + & \ascii{tFS5INVALIDADDRESS08}, \ascii{tFS5INVALIDADDRESS09}, \\ + & \ascii{tFS5INVALIDADDRESS10}, \ascii{tFS5INVALIDADDRESS11}\, ] +\end{tabular} +} %scalebox + +\vspace{1ex} +\introlist +For the test network, $\FundingStreamAddressList{5}_{\oneto{\FundingStreamNumAddresses{5}}}$ is: + +\scalebox{0.96}{ +\begin{tabular}{@{\hskip 2.5em}l@{\;}l} +[& \ascii{tFS5INVALIDADDRESS00}, \ascii{tFS5INVALIDADDRESS01}, \\ + & \ascii{tFS5INVALIDADDRESS02}, \ascii{tFS5INVALIDADDRESS03}, \\ + & \ascii{tFS5INVALIDADDRESS04}, \ascii{tFS5INVALIDADDRESS05}, \\ + & \ascii{tFS5INVALIDADDRESS06}, \ascii{tFS5INVALIDADDRESS07}, \\ + & \ascii{tFS5INVALIDADDRESS08}, \ascii{tFS5INVALIDADDRESS09}, \\ + & \ascii{tFS5INVALIDADDRESS10}, \ascii{tFS5INVALIDADDRESS11}\, ] +\end{tabular} +} %scalebox + +\introsection +\subsubsubsection{Funding Stream 6} \label{zip207fundingstream6} + +\begin{formulae} + \item $\FundingStreamFraction{6} := \frac{1}{80}$ + \item $\FundingStreamStartHeight{6} := \BlossomActivationHeight$ + \item $\FundingStreamEndHeight{6} := \HeightForHalving(1)$. +\end{formulae} + +\vspace{1ex} +\introlist +For the production network, $\FundingStreamAddressList{6}_{\oneto{\FundingStreamNumAddresses{6}}}$ is: + +\scalebox{0.95}{ +\begin{tabular}{@{\hskip 2.5em}l@{\;}l} +[& \ascii{tFS6INVALIDADDRESS00}, \ascii{tFS6INVALIDADDRESS01}, \\ + & \ascii{tFS6INVALIDADDRESS02}, \ascii{tFS6INVALIDADDRESS03}, \\ + & \ascii{tFS6INVALIDADDRESS04}, \ascii{tFS6INVALIDADDRESS05}, \\ + & \ascii{tFS6INVALIDADDRESS06}, \ascii{tFS6INVALIDADDRESS07}, \\ + & \ascii{tFS6INVALIDADDRESS08}, \ascii{tFS6INVALIDADDRESS09}, \\ + & \ascii{tFS6INVALIDADDRESS10}, \ascii{tFS6INVALIDADDRESS11}\, ] +\end{tabular} +} %scalebox + +\vspace{1ex} +\introlist +For the test network, $\FundingStreamAddressList{6}_{\oneto{\FundingStreamNumAddresses{6}}}$ is: + +\scalebox{0.96}{ +\begin{tabular}{@{\hskip 2.5em}l@{\;}l} +[& \ascii{tFS6INVALIDADDRESS00}, \ascii{tFS6INVALIDADDRESS01}, \\ + & \ascii{tFS6INVALIDADDRESS02}, \ascii{tFS6INVALIDADDRESS03}, \\ + & \ascii{tFS6INVALIDADDRESS04}, \ascii{tFS6INVALIDADDRESS05}, \\ + & \ascii{tFS6INVALIDADDRESS06}, \ascii{tFS6INVALIDADDRESS07}, \\ + & \ascii{tFS6INVALIDADDRESS08}, \ascii{tFS6INVALIDADDRESS09}, \\ + & \ascii{tFS6INVALIDADDRESS10}, \ascii{tFS6INVALIDADDRESS11}\, ] +\end{tabular} +} %scalebox + +\introsection +\subsubsubsection{Funding Stream 7} \label{zip207fundingstream7} + +\begin{formulae} + \item $\FundingStreamFraction{7} := \frac{1}{100}$ + \item $\FundingStreamStartHeight{7} := \BlossomActivationHeight$ + \item $\FundingStreamEndHeight{7} := \HeightForHalving(1)$. +\end{formulae} + +\vspace{1ex} +\introlist +For the production network, $\FundingStreamAddressList{7}_{\oneto{\FundingStreamNumAddresses{7}}}$ is: + +\scalebox{0.95}{ +\begin{tabular}{@{\hskip 2.5em}l@{\;}l} +[& \ascii{tFS7INVALIDADDRESS00}, \ascii{tFS7INVALIDADDRESS01}, \\ + & \ascii{tFS7INVALIDADDRESS02}, \ascii{tFS7INVALIDADDRESS03}, \\ + & \ascii{tFS7INVALIDADDRESS04}, \ascii{tFS7INVALIDADDRESS05}, \\ + & \ascii{tFS7INVALIDADDRESS06}, \ascii{tFS7INVALIDADDRESS07}, \\ + & \ascii{tFS7INVALIDADDRESS08}, \ascii{tFS7INVALIDADDRESS09}, \\ + & \ascii{tFS7INVALIDADDRESS10}, \ascii{tFS7INVALIDADDRESS11}\, ] +\end{tabular} +} %scalebox + +\vspace{1ex} +\introlist +For the test network, $\FundingStreamAddressList{7}_{\oneto{\FundingStreamNumAddresses{7}}}$ is: + +\scalebox{0.96}{ +\begin{tabular}{@{\hskip 2.5em}l@{\;}l} +[& \ascii{tFS7INVALIDADDRESS00}, \ascii{tFS7INVALIDADDRESS01}, \\ + & \ascii{tFS7INVALIDADDRESS02}, \ascii{tFS7INVALIDADDRESS03}, \\ + & \ascii{tFS7INVALIDADDRESS04}, \ascii{tFS7INVALIDADDRESS05}, \\ + & \ascii{tFS7INVALIDADDRESS06}, \ascii{tFS7INVALIDADDRESS07}, \\ + & \ascii{tFS7INVALIDADDRESS08}, \ascii{tFS7INVALIDADDRESS09}, \\ + & \ascii{tFS7INVALIDADDRESS10}, \ascii{tFS7INVALIDADDRESS11}\, ] +\end{tabular} +} %scalebox + +\introsection +\subsubsubsection{Funding Stream 8} \label{zip207fundingstream8} + +\begin{formulae} + \item $\FundingStreamFraction{8} := \frac{1}{200}$ + \item $\FundingStreamStartHeight{8} := \BlossomActivationHeight$ + \item $\FundingStreamEndHeight{8} := \HeightForHalving(1)$. +\end{formulae} + +\vspace{1ex} +\introlist +For the production network, $\FundingStreamAddressList{8}_{\oneto{\FundingStreamNumAddresses{8}}}$ is: + +\scalebox{0.95}{ +\begin{tabular}{@{\hskip 2.5em}l@{\;}l} +[& \ascii{tFS8INVALIDADDRESS00}, \ascii{tFS8INVALIDADDRESS01}, \\ + & \ascii{tFS8INVALIDADDRESS02}, \ascii{tFS8INVALIDADDRESS03}, \\ + & \ascii{tFS8INVALIDADDRESS04}, \ascii{tFS8INVALIDADDRESS05}, \\ + & \ascii{tFS8INVALIDADDRESS06}, \ascii{tFS8INVALIDADDRESS07}, \\ + & \ascii{tFS8INVALIDADDRESS08}, \ascii{tFS8INVALIDADDRESS09}, \\ + & \ascii{tFS8INVALIDADDRESS10}, \ascii{tFS8INVALIDADDRESS11}\, ] +\end{tabular} +} %scalebox + +\vspace{1ex} +\introlist +For the test network, $\FundingStreamAddressList{8}_{\oneto{\FundingStreamNumAddresses{8}}}$ is: + +\scalebox{0.96}{ +\begin{tabular}{@{\hskip 2.5em}l@{\;}l} +[& \ascii{tFS8INVALIDADDRESS00}, \ascii{tFS8INVALIDADDRESS01}, \\ + & \ascii{tFS8INVALIDADDRESS02}, \ascii{tFS8INVALIDADDRESS03}, \\ + & \ascii{tFS8INVALIDADDRESS04}, \ascii{tFS8INVALIDADDRESS05}, \\ + & \ascii{tFS8INVALIDADDRESS06}, \ascii{tFS8INVALIDADDRESS07}, \\ + & \ascii{tFS8INVALIDADDRESS08}, \ascii{tFS8INVALIDADDRESS09}, \\ + & \ascii{tFS8INVALIDADDRESS10}, \ascii{tFS8INVALIDADDRESS11}\, ] +\end{tabular} +} %scalebox + +\renewcommand{\arraystretch}{\defaultarraystretch} +} %blossom + + \subsection{Changes to the Script System} \label{scripts} The \ScriptOP{CODESEPARATOR} opcode has been disabled. This opcode also no longer @@ -9866,6 +10341,32 @@ Peter Newell's illustration of the Jubjub bird, from \cite{Carroll1902}. \section{Change History} +\subparagraph{2019.0-beta-38} +2019-02-23 + +\begin{itemize} + \item No changes to \Sprout. +\sapling{ + \item No changes to \Sapling. +} +\blossom{ + \item Update the following sections to match the current draft of \cite{ZIP-208}: + \begin{itemize} + \item \crossref{diffadjustment} + \item \crossref{subsidies} + \end{itemize} + \item Specify \fundingStreams, along with the draft \fundingStreams defined + in the current draft of \cite{ZIP-207}. + \item Update the following sections to match the current draft of \cite{ZIP-207}: + \begin{itemize} + \item \crossref{subsidyconcepts} + \item \crossref{coinbasetransactions} + \item \crossref{subsidies} + \item \crossref{foundersreward} + \end{itemize} +} +\end{itemize} + \subparagraph{2019.0-beta-37} 2019-02-22 diff --git a/protocol/zcash.bib b/protocol/zcash.bib index 889d02f8..1afbd545 100644 --- a/protocol/zcash.bib +++ b/protocol/zcash.bib @@ -872,6 +872,24 @@ Last revised February~5, 2018.} urldate={2019-02-08} } +@misc{ZIP-207, + presort={ZIP-0207}, + author={Jack Grigg}, + title={Split Founders' Reward}, + howpublished={Zcash Improvement Proposal 207. Created January~4, 2019.}, + url={https://github.com/zcash/zips/blob/master/zip-0207.rst}, + urldate={2019-02-23} +} + +@misc{ZIP-208, + presort={ZIP-0208}, + author={Simon Liu and Daira Hopwood}, + title={Shorter Block Target Spacing}, + howpublished={Zcash Improvement Proposal 208. Created January~10, 2019.}, + url={https://github.com/zcash/zips/blob/master/zip-0208.rst}, + urldate={2019-02-23} +} + @misc{ZIP-243, presort={ZIP-0243}, author={Jack Grigg and Daira Hopwood},