The key words "MUST", "MUST NOT", "SHOULD", "RECOMMENDED", and "MAY" in this document are to be interpreted as described in BCP 14 1 when, and only when, they appear in all capitals.
The term "network upgrade" in this document is to be interpreted as described in ZIP 200 7.
-
The terms "Orchard" and "Action" in this document are to be interpreted as described in ZIP 224 8.
+
The terms "Orchard" and "Action" in this document are to be interpreted as described in ZIP 224 9.
We define the following additional terms:
Asset: A type of note that can be transferred on the Zcash blockchain. Each Asset is identified by an Asset Identifier Specification: Asset Identifier.
@@ -43,10 +43,10 @@
Abstract
-
This ZIP (ZIP 227) proposes the Zcash Shielded Assets (ZSA) protocol, in conjunction with ZIP 226 9. This protocol is an extension of the Orchard protocol that enables the creation, transfer and burn of Custom Assets on the Zcash chain. The creation of such Assets is defined in this ZIP (ZIP 227), while the transfer and burn of such Assets is defined in ZIP 226 9. This ZIP must only be implemented in conjunction with ZIP 226 9. The proposed issuance mechanism is only valid for the Orchard-ZSA transfer protocol, because it produces notes that can only be transferred under ZSA.
+
This ZIP (ZIP 227) proposes the Zcash Shielded Assets (ZSA) protocol, in conjunction with ZIP 226 10. This protocol is an extension of the Orchard protocol that enables the creation, transfer and burn of Custom Assets on the Zcash chain. The creation of such Assets is defined in this ZIP (ZIP 227), while the transfer and burn of such Assets is defined in ZIP 226 10. This ZIP must only be implemented in conjunction with ZIP 226 10. The proposed issuance mechanism is only valid for the Orchard-ZSA transfer protocol, because it produces notes that can only be transferred under ZSA.
Motivation
-
This ZIP introduces the issuance mechanism for Custom Assets on the Zcash chain. While originally part of a single ZSA ZIP, the issuance mechanism turned out to be substantial enough to stand on its own and justify the creation of this supporting ZIP for ZIP 226 9.
+
This ZIP introduces the issuance mechanism for Custom Assets on the Zcash chain. While originally part of a single ZSA ZIP, the issuance mechanism turned out to be substantial enough to stand on its own and justify the creation of this supporting ZIP for ZIP 226 10.
This ZIP only enables transparent issuance. As a first step, transparency will allow for proper testing of the applications that will be most used in the Zcash ecosystem, and will enable the supply of Assets to be tracked.
The issuance mechanism described in this ZIP is broad enough for issuers to either create Assets on Zcash (i.e. Assets that originate on the Zcash blockchain), as well as for institutions to create bridges from other chains and import Wrapped Assets. This enables what we hope will be a useful set of applications.
@@ -73,7 +73,7 @@
Specification: Issuance Keys and Issuance Authorization Signature Scheme
-
The Orchard-ZSA Protocol adds the following keys to the key components 1819:
+
The Orchard-ZSA Protocol adds the following keys to the key components 1920:
The issuance authorizing key, denoted as
\(\mathsf{isk}\!\)
@@ -90,7 +90,7 @@
Issuance Authorization Signature Scheme
We instantiate the issuance authorization signature scheme
\(\mathsf{IssueAuthSig}\)
- as a BIP-340 Schnorr signature over the secp256k1 curve. The signing and validation algorithms, signature encoding, and public key encoding MUST follow BIP 340 16.
+ as a BIP-340 Schnorr signature over the secp256k1 curve. The signing and validation algorithms, signature encoding, and public key encoding MUST follow BIP 340 17.
Batch verification MAY be used. Precomputation MAY be used if and only if it produces equivalent results; for example, for a given verification key
\(pk\)
and
@@ -120,7 +120,7 @@
\(k\)
bytes, and
\(\mathbb{B}^{\mathbb{Y}^{[\mathbb{N}]}}\)
- denotes the type of byte sequences of arbitrary length, as defined in the Zcash protocol specification 17.
+ denotes the type of byte sequences of arbitrary length, as defined in the Zcash protocol specification 18.
The issuance authorizing key generation algorithm and the issuance validating key derivation algorithm are defined in the Issuance Key Derivation section, while the corresponding signing and validation algorithms are defined in the Issuance Authorization Signing and Validation section.
Issuance Key Derivation
@@ -184,7 +184,7 @@
where the
\(\textit{PubKey}\)
- algorithm is defined in BIP 340 16. Note that the byte representation of
+ algorithm is defined in BIP 340 17. Note that the byte representation of
\(\mathsf{ik}\)
is in big-endian order as defined in BIP 340.
It is possible for the
@@ -222,7 +222,7 @@
\(\mathsf{Sign}\)
algorithm is defined in BIP 340 and
\(a\)
- denotes the auxiliary data used in BIP 340 16. Note that
+ denotes the auxiliary data used in BIP 340 17. Note that
\(\mathsf{IssueAuthSig}.\!\mathsf{Sign}\)
could return
\(\bot\)
@@ -246,7 +246,7 @@
where the
\(\mathsf{Verify}\)
- algorithm is defined in BIP 340 16.
@@ -291,7 +291,7 @@
\(\mathsf{ZSAValueBase}(\mathsf{AssetDigest_{AssetId}}) := \mathsf{GroupHash}^\mathbb{P}(\texttt{"z.cash:OrchardZSA"}, \mathsf{AssetDigest_{AssetId}})\)
where
\(\mathsf{GroupHash}^\mathbb{P}\)
- is defined as in 20.
+ is defined as in 21.
The relations between the Asset Identifier, Asset Digest, and Asset Base are shown in the following diagram:
@@ -312,17 +312,31 @@
Specification: Global Issuance State
Issuance requires the following additions to the global state defined at block boundaries:
+
A map,
+ \(\mathsf{issued\_assets}\!\)
+ , from the Asset Base,
+ \(\mathsf{AssetBase_{AssetId}}\)
+ , to a tuple
+ \((\mathsf{balance_{AssetId}}, \mathsf{final_{AssetId}})\)
+ , for every Asset that has been issued up until the block boundary.
-
- \(\mathsf{previously\_finalized}\!\)
- , a set of
- \(\mathsf{AssetId}\)
- that have been finalized (i.e.: the
+
The amount of the Asset in circulation, computed as the amount of the Asset that has been issued less the amount of the Asset that has been burnt, is stored in
+ \(\mathsf{balance_{AssetId}}\)
+ .
+
The boolean
+ \(\mathsf{final_{AssetId}}\)
+ stores the finalization status of the Asset (i.e.: whether the
\(\mathsf{finalize}\)
flag has been set to
\(1\)
in some issuance transaction preceding the block boundary).
+
Rationale for Global Issuance State
+
It is necessary to ensure that the balance of any issued Custom Asset never becomes negative within a shielded pool, along the lines of ZIP 209 8. However, unlike for the shielded ZEC pools, there is no individual transaction field that directly corresponds to both the issuance and burnt amounts for a given Asset. Therefore, we require that all nodes maintain a record of the current amount in circulation for every issued Custom Asset, and update this record at the block boundary based on the issuance and burn transactions within the block. This allows for efficient detection of balance violations for any Asset, in which scenario we specify a consensus rule to reject the block.
+
Nodes also need to ensure the rejection of blocks in which issuance of Custom Assets that have been previously finalized. The
+ \(\mathsf{issued\_assets}\!\)
+ map allows nodes to store whether or not a given Asset has been finalized.
+
Specification: Issuance Action, Issuance Bundle and Issuance Protocol
Issuance Action Description
@@ -429,7 +443,7 @@
\(\mathsf{isk}\!\)
, that validates the issuance.
-
The issuance bundle is then added within the transaction format as a new bundle. That is, issuance requires the addition of the following information to the transaction format 22.
+
The issuance bundle is then added within the transaction format as a new bundle. That is, issuance requires the addition of the following information to the transaction format 23.
@@ -566,7 +580,7 @@
For each note, compute the note commitment as
\(\mathsf{cm} = \mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase})\)
- as defined in the Note Structure and Commitment section of ZIP 226 10 and
+ as defined in the Note Structure and Commitment section of ZIP 226 11 and
Add
\(\mathsf{cm}\)
to the Merkle tree of note commitments.
@@ -607,7 +621,7 @@
By using the
\(\mathsf{finalize}\)
- boolean and the burning mechanism defined in 9, issuers can control the supply production of any Asset associated to their issuer keys. For example,
+ boolean and the burning mechanism defined in 10, issuers can control the supply production of any Asset associated to their issuer keys. For example,
by setting
\(\mathsf{finalize} = 1\)
@@ -643,7 +657,7 @@
TxId Digest - Issuance
-
This section details the construction of the subtree of hashes in the transaction digest that corresponds to issuance transaction data. Details of the overall changes to the transaction digest due to the Orchard-ZSA protocol can be found in ZIP 226 11. As in ZIP 244 12, the digests are all personalized BLAKE2b-256 hashes, and in cases where no elements are available for hashing, a personalized hash of the empty byte array is used.
+
This section details the construction of the subtree of hashes in the transaction digest that corresponds to issuance transaction data. Details of the overall changes to the transaction digest due to the Orchard-ZSA protocol can be found in ZIP 226 12. As in ZIP 244 13, the digests are all personalized BLAKE2b-256 hashes, and in cases where no elements are available for hashing, a personalized hash of the empty byte array is used.
A new issuance transaction digest algorithm is defined that constructs the subtree of the transaction digest tree of hashes for the issuance portion of a transaction. Each branch of the subtree will correspond to a specific subset of issuance transaction data. The overall structure of the hash is as follows; each name referenced here will be described in detail below:
In case the transaction has no Issue Notes, ''issue_notes_digest'' is:
BLAKE2b-256("ZTxIdIAcNoteHash", [])
T.5a.i.1: recipient
-
This is the raw encoding of an Orchard shielded payment address as defined in the protocol specification 21.
+
This is the raw encoding of an Orchard shielded payment address as defined in the protocol specification 22.
T.5a.i.2: value
Note value encoded as little-endian 8-byte representation of 64-bit unsigned integer (e.g. u64 in Rust) raw value.
@@ -713,7 +727,7 @@
Signature Digest
-
The per-input transaction digest algorithm to generate the signature digest in ZIP 244 13 is modified so that a signature digest is produced for each transparent input, each Sapling input, each Orchard action, and additionally for each Issuance Action. For Issuance Actions, this algorithm has the exact same output as the transaction digest algorithm, thus the txid may be signed directly.
+
The per-input transaction digest algorithm to generate the signature digest in ZIP 244 14 is modified so that a signature digest is produced for each transparent input, each Sapling input, each Orchard action, and additionally for each Issuance Action. For Issuance Actions, this algorithm has the exact same output as the transaction digest algorithm, thus the txid may be signed directly.
The overall structure of the hash is as follows. We highlight the changes for the Orchard-ZSA protocol via the [ADDED FOR ZSA] text label, and we omit the descriptions of the sections that do not change for the Orchard-ZSA protocol:
The personalization field remains the same as in ZIP 244 12.
+
The personalization field remains the same as in ZIP 244 13.
S.5: issuance_digest
Identical to that specified for the transaction identifier.
Authorizing Data Commitment
-
The transaction digest algorithm defined in ZIP 244 14 which commits to the authorizing data of a transaction is modified by the Orchard-ZSA protocol to have the following structure. We highlight the changes for the Orchard-ZSA protocol via the [ADDED FOR ZSA] text label, and we omit the descriptions of the sections that do not change for the Orchard-ZSA protocol:
+
The transaction digest algorithm defined in ZIP 244 15 which commits to the authorizing data of a transaction is modified by the Orchard-ZSA protocol to have the following structure. We highlight the changes for the Orchard-ZSA protocol via the [ADDED FOR ZSA] text label, and we omit the descriptions of the sections that do not change for the Orchard-ZSA protocol:
For bridging purposes, the secure method of off-boarding Assets is to burn an Asset with the burning mechanism in ZIP 226 9. Users should be aware of issuers that demand the Assets be sent to a specific address on the Zcash chain to be redeemed elsewhere, as this may not reflect the real reserve value of the specific Wrapped Asset.
+
For bridging purposes, the secure method of off-boarding Assets is to burn an Asset with the burning mechanism in ZIP 226 10. Users should be aware of issuers that demand the Assets be sent to a specific address on the Zcash chain to be redeemed elsewhere, as this may not reflect the real reserve value of the specific Wrapped Asset.
Other Considerations
@@ -790,7 +804,7 @@
in order to properly keep track of the total supply for different Asset Identifiers. This is useful for wallets and other applications that need to keep track of the total supply of Assets.
Fee Structures
-
The fee mechanism described in this ZIP will follow the mechanism described in ZIP 317 15.
+
The fee mechanism described in this ZIP will follow the mechanism described in ZIP 317 16.
diff --git a/zips/zip-0227.rst b/zips/zip-0227.rst
index 7aed636a5..ab37c2470 100644
--- a/zips/zip-0227.rst
+++ b/zips/zip-0227.rst
@@ -221,8 +221,21 @@ Specification: Global Issuance State
Issuance requires the following additions to the global state defined at block boundaries:
-- :math:`\mathsf{previously\_finalized}\!`, a set of :math:`\mathsf{AssetId}` that have been finalized (i.e.: the :math:`\mathsf{finalize}` flag has been set to :math:`1` in some issuance transaction preceding the block boundary).
+A map, :math:`\mathsf{issued\_assets}\!`, from the Asset Base, :math:`\mathsf{AssetBase_{AssetId}}`, to a tuple :math:`(\mathsf{balance_{AssetId}}, \mathsf{final_{AssetId}})`, for every Asset that has been issued up until the block boundary.
+- The amount of the Asset in circulation, computed as the amount of the Asset that has been issued less the amount of the Asset that has been burnt, is stored in :math:`\mathsf{balance_{AssetId}}`.
+- The boolean :math:`\mathsf{final_{AssetId}}` stores the finalization status of the Asset (i.e.: whether the :math:`\mathsf{finalize}` flag has been set to :math:`1` in some issuance transaction preceding the block boundary).
+
+Rationale for Global Issuance State
+-----------------------------------
+
+It is necessary to ensure that the balance of any issued Custom Asset never becomes negative within a shielded pool, along the lines of ZIP 209 [#zip-0209]_.
+However, unlike for the shielded ZEC pools, there is no individual transaction field that directly corresponds to both the issuance and burnt amounts for a given Asset.
+Therefore, we require that all nodes maintain a record of the current amount in circulation for every issued Custom Asset, and update this record at the block boundary based on the issuance and burn transactions within the block.
+This allows for efficient detection of balance violations for any Asset, in which scenario we specify a consensus rule to reject the block.
+
+Nodes also need to ensure the rejection of blocks in which issuance of Custom Assets that have been previously finalized.
+The :math:`\mathsf{issued\_assets}\!` map allows nodes to store whether or not a given Asset has been finalized.
Specification: Issuance Action, Issuance Bundle and Issuance Protocol
=====================================================================
@@ -237,6 +250,8 @@ An issuance action, ``IssueAction``, is the instance of issuing a specific Custo
- ``vNotes``: an array of ``Note`` containing the unencrypted output notes of the recipients of the Asset.
- ``flagsIssuance``: a byte that stores the :math:`\mathsf{finalize}` boolean that defines whether the issuance of that specific Custom Asset is finalized or not.
+
+
An asset's :math:`\mathsf{AssetDigest}` is added to the :math:`\mathsf{previously\_finalized}` set after a block that contains any issuance transaction for that asset with :math:`\mathsf{finalize} = 1\!`. It then cannot be removed from this set. For Assets with :math:`\mathsf{AssetDigest} \in \mathsf{previously\_finalized}\!`, no further tokens can be issued, so as seen below, the validators will reject the transaction. For Assets with :math:`\mathsf{AssetDigest} \not\in \mathsf{previously\_finalized}\!`, new issuance actions can be issued in future transactions. These must use the same Asset description, :math:`\mathsf{asset\_desc}\!`, and can either maintain :math:`\mathsf{finalize} = 0` or change it to :math:`\mathsf{finalize} = 1\!`, denoting that this Custom Asset cannot be issued after the containing block.
@@ -606,6 +621,7 @@ References
.. [#zip-0032-key-path-levels] `ZIP 32: Shielded Hierarchical Deterministic Wallets - Key path levels `_
.. [#zip-0032-orchard-key-path] `ZIP 32: Shielded Hierarchical Deterministic Wallets - Orchard key path `_
.. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_
+.. [#zip-0209] `ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances `_
.. [#zip-0224] `ZIP 224: Orchard `_
.. [#zip-0226] `ZIP 226: Transfer and Burn of Zcash Shielded Assets `_
.. [#zip-0226-notestructure] `ZIP 226: Transfer and Burn of Zcash Shielded Assets - Note Structure & Commitment `_
From 20b1f16c5c196cd59298302a159a1b24e7652fe0 Mon Sep 17 00:00:00 2001
From: Vivek Arte
Date: Mon, 12 Aug 2024 18:05:46 +0530
Subject: [PATCH 2/4] first draft of changes for the consensus changes
---
rendered/zip-0226.html | 60 ++++++++++++++++-----------
rendered/zip-0227.html | 92 ++++++++++++++++++++++++++++++------------
zips/zip-0226.rst | 9 +++--
zips/zip-0227.rst | 31 +++++++++-----
4 files changed, 132 insertions(+), 60 deletions(-)
diff --git a/rendered/zip-0226.html b/rendered/zip-0226.html
index c54818e33..b93063cc5 100644
--- a/rendered/zip-0226.html
+++ b/rendered/zip-0226.html
@@ -214,25 +214,39 @@
set.
Additional Consensus Rules
-
We require that for every
- \((\mathsf{AssetBase_{AssetId}}, \mathsf{v_{AssetId}}) \in \mathsf{assetBurn}, \mathsf{AssetBase_{AssetId}} \neq \mathcal{V}^{\mathsf{Orchard}}\!\)
+
Check that for every
+ \((\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{AssetBase} \neq \mathcal{V}^{\mathsf{Orchard}}\!\)
. That is, ZEC or TAZ is not allowed to be burnt by this mechanism.
-
We require that for every
- \((\mathsf{AssetBase_{AssetId}}, \mathsf{v_{AssetId}}) \in \mathsf{assetBurn}, \mathsf{v_{AssetId}} \neq 0\!\)
+
Check that for every
+ \((\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{v} \neq 0\!\)
.
-
We require that there be no duplication of Custom Assets in the
+
Check that there is no duplication of Custom Assets in the
\(\mathsf{assetBurn}\)
set. That is, every
- \(\mathsf{AssetBase_{AssetId}}\)
+ \(\mathsf{AssetBase}\)
has at most one entry in
\(\mathsf{assetBurn}\!\)
.
+
Check that for every
+ \((\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}\!\)
+ ,
+ \(\mathsf{v} \leq \mathsf{issued\_assets(AssetDigest).balance}\!\)
+ , where the map
+ \(\mathsf{issued\_assets}\)
+ is defined in ZIP 227 5. That is, it is not possible to burn more of an Asset than is currently in circulation.
+
If all these checks pass, then for every
+ \((\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}\!\)
+ , reduce the value of
+ \(\mathsf{issued\_assets(AssetDigest).balance}\)
+ in the global state by
+ \(\mathsf{v}\!\)
+ .
Note: Even if this mechanism allows having transparent ↔ shielded Asset transfers in theory, the transparent protocol will not be changed with this ZIP to adapt to a multiple Asset structure. This means that unless future consensus rules changes do allow it, unshielding will not be possible for Custom Assets.
Value Balance Verification
-
In order to verify the balance of the different Assets, the verifier MUST perform a similar process as for the Orchard protocol 18, with the addition of the burn information.
+
In order to verify the balance of the different Assets, the verifier MUST perform a similar process as for the Orchard protocol 18, with the addition of the burn information.
For a total of
\(n\)
Actions in a transfer, the prover MUST still sign the SIGHASH transaction hash using the binding signature key
@@ -255,7 +269,7 @@
the set of indices of Actions that are related to Custom Assets.
The right hand side of the value balance verification equation can be expanded to:
This equation contains the balance check of the Orchard protocol 18. With ZSA, transfer Actions for Custom Assets must also be balanced across Asset Bases. All Custom Assets are contained within the shielded pool, and cannot be unshielded via a regular transfer. Custom Assets can be burnt, the mechanism for which reveals the amount and identifier of the Asset being burnt, within the
+
This equation contains the balance check of the Orchard protocol 18. With ZSA, transfer Actions for Custom Assets must also be balanced across Asset Bases. All Custom Assets are contained within the shielded pool, and cannot be unshielded via a regular transfer. Custom Assets can be burnt, the mechanism for which reveals the amount and identifier of the Asset being burnt, within the
\(\mathsf{assetBurn}\)
set. As such, for a correctly constructed transaction, we will get
\(\sum_{j \in S_{\mathsf{CA}}} \mathsf{cv}^{\mathsf{net}}_j - \sum_{(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}} [\mathsf{v}]\,\mathsf{AssetBase} = \sum_{j \in S_{\mathsf{CA}}} [\mathsf{rcv}^{\mathsf{net}}_j]\,\mathcal{R}^{\mathsf{Orchard}}\!\)
@@ -304,11 +318,11 @@
\(\mathbb{F}_{q_{\mathbb{P}}}\!\)
,
\(\mathcal{K}^{\mathsf{Orchard}}\)
- is the Orchard Nullifier Base as defined in 19, and
+ is the Orchard Nullifier Base as defined in 19, and
\(\mathcal{L}^{\mathsf{Orchard}} := \mathsf{GroupHash^{\mathbb{P}}}(\texttt{"z.cash:Orchard"}, \texttt{"L"})\!\)
.
Rationale for Split Notes
-
In the Orchard protocol, since each Action represents an input and an output, the transaction that wants to send one input to multiple outputs must have multiple inputs. The Orchard protocol gives dummy spend notes17 to the Actions that have not been assigned input notes.
+
In the Orchard protocol, since each Action represents an input and an output, the transaction that wants to send one input to multiple outputs must have multiple inputs. The Orchard protocol gives dummy spend notes17 to the Actions that have not been assigned input notes.
The Orchard technique requires modification for the ZSA protocol with multiple Asset Identifiers, as the output note of the split Actions cannot contain just any Asset Base. We must enforce it to be an actual output of a GroupHash computation (in fact, we want it to be of the same Asset Base as the original input note, but the binding signature takes care that the proper balancing is performed). Without this enforcement the prover could input a multiple (or linear combination) of an existing Asset Base, and thereby attack the network by overflowing the ZEC value balance and hence counterfeiting ZEC funds.
Therefore, for Custom Assets we enforce that every input note to an ZSA Action must be proven to exist in the set of note commitments in the note commitment tree. We then enforce this real note to be “unspendable” in the sense that its value will be zeroed in split Actions and the nullifier will be randomized, making the note not spendable in the specific Action. Then, the proof itself ensures that the output note is of the same Asset Base as the input note. In the circuit, the split note functionality will be activated by a boolean private input to the proof (aka the
\(\mathsf{split\_flag}\)
@@ -317,8 +331,8 @@
Circuit Statement
-
Every ZSA Action statement is closely similar to the Orchard Action statement 20, except for a few additions that ensure the security of the Asset Identifier system. We detail these changes below.
-
All modifications in the Circuit are detailed in 31.
+
Every ZSA Action statement is closely similar to the Orchard Action statement 20, except for a few additions that ensure the security of the Asset Identifier system. We detail these changes below.
+
All modifications in the Circuit are detailed in 31.
Asset Base Equality
The following constraints must be added to ensure that the input and output note are of the same
\(\mathsf{AssetBase}\!\)
@@ -327,12 +341,12 @@
The Asset Base,
\(\mathsf{AssetBase_{AssetId}}\!\)
, for the note is witnessed once, as an auxiliary input.
-
In the Old note commitment integrity constraint in the Orchard Action statement 20,
+
In the Old note commitment integrity constraint in the Orchard Action statement 20,
\(\mathsf{NoteCommit^{Orchard}_{rcm^{old}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{old}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{old}}), \mathsf{v^{old}}, \text{ρ}^{\mathsf{old}}, \text{ψ}^{\mathsf{old}})\)
is replaced with
\(\mathsf{NoteCommit^{OrchardZSA}_{rcm^{old}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{old}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{old}}), \mathsf{v^{old}}, \text{ρ}^{\mathsf{old}}, \text{ψ}^{\mathsf{old}}, \mathsf{AssetBase_{AssetId}})\!\)
.
-
In the New note commitment integrity constraint in the Orchard Action statement 20,
+
In the New note commitment integrity constraint in the Orchard Action statement 20,
\(\mathsf{NoteCommit^{Orchard}_{rcm^{new}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{new}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{new}}), \mathsf{v^{new}}, \text{ρ}^{\mathsf{new}}, \text{ψ}^{\mathsf{new}})\)
is replaced with
\(\mathsf{NoteCommit^{OrchardZSA}_{rcm^{new}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{new}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{new}}), \mathsf{v^{new}}, \text{ρ}^{\mathsf{new}}, \text{ψ}^{\mathsf{new}}, \mathsf{AssetBase_{AssetId}})\!\)
@@ -449,15 +463,15 @@
The
Backwards Compatibility with ZEC Notes
-
The input note in the old note commitment integrity check must either include an Asset Base (ZSA note) or not (pre-ZSA Orchard note). If the note is a pre-ZSA Orchard note, the note commitment is computed in the original Orchard fashion 16. If the note is a ZSA note, the note commitment is computed as defined in the Note Structure & Commitment section.
+
The input note in the old note commitment integrity check must either include an Asset Base (ZSA note) or not (pre-ZSA Orchard note). If the note is a pre-ZSA Orchard note, the note commitment is computed in the original Orchard fashion 16. If the note is a ZSA note, the note commitment is computed as defined in the Note Structure & Commitment section.
Orchard-ZSA Transaction Structure
-
The transaction format for v6 transactions is described in ZIP 230 10.
+
The transaction format for v6 transactions is described in ZIP 230 10.
TxId Digest
-
The transaction digest algorithm defined in ZIP 244 11 is modified by the ZSA protocol to add a new branch for issuance information, along with modifications within the orchard_digest to account for the inclusion of the Asset Base. The details of these changes are described in this section, and highlighted using the [UPDATED FOR ZSA] or [ADDED FOR ZSA] text label. We omit the details of the sections that do not change for the ZSA protocol.
+
The transaction digest algorithm defined in ZIP 244 11 is modified by the ZSA protocol to add a new branch for issuance information, along with modifications within the orchard_digest to account for the inclusion of the Asset Base. The details of these changes are described in this section, and highlighted using the [UPDATED FOR ZSA] or [ADDED FOR ZSA] text label. We omit the details of the sections that do not change for the ZSA protocol.
The
T.4f: valueBalanceOrchard (64-bit signed little-endian)
T.4g: anchorOrchard (32 bytes)
T.4a: orchard_actions_compact_digest
-
A BLAKE2b-256 hash of the subset of Orchard Action information intended to be included in an updated version of the ZIP-307 12CompactBlock format for all Orchard Actions belonging to the transaction. For each Action, the following elements are included in the hash:
+
A BLAKE2b-256 hash of the subset of Orchard Action information intended to be included in an updated version of the ZIP-307 12CompactBlock format for all Orchard Actions belonging to the transaction. For each Action, the following elements are included in the hash:
A BLAKE2b-256 hash of the remaining subset of Orchard Action information not intended for inclusion in an updated version of the the ZIP 307 12CompactBlock format, for all Orchard Actions belonging to the transaction. For each Action, the following elements are included in the hash:
+
A BLAKE2b-256 hash of the remaining subset of Orchard Action information not intended for inclusion in an updated version of the the ZIP 307 12CompactBlock format, for all Orchard Actions belonging to the transaction. For each Action, the following elements are included in the hash:
T.4d.i : cv (field encoding bytes)
T.4d.ii : rk (field encoding bytes)
T.4d.iii: encCiphertext[596..] (post-memo suffix of field encoding) [UPDATED FOR ZSA]
@@ -520,12 +534,12 @@
The
T.5: issuance_digest
-
The details of the computation of this value are in ZIP 227 7.
+
The details of the computation of this value are in ZIP 227 7.
Signature Digest and Authorizing Data Commitment
-
The details of the changes to these algorithms are in ZIP 227 89.
+
The details of the changes to these algorithms are in ZIP 227 89.
Security and Privacy Considerations
@@ -538,7 +552,7 @@
The
Other Considerations
Transaction Fees
-
The fee mechanism for the upgrades proposed in this ZIP will follow the mechanism described in ZIP 317 for the ZSA protocol upgrade 13.
+
The fee mechanism for the upgrades proposed in this ZIP will follow the mechanism described in ZIP 317 for the ZSA protocol upgrade 13.
Backward Compatibility
In order to have backward compatibility with the ZEC notes, we have designed the circuit to support both ZEC and ZSA notes. As we specify above, there are three main reasons we can do this:
Issuance requires the following additions to the global state defined at block boundaries:
A map,
\(\mathsf{issued\_assets}\!\)
- , from the Asset Base,
- \(\mathsf{AssetBase_{AssetId}}\)
+ , from the Asset Digest,
+ \(\mathsf{AssetDigest}\)
+ corresponding to an Asset Identifier
+ \(\mathsf{AId}\)
, to a tuple
- \((\mathsf{balance_{AssetId}}, \mathsf{final_{AssetId}})\)
+ \((\mathsf{balance_{AId}}, \mathsf{final_{AId}})\)
, for every Asset that has been issued up until the block boundary.
The amount of the Asset in circulation, computed as the amount of the Asset that has been issued less the amount of the Asset that has been burnt, is stored in
- \(\mathsf{balance_{AssetId}}\)
+ \(\mathsf{balance_{AId}}\)
.
The boolean
- \(\mathsf{final_{AssetId}}\)
+ \(\mathsf{final_{AId}}\)
stores the finalization status of the Asset (i.e.: whether the
\(\mathsf{finalize}\)
flag has been set to
\(1\)
- in some issuance transaction preceding the block boundary).
+ in some issuance transaction for Asset
+ \(\mathsf{AId}\)
+ preceding the block boundary).
+
We use the notation
+ \(\mathsf{issued\_assets}(AssetDigest)\)
+ to refer to the tuple,
+ \((\mathsf{balance_{AId}}, \mathsf{final_{AId}})\)
+ . Further, we use the notation
+ \(\mathsf{issued\_assets}(AssetDigest).balance\)
+ and
+ \(\mathsf{issued\_assets}(AssetDigest).final\)
+ to refer to the balance and finalization status of the Asset, respectively.
Rationale for Global Issuance State
-
It is necessary to ensure that the balance of any issued Custom Asset never becomes negative within a shielded pool, along the lines of ZIP 209 8. However, unlike for the shielded ZEC pools, there is no individual transaction field that directly corresponds to both the issuance and burnt amounts for a given Asset. Therefore, we require that all nodes maintain a record of the current amount in circulation for every issued Custom Asset, and update this record at the block boundary based on the issuance and burn transactions within the block. This allows for efficient detection of balance violations for any Asset, in which scenario we specify a consensus rule to reject the block.
+
It is necessary to ensure that the balance of any issued Custom Asset never becomes negative within a shielded pool, along the lines of ZIP 209 8. However, unlike for the shielded ZEC pools, there is no individual transaction field that directly corresponds to both the issued and burnt amounts for a given Asset. Therefore, we require that all nodes maintain a record of the current amount in circulation for every issued Custom Asset, and update this record at the block boundary based on the issuance and burn transactions within the block. This allows for efficient detection of balance violations for any Asset, in which scenario we specify a consensus rule to reject the block.
Nodes also need to ensure the rejection of blocks in which issuance of Custom Assets that have been previously finalized. The
\(\mathsf{issued\_assets}\!\)
map allows nodes to store whether or not a given Asset has been finalized.
+
Note that while there is only a single pool for ZSAs, the
+ \(\mathsf{issued\_assets}\)
+ map can be as specified above, but in future when there are multiple pools, the map will need to be extended to store the balance for the Asset in each pool. That is, the map will be from the Asset Digest
+ \(\mathsf{AssetDigest}\)
+ to a tuple of the form
+ \(((\mathsf{balance_{AId}^{OrchardZSA}}, \mathsf{balance_{AId}^{NewPool}}, \ldots), \mathsf{final_{AId}})\)
+ , with one balance entry for each pool that supports ZSAs.
Specification: Issuance Action, Issuance Bundle and Issuance Protocol
@@ -353,6 +373,21 @@
\(\mathsf{finalize}\)
boolean that defines whether the issuance of that specific Custom Asset is finalized or not.
+
The value of
+ \(\mathsf{issued\_assets}(AssetDigest).final\)
+ is set to
+ \(1\)
+ after a block that contains any issuance transaction for the Asset corresponding to
+ \(\mathsf{AssetDigest}`\)
+ with
+ \(\mathsf{finalize} = 1\!\)
+ . The value of
+ \(\mathsf{issued\_assets}(AssetDigest).final\)
+ cannot be changed from
+ \(1\)
+ to
+ \(0\)
+ .
An asset's
\(\mathsf{AssetDigest}\)
is added to the
@@ -565,11 +600,9 @@
and
\(\mathsf{asset\_desc}\)
as described in the Specification: Asset Identifier section.
-
check that the
- \(\mathsf{AssetDigest}\)
- does not exist in the
- \(\mathsf{previously\_finalized}\)
- set in the global state.
+
check that
+ \(\mathsf{issued\_assets(AssetDigest).final} \neq 1\)
+ in the global state.
check that every note in the IssueAction contains the same
\(\mathsf{AssetBase}\)
and is properly constructed as
@@ -578,19 +611,28 @@
If all of the above checks pass, do the following:
-
For each note, compute the note commitment as
- \(\mathsf{cm} = \mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase})\)
- as defined in the Note Structure and Commitment section of ZIP 226 11 and
-
Add
- \(\mathsf{cm}\)
- to the Merkle tree of note commitments.
+
For each note,
+
+
compute the note commitment as
+ \(\mathsf{cm} = \mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase})\)
+ as defined in the Note Structure and Commitment section of ZIP 226 11.
+
Add
+ \(\mathsf{cm}\)
+ to the Merkle tree of note commitments.
+
Increase the value of
+ \(\mathsf{issued\_assets(AssetDigest).balance}\)
+ by the value of the note,
+ \(\mathsf{v}\)
+ .
+
+
If
\(\mathsf{finalize} = 1\!\)
- , add
- \(\mathsf{AssetDigest}\)
- to the
- \(\mathsf{previously\_finalized}\)
- set immediately after the block in which this transaction occurs.
+ , set
+ \(\mathsf{issued\_assets(AssetDigest).final}\)
+ to
+ \(1\)
+ in the global state immediately after the block in which this transaction occurs.
(Replay Protection) If issue bundle is present, the fees MUST be greater than zero.
@@ -612,8 +654,8 @@
We require a check whether the
\(\mathsf{finalize}\)
flag only has been set in a previous block rather than a previous transaction in the same block. In other words, we only update the
- \(\mathsf{previously\_finalized}`\)
- set at the block boundary. This is in keeping with the current property which allows for a miner to reorder transactions in a block without changing the meaning, which we aim to preserve.
+ \(\mathsf{issued\_assets}\)
+ map at the block boundary. This is in keeping with the current property which allows for a miner to reorder transactions in a block without changing the meaning, which we aim to preserve.
We require non-zero fees in the presence of an issue bundle, in order to preclude the possibility of a transaction containing only an issue bundle. If a transaction includes only an issue bundle, the SIGHASH transaction hash would be computed solely based on the issue bundle. A duplicate bundle would have the same SIGHASH transaction hash, potentially allowing for a replay attack.
Concrete Applications
diff --git a/zips/zip-0226.rst b/zips/zip-0226.rst
index a498db3cb..6b7d3d37d 100644
--- a/zips/zip-0226.rst
+++ b/zips/zip-0226.rst
@@ -182,9 +182,12 @@ We denote by :math:`L` the cardinality of the :math:`\mathsf{assetBurn}` set.
Additional Consensus Rules
``````````````````````````
-1. We require that for every :math:`(\mathsf{AssetBase_{AssetId}}, \mathsf{v_{AssetId}}) \in \mathsf{assetBurn}, \mathsf{AssetBase_{AssetId}} \neq \mathcal{V}^{\mathsf{Orchard}}\!`. That is, ZEC or TAZ is not allowed to be burnt by this mechanism.
-2. We require that for every :math:`(\mathsf{AssetBase_{AssetId}}, \mathsf{v_{AssetId}}) \in \mathsf{assetBurn}, \mathsf{v_{AssetId}} \neq 0\!`.
-3. We require that there be no duplication of Custom Assets in the :math:`\mathsf{assetBurn}` set. That is, every :math:`\mathsf{AssetBase_{AssetId}}` has at most one entry in :math:`\mathsf{assetBurn}\!`.
+1. Check that for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{AssetBase} \neq \mathcal{V}^{\mathsf{Orchard}}\!`. That is, ZEC or TAZ is not allowed to be burnt by this mechanism.
+2. Check that for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{v} \neq 0\!`.
+3. Check that there is no duplication of Custom Assets in the :math:`\mathsf{assetBurn}` set. That is, every :math:`\mathsf{AssetBase}` has at most one entry in :math:`\mathsf{assetBurn}\!`.
+4. Check that for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}\!`, :math:`\mathsf{v} \leq \mathsf{issued\_assets(AssetDigest).balance}\!`, where the map :math:`\mathsf{issued\_assets}` is defined in ZIP 227 [#zip-0227]_. That is, it is not possible to burn more of an Asset than is currently in circulation.
+
+If all these checks pass, then for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}\!`, reduce the value of :math:`\mathsf{issued\_assets(AssetDigest).balance}` in the global state by :math:`\mathsf{v}\!`.
**Note:** Even if this mechanism allows having transparent ↔ shielded Asset transfers in theory, the transparent protocol will not be changed with this ZIP to adapt to a multiple Asset structure. This means that unless future consensus rules changes do allow it, unshielding will not be possible for Custom Assets.
diff --git a/zips/zip-0227.rst b/zips/zip-0227.rst
index ab37c2470..621f23837 100644
--- a/zips/zip-0227.rst
+++ b/zips/zip-0227.rst
@@ -221,22 +221,28 @@ Specification: Global Issuance State
Issuance requires the following additions to the global state defined at block boundaries:
-A map, :math:`\mathsf{issued\_assets}\!`, from the Asset Base, :math:`\mathsf{AssetBase_{AssetId}}`, to a tuple :math:`(\mathsf{balance_{AssetId}}, \mathsf{final_{AssetId}})`, for every Asset that has been issued up until the block boundary.
+A map, :math:`\mathsf{issued\_assets}\!`, from the Asset Digest, :math:`\mathsf{AssetDigest}` corresponding to an Asset Identifier :math:`\mathsf{AId}`, to a tuple :math:`(\mathsf{balance_{AId}}, \mathsf{final_{AId}})`, for every Asset that has been issued up until the block boundary.
-- The amount of the Asset in circulation, computed as the amount of the Asset that has been issued less the amount of the Asset that has been burnt, is stored in :math:`\mathsf{balance_{AssetId}}`.
-- The boolean :math:`\mathsf{final_{AssetId}}` stores the finalization status of the Asset (i.e.: whether the :math:`\mathsf{finalize}` flag has been set to :math:`1` in some issuance transaction preceding the block boundary).
+- The amount of the Asset in circulation, computed as the amount of the Asset that has been issued less the amount of the Asset that has been burnt, is stored in :math:`\mathsf{balance_{AId}}`.
+- The boolean :math:`\mathsf{final_{AId}}` stores the finalization status of the Asset (i.e.: whether the :math:`\mathsf{finalize}` flag has been set to :math:`1` in some issuance transaction for Asset :math:`\mathsf{AId}` preceding the block boundary).
+
+We use the notation :math:`\mathsf{issued\_assets}(AssetDigest)` to refer to the tuple, :math:`(\mathsf{balance_{AId}}, \mathsf{final_{AId}})`.
+Further, we use the notation :math:`\mathsf{issued\_assets}(AssetDigest).balance` and :math:`\mathsf{issued\_assets}(AssetDigest).final` to refer to the balance and finalization status of the Asset, respectively.
Rationale for Global Issuance State
-----------------------------------
It is necessary to ensure that the balance of any issued Custom Asset never becomes negative within a shielded pool, along the lines of ZIP 209 [#zip-0209]_.
-However, unlike for the shielded ZEC pools, there is no individual transaction field that directly corresponds to both the issuance and burnt amounts for a given Asset.
+However, unlike for the shielded ZEC pools, there is no individual transaction field that directly corresponds to both the issued and burnt amounts for a given Asset.
Therefore, we require that all nodes maintain a record of the current amount in circulation for every issued Custom Asset, and update this record at the block boundary based on the issuance and burn transactions within the block.
This allows for efficient detection of balance violations for any Asset, in which scenario we specify a consensus rule to reject the block.
Nodes also need to ensure the rejection of blocks in which issuance of Custom Assets that have been previously finalized.
The :math:`\mathsf{issued\_assets}\!` map allows nodes to store whether or not a given Asset has been finalized.
+Note that while there is only a single pool for ZSAs, the :math:`\mathsf{issued\_assets}` map can be as specified above, but in future when there are multiple pools, the map will need to be extended to store the balance for the Asset in each pool.
+That is, the map will be from the Asset Digest :math:`\mathsf{AssetDigest}` to a tuple of the form :math:`((\mathsf{balance_{AId}^{OrchardZSA}}, \mathsf{balance_{AId}^{NewPool}}, \ldots), \mathsf{final_{AId}})`, with one balance entry for each pool that supports ZSAs.
+
Specification: Issuance Action, Issuance Bundle and Issuance Protocol
=====================================================================
@@ -250,6 +256,8 @@ An issuance action, ``IssueAction``, is the instance of issuing a specific Custo
- ``vNotes``: an array of ``Note`` containing the unencrypted output notes of the recipients of the Asset.
- ``flagsIssuance``: a byte that stores the :math:`\mathsf{finalize}` boolean that defines whether the issuance of that specific Custom Asset is finalized or not.
+The value of :math:`\mathsf{issued\_assets}(AssetDigest).final` is set to :math:`1` after a block that contains any issuance transaction for the Asset corresponding to :math:`\mathsf{AssetDigest}`` with :math:`\mathsf{finalize} = 1\!`.
+The value of :math:`\mathsf{issued\_assets}(AssetDigest).final` cannot be changed from :math:`1` to :math:`0`.
An asset's :math:`\mathsf{AssetDigest}` is added to the :math:`\mathsf{previously\_finalized}` set after a block that contains any issuance transaction for that asset with :math:`\mathsf{finalize} = 1\!`. It then cannot be removed from this set. For Assets with :math:`\mathsf{AssetDigest} \in \mathsf{previously\_finalized}\!`, no further tokens can be issued, so as seen below, the validators will reject the transaction. For Assets with :math:`\mathsf{AssetDigest} \not\in \mathsf{previously\_finalized}\!`, new issuance actions can be issued in future transactions. These must use the same Asset description, :math:`\mathsf{asset\_desc}\!`, and can either maintain :math:`\mathsf{finalize} = 0` or change it to :math:`\mathsf{finalize} = 1\!`, denoting that this Custom Asset cannot be issued after the containing block.
@@ -343,14 +351,19 @@ For each ``IssueAction`` in ``IssueBundle``:
- check that :math:`\mathsf{asset\_desc}` is a string of length :math:`\mathtt{assetDescSize}` bytes.
- retrieve :math:`\mathsf{AssetBase}` from the first note in the sequence and check that :math:`\mathsf{AssetBase}` is derived from the issuance validating key :math:`\mathsf{ik}` and :math:`\mathsf{asset\_desc}` as described in the `Specification: Asset Identifier`_ section.
-- check that the :math:`\mathsf{AssetDigest}` does not exist in the :math:`\mathsf{previously\_finalized}` set in the global state.
+- check that :math:`\mathsf{issued\_assets(AssetDigest).final} \neq 1` in the global state.
- check that every note in the ``IssueAction`` contains the same :math:`\mathsf{AssetBase}` and is properly constructed as :math:`\mathsf{note} = (\mathsf{g_d}, \mathsf{pk_d}, \mathsf{v}, \text{ρ}, \mathsf{rseed}, \mathsf{AssetBase})\!`.
If all of the above checks pass, do the following:
-- For each note, compute the note commitment as :math:`\mathsf{cm} = \mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase})` as defined in the Note Structure and Commitment section of ZIP 226 [#zip-0226-notestructure]_ and
-- Add :math:`\mathsf{cm}` to the Merkle tree of note commitments.
-- If :math:`\mathsf{finalize} = 1\!`, add :math:`\mathsf{AssetDigest}` to the :math:`\mathsf{previously\_finalized}` set immediately after the block in which this transaction occurs.
+- For each note,
+
+ - compute the note commitment as :math:`\mathsf{cm} = \mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase})` as defined in the Note Structure and Commitment section of ZIP 226 [#zip-0226-notestructure]_.
+ - Add :math:`\mathsf{cm}` to the Merkle tree of note commitments.
+ - Increase the value of :math:`\mathsf{issued\_assets(AssetDigest).balance}` by the value of the note, :math:`\mathsf{v}`.
+
+- If :math:`\mathsf{finalize} = 1\!`, set :math:`\mathsf{issued\_assets(AssetDigest).final}` to :math:`1` in the global state immediately after the block in which this transaction occurs.
+
- (Replay Protection) If issue bundle is present, the fees MUST be greater than zero.
@@ -368,7 +381,7 @@ The following is a list of rationale for different decisions made in the proposa
- bridging information for Wrapped Assets (chain of origin, issuer name, etc)
- information to be committed by the issuer, though not enforceable by the protocol.
-- We require a check whether the :math:`\mathsf{finalize}` flag only has been set in a previous block rather than a previous transaction in the same block. In other words, we only update the :math:`\mathsf{previously\_finalized}`` set at the block boundary. This is in keeping with the current property which allows for a miner to reorder transactions in a block without changing the meaning, which we aim to preserve.
+- We require a check whether the :math:`\mathsf{finalize}` flag only has been set in a previous block rather than a previous transaction in the same block. In other words, we only update the :math:`\mathsf{issued\_assets}` map at the block boundary. This is in keeping with the current property which allows for a miner to reorder transactions in a block without changing the meaning, which we aim to preserve.
- We require non-zero fees in the presence of an issue bundle, in order to preclude the possibility of a transaction containing only an issue bundle. If a transaction includes only an issue bundle, the SIGHASH transaction hash would be computed solely based on the issue bundle. A duplicate bundle would have the same SIGHASH transaction hash, potentially allowing for a replay attack.
Concrete Applications
From 38469eff0e2c906f146ea81921e3c837f298abf8 Mon Sep 17 00:00:00 2001
From: Vivek Arte
Date: Tue, 13 Aug 2024 12:03:54 +0530
Subject: [PATCH 3/4] further updates
---
rendered/zip-0226.html | 130 ++++++++++++++++++++++-------------------
rendered/zip-0227.html | 36 +++++-------
zips/zip-0226.rst | 3 +-
zips/zip-0227.rst | 13 ++---
4 files changed, 91 insertions(+), 91 deletions(-)
diff --git a/rendered/zip-0226.html b/rendered/zip-0226.html
index b93063cc5..8003fc738 100644
--- a/rendered/zip-0226.html
+++ b/rendered/zip-0226.html
@@ -32,7 +32,7 @@
Split Input: an Action input used to ensure that the output note of that Action is of a validly issued
\(\mathsf{AssetBase}\)
- (see 6) when there is no corresponding real input note, in situations where the number of outputs are larger than the number of inputs. See formal definition in Split Notes.
+ (see 7) when there is no corresponding real input note, in situations where the number of outputs are larger than the number of inputs. See formal definition in Split Notes.
Split Action: an Action that contains a Split Input.
@@ -48,18 +48,18 @@
. This Asset Identifier maps to an Asset Base
\(\mathsf{AssetBase}\)
that is stored in Orchard-based ZSA notes. These terms are formally defined in ZIP 227 5.
-
The Asset Identifier (via means of the Asset Digest and Asset Base) will be used to enforce that the balance of an Action Description 1528 is preserved across Assets (see the Orchard Binding Signature 18), and by extension the balance of an Orchard transaction. That is, the sum of all the
+
The Asset Identifier (via means of the Asset Digest and Asset Base) will be used to enforce that the balance of an Action Description 1629 is preserved across Assets (see the Orchard Binding Signature 19), and by extension the balance of an Orchard transaction. That is, the sum of all the
\(\mathsf{value^{net}}\)
from each Action Description, computed as
\(\mathsf{value^{old}} - \mathsf{value^{new}}\!\)
, must be balanced only with respect to the same Asset Identifier. This is especially important since we will allow different Action Descriptions to transfer notes of different Asset Identifiers, where the overall balance is checked without revealing which (or how many distinct) Assets are being transferred.
-
As was initially proposed by Jack Grigg and Daira-Emma Hopwood 2930, we propose to make this happen by changing the value base point,
+
As was initially proposed by Jack Grigg and Daira-Emma Hopwood 3031, we propose to make this happen by changing the value base point,
\(\mathcal{V}^{\mathsf{Orchard}}\!\)
, in the Homomorphic Pedersen Commitment that derives the value commitment,
\(\mathsf{cv^{net}}\!\)
, of the net value in an Orchard Action.
-
Because in a single transaction all value commitments are balanced, there must be as many different value base points as there are Asset Identifiers for a given shielded protocol used in a transaction. We propose to make the Asset Base an auxiliary input to the proof for each Action statement 20, represented already as a point on the Pallas curve. The circuit then should check that the same Asset Base is used in the old note commitment and the new note commitment 25, and as the base point in the value commitment 24. This ensures (1) that the input and output notes are of the same Asset Base, and (2) that only Actions with the same Asset Base will balance out in the Orchard binding signature.
-
In order to ensure the security of the transfers, and as we will explain below, we are redefining input dummy notes 17 for Custom Assets, as we need to enforce that the
+
Because in a single transaction all value commitments are balanced, there must be as many different value base points as there are Asset Identifiers for a given shielded protocol used in a transaction. We propose to make the Asset Base an auxiliary input to the proof for each Action statement 21, represented already as a point on the Pallas curve. The circuit then should check that the same Asset Base is used in the old note commitment and the new note commitment 26, and as the base point in the value commitment 25. This ensures (1) that the input and output notes are of the same Asset Base, and (2) that only Actions with the same Asset Base will balance out in the Orchard binding signature.
+
In order to ensure the security of the transfers, and as we will explain below, we are redefining input dummy notes 18 for Custom Assets, as we need to enforce that the
\(\mathsf{AssetBase}\)
of the output note of that Split Action is the output of a valid
\(\mathsf{ZSAValueBase}\)
@@ -98,7 +98,7 @@
be the type of a ZSA note, i.e.
\(\mathsf{Note^{OrchardZSA}} := \mathsf{Note^{Orchard}} \times \mathbb{P}^*\!\)
.
-
An Orchard ZSA note differs from an Orchard note 14 by additionally including the Asset Base,
+
An Orchard ZSA note differs from an Orchard note 15 by additionally including the Asset Base,
\(\mathsf{AssetBase}\!\)
. So a ZSA note is a tuple
\((\mathsf{g_d}, \mathsf{pk_d}, \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase})\!\)
@@ -106,7 +106,7 @@
\(\mathsf{AssetBase} : \mathbb{P}^*\)
- is the unique element of the Pallas group 26 that identifies each Asset in the Orchard protocol, defined as the Asset Base in ZIP 227 5, a valid group element that is not the identity and is not
+ is the unique element of the Pallas group 27 that identifies each Asset in the Orchard protocol, defined as the Asset Base in ZIP 227 5, a valid group element that is not the identity and is not
\(\bot\!\)
. The byte representation of the Asset Base is defined as
\(\mathsf{asset\_base} : \mathbb{B}^{[\ell_{\mathbb{P}}]} := \mathsf{repr}_{\mathbb{P}}(\mathsf{AssetBase})\!\)
@@ -119,11 +119,11 @@
where
\(\mathbb{P}, \ell_{\mathbb{P}}, q_{\mathbb{P}}\)
- are as defined for the Pallas curve 26, and where
+ are as defined for the Pallas curve 27, and where
\(\mathsf{NoteCommit^{Orchard}}.\!\mathsf{Trapdoor}\)
and
\(\mathsf{Orchard}.\!\mathsf{Output}\)
- are as defined in the Zcash protocol specification 16. This note commitment scheme is instantiated using the Sinsemilla Commitment 25 as follows:
+ are as defined in the Zcash protocol specification 17. This note commitment scheme is instantiated using the Sinsemilla Commitment 26 as follows:
\(\begin{align}
\mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{g_d}\star, \mathsf{pk_d}\star, \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase})
:= \begin{cases}
@@ -141,21 +141,21 @@
\(\mathsf{repr}_{\mathbb{P}}\)
and
\(\mathsf{GroupHash}^{\mathbb{P}}\)
- are as defined for the Pallas curve 26,
+ are as defined for the Pallas curve 27,
\(\ell^{\mathsf{Orchard}}_{\mathsf{base}}\)
- is as defined in §5.3 22, and
+ is as defined in §5.3 23, and
\(\mathsf{I2LEBSP}\)
- is as defined in §5.1 21 of the Zcash protocol specification.
-
The nullifier is generated in the same manner as in the Orchard protocol 19.
-
The ZSA note plaintext also includes the Asset Base in addition to the components in the Orchard note plaintext 27. It consists of
+ is as defined in §5.1 22 of the Zcash protocol specification.
+
The nullifier is generated in the same manner as in the Orchard protocol 20.
+
The ZSA note plaintext also includes the Asset Base in addition to the components in the Orchard note plaintext 28. It consists of
In the ZSA protocol, the instance of the note commitment scheme,
\(\mathsf{NoteCommit^{OrchardZSA}_{rcm}}\!\)
, differs from the Orchard note commitment
\(\mathsf{NoteCommit^{Orchard}_{rcm}}\)
- in that for Custom Assets, the Asset Base will be added as an input to the commitment computation. In the case where the Asset is the ZEC Asset, the commitment is computed identically to the Orchard note commitment, without making use of the ZEC Asset Base as an input. As we will see, the nested structure of the Sinsemilla-based commitment 25 allows us to add the Asset Base as a final recursive step.
-
The note commitment output is still indistinguishable from the original Orchard ZEC note commitments, by definition of the Sinsemilla hash function 23. ZSA note commitments will therefore be added to the same Orchard Note Commitment Tree. In essence, we have:
+ in that for Custom Assets, the Asset Base will be added as an input to the commitment computation. In the case where the Asset is the ZEC Asset, the commitment is computed identically to the Orchard note commitment, without making use of the ZEC Asset Base as an input. As we will see, the nested structure of the Sinsemilla-based commitment 26 allows us to add the Asset Base as a final recursive step.
+
The note commitment output is still indistinguishable from the original Orchard ZEC note commitments, by definition of the Sinsemilla hash function 24. ZSA note commitments will therefore be added to the same Orchard Note Commitment Tree. In essence, we have:
This definition can be viewed as a generalization of the Orchard note commitment, and will allow maintaining a single commitment instance for the note commitment, which will be used both for pre-ZSA Orchard and ZSA notes.
The Orchard Protocol uses a Homomorphic Pedersen Commitment 24 to perform the value commitment, with fixed base points
+
The Orchard Protocol uses a Homomorphic Pedersen Commitment 25 to perform the value commitment, with fixed base points
\(\mathcal{V}^{\mathsf{Orchard}}\)
and
\(\mathcal{R}^{\mathsf{Orchard}}\)
@@ -233,7 +233,7 @@
\(\mathsf{v} \leq \mathsf{issued\_assets(AssetDigest).balance}\!\)
, where the map
\(\mathsf{issued\_assets}\)
- is defined in ZIP 227 5. That is, it is not possible to burn more of an Asset than is currently in circulation.
+ is defined in ZIP 227 6. That is, it is not possible to burn more of an Asset than is currently in circulation.
If all these checks pass, then for every
\((\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}\!\)
@@ -246,7 +246,7 @@
Value Balance Verification
-
In order to verify the balance of the different Assets, the verifier MUST perform a similar process as for the Orchard protocol 18, with the addition of the burn information.
+
In order to verify the balance of the different Assets, the verifier MUST perform a similar process as for the Orchard protocol 19, with the addition of the burn information.
For a total of
\(n\)
Actions in a transfer, the prover MUST still sign the SIGHASH transaction hash using the binding signature key
@@ -269,7 +269,7 @@
the set of indices of Actions that are related to Custom Assets.
The right hand side of the value balance verification equation can be expanded to:
This equation contains the balance check of the Orchard protocol 18. With ZSA, transfer Actions for Custom Assets must also be balanced across Asset Bases. All Custom Assets are contained within the shielded pool, and cannot be unshielded via a regular transfer. Custom Assets can be burnt, the mechanism for which reveals the amount and identifier of the Asset being burnt, within the
+
This equation contains the balance check of the Orchard protocol 19. With ZSA, transfer Actions for Custom Assets must also be balanced across Asset Bases. All Custom Assets are contained within the shielded pool, and cannot be unshielded via a regular transfer. Custom Assets can be burnt, the mechanism for which reveals the amount and identifier of the Asset being burnt, within the
\(\mathsf{assetBurn}\)
set. As such, for a correctly constructed transaction, we will get
\(\sum_{j \in S_{\mathsf{CA}}} \mathsf{cv}^{\mathsf{net}}_j - \sum_{(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}} [\mathsf{v}]\,\mathsf{AssetBase} = \sum_{j \in S_{\mathsf{CA}}} [\mathsf{rcv}^{\mathsf{net}}_j]\,\mathcal{R}^{\mathsf{Orchard}}\!\)
@@ -318,11 +318,11 @@
\(\mathbb{F}_{q_{\mathbb{P}}}\!\)
,
\(\mathcal{K}^{\mathsf{Orchard}}\)
- is the Orchard Nullifier Base as defined in 19, and
+ is the Orchard Nullifier Base as defined in 20, and
\(\mathcal{L}^{\mathsf{Orchard}} := \mathsf{GroupHash^{\mathbb{P}}}(\texttt{"z.cash:Orchard"}, \texttt{"L"})\!\)
.
Rationale for Split Notes
-
In the Orchard protocol, since each Action represents an input and an output, the transaction that wants to send one input to multiple outputs must have multiple inputs. The Orchard protocol gives dummy spend notes17 to the Actions that have not been assigned input notes.
+
In the Orchard protocol, since each Action represents an input and an output, the transaction that wants to send one input to multiple outputs must have multiple inputs. The Orchard protocol gives dummy spend notes18 to the Actions that have not been assigned input notes.
The Orchard technique requires modification for the ZSA protocol with multiple Asset Identifiers, as the output note of the split Actions cannot contain just any Asset Base. We must enforce it to be an actual output of a GroupHash computation (in fact, we want it to be of the same Asset Base as the original input note, but the binding signature takes care that the proper balancing is performed). Without this enforcement the prover could input a multiple (or linear combination) of an existing Asset Base, and thereby attack the network by overflowing the ZEC value balance and hence counterfeiting ZEC funds.
Therefore, for Custom Assets we enforce that every input note to an ZSA Action must be proven to exist in the set of note commitments in the note commitment tree. We then enforce this real note to be “unspendable” in the sense that its value will be zeroed in split Actions and the nullifier will be randomized, making the note not spendable in the specific Action. Then, the proof itself ensures that the output note is of the same Asset Base as the input note. In the circuit, the split note functionality will be activated by a boolean private input to the proof (aka the
\(\mathsf{split\_flag}\)
@@ -331,8 +331,8 @@
Circuit Statement
-
Every ZSA Action statement is closely similar to the Orchard Action statement 20, except for a few additions that ensure the security of the Asset Identifier system. We detail these changes below.
-
All modifications in the Circuit are detailed in 31.
+
Every ZSA Action statement is closely similar to the Orchard Action statement 21, except for a few additions that ensure the security of the Asset Identifier system. We detail these changes below.
+
All modifications in the Circuit are detailed in 32.
Asset Base Equality
The following constraints must be added to ensure that the input and output note are of the same
\(\mathsf{AssetBase}\!\)
@@ -341,12 +341,12 @@
The Asset Base,
\(\mathsf{AssetBase_{AssetId}}\!\)
, for the note is witnessed once, as an auxiliary input.
-
In the Old note commitment integrity constraint in the Orchard Action statement 20,
+
In the Old note commitment integrity constraint in the Orchard Action statement 21,
\(\mathsf{NoteCommit^{Orchard}_{rcm^{old}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{old}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{old}}), \mathsf{v^{old}}, \text{ρ}^{\mathsf{old}}, \text{ψ}^{\mathsf{old}})\)
is replaced with
\(\mathsf{NoteCommit^{OrchardZSA}_{rcm^{old}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{old}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{old}}), \mathsf{v^{old}}, \text{ρ}^{\mathsf{old}}, \text{ψ}^{\mathsf{old}}, \mathsf{AssetBase_{AssetId}})\!\)
.
-
In the New note commitment integrity constraint in the Orchard Action statement 20,
+
In the New note commitment integrity constraint in the Orchard Action statement 21,
\(\mathsf{NoteCommit^{Orchard}_{rcm^{new}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{new}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{new}}), \mathsf{v^{new}}, \text{ρ}^{\mathsf{new}}, \text{ψ}^{\mathsf{new}})\)
is replaced with
\(\mathsf{NoteCommit^{OrchardZSA}_{rcm^{new}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{new}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{new}}), \mathsf{v^{new}}, \text{ρ}^{\mathsf{new}}, \text{ψ}^{\mathsf{new}}, \mathsf{AssetBase_{AssetId}})\!\)
@@ -463,15 +463,15 @@
The
Backwards Compatibility with ZEC Notes
-
The input note in the old note commitment integrity check must either include an Asset Base (ZSA note) or not (pre-ZSA Orchard note). If the note is a pre-ZSA Orchard note, the note commitment is computed in the original Orchard fashion 16. If the note is a ZSA note, the note commitment is computed as defined in the Note Structure & Commitment section.
+
The input note in the old note commitment integrity check must either include an Asset Base (ZSA note) or not (pre-ZSA Orchard note). If the note is a pre-ZSA Orchard note, the note commitment is computed in the original Orchard fashion 17. If the note is a ZSA note, the note commitment is computed as defined in the Note Structure & Commitment section.
Orchard-ZSA Transaction Structure
-
The transaction format for v6 transactions is described in ZIP 230 10.
+
The transaction format for v6 transactions is described in ZIP 230 11.
TxId Digest
-
The transaction digest algorithm defined in ZIP 244 11 is modified by the ZSA protocol to add a new branch for issuance information, along with modifications within the orchard_digest to account for the inclusion of the Asset Base. The details of these changes are described in this section, and highlighted using the [UPDATED FOR ZSA] or [ADDED FOR ZSA] text label. We omit the details of the sections that do not change for the ZSA protocol.
+
The transaction digest algorithm defined in ZIP 244 12 is modified by the ZSA protocol to add a new branch for issuance information, along with modifications within the orchard_digest to account for the inclusion of the Asset Base. The details of these changes are described in this section, and highlighted using the [UPDATED FOR ZSA] or [ADDED FOR ZSA] text label. We omit the details of the sections that do not change for the ZSA protocol.
The
T.4f: valueBalanceOrchard (64-bit signed little-endian)
T.4g: anchorOrchard (32 bytes)
T.4a: orchard_actions_compact_digest
-
A BLAKE2b-256 hash of the subset of Orchard Action information intended to be included in an updated version of the ZIP-307 12CompactBlock format for all Orchard Actions belonging to the transaction. For each Action, the following elements are included in the hash:
+
A BLAKE2b-256 hash of the subset of Orchard Action information intended to be included in an updated version of the ZIP-307 13CompactBlock format for all Orchard Actions belonging to the transaction. For each Action, the following elements are included in the hash:
A BLAKE2b-256 hash of the remaining subset of Orchard Action information not intended for inclusion in an updated version of the the ZIP 307 12CompactBlock format, for all Orchard Actions belonging to the transaction. For each Action, the following elements are included in the hash:
+
A BLAKE2b-256 hash of the remaining subset of Orchard Action information not intended for inclusion in an updated version of the the ZIP 307 13CompactBlock format, for all Orchard Actions belonging to the transaction. For each Action, the following elements are included in the hash:
T.4d.i : cv (field encoding bytes)
T.4d.ii : rk (field encoding bytes)
T.4d.iii: encCiphertext[596..] (post-memo suffix of field encoding) [UPDATED FOR ZSA]
@@ -534,12 +534,12 @@
The
T.5: issuance_digest
-
The details of the computation of this value are in ZIP 227 7.
+
The details of the computation of this value are in ZIP 227 8.
Signature Digest and Authorizing Data Commitment
-
The details of the changes to these algorithms are in ZIP 227 89.
+
The details of the changes to these algorithms are in ZIP 227 910.
Security and Privacy Considerations
@@ -552,7 +552,7 @@
The
Other Considerations
Transaction Fees
-
The fee mechanism for the upgrades proposed in this ZIP will follow the mechanism described in ZIP 317 for the ZSA protocol upgrade 13.
+
The fee mechanism for the upgrades proposed in this ZIP will follow the mechanism described in ZIP 317 for the ZSA protocol upgrade 14.
Backward Compatibility
In order to have backward compatibility with the ZEC notes, we have designed the circuit to support both ZEC and ZSA notes. As we specify above, there are three main reasons we can do this:
diff --git a/rendered/zip-0227.html b/rendered/zip-0227.html
index 1bf686866..4081d95a2 100644
--- a/rendered/zip-0227.html
+++ b/rendered/zip-0227.html
@@ -316,46 +316,38 @@
\(\mathsf{issued\_assets}\!\)
, from the Asset Digest,
\(\mathsf{AssetDigest}\)
- corresponding to an Asset Identifier
- \(\mathsf{AId}\)
, to a tuple
- \((\mathsf{balance_{AId}}, \mathsf{final_{AId}})\)
- , for every Asset that has been issued up until the block boundary.
+ \((\mathsf{balance}, \mathsf{final})\!\)
+ , for every Asset that has been issued up until the block boundary. For each Asset:
The amount of the Asset in circulation, computed as the amount of the Asset that has been issued less the amount of the Asset that has been burnt, is stored in
- \(\mathsf{balance_{AId}}\)
+ \(\mathsf{balance}\!\)
.
The boolean
- \(\mathsf{final_{AId}}\)
+ \(\mathsf{final}\)
stores the finalization status of the Asset (i.e.: whether the
\(\mathsf{finalize}\)
flag has been set to
\(1\)
- in some issuance transaction for Asset
- \(\mathsf{AId}\)
- preceding the block boundary).
+ in some issuance transaction for the Asset preceding the block boundary).
We use the notation
- \(\mathsf{issued\_assets}(AssetDigest)\)
- to refer to the tuple,
- \((\mathsf{balance_{AId}}, \mathsf{final_{AId}})\)
- . Further, we use the notation
- \(\mathsf{issued\_assets}(AssetDigest).balance\)
+ \(\mathsf{issued\_assets}(\mathsf{AssetDigest}).\!\mathsf{balance}\)
and
- \(\mathsf{issued\_assets}(AssetDigest).final\)
- to refer to the balance and finalization status of the Asset, respectively.
+ \(\mathsf{issued\_assets}(\mathsf{AssetDigest}).\!\mathsf{final}\)
+ to access, respectively, the balance and finalization status of the Asset stored in the global state.
Rationale for Global Issuance State
It is necessary to ensure that the balance of any issued Custom Asset never becomes negative within a shielded pool, along the lines of ZIP 209 8. However, unlike for the shielded ZEC pools, there is no individual transaction field that directly corresponds to both the issued and burnt amounts for a given Asset. Therefore, we require that all nodes maintain a record of the current amount in circulation for every issued Custom Asset, and update this record at the block boundary based on the issuance and burn transactions within the block. This allows for efficient detection of balance violations for any Asset, in which scenario we specify a consensus rule to reject the block.
Nodes also need to ensure the rejection of blocks in which issuance of Custom Assets that have been previously finalized. The
- \(\mathsf{issued\_assets}\!\)
+ \(\mathsf{issued\_assets}\)
map allows nodes to store whether or not a given Asset has been finalized.
Note that while there is only a single pool for ZSAs, the
\(\mathsf{issued\_assets}\)
- map can be as specified above, but in future when there are multiple pools, the map will need to be extended to store the balance for the Asset in each pool. That is, the map will be from the Asset Digest
- \(\mathsf{AssetDigest}\)
- to a tuple of the form
- \(((\mathsf{balance_{AId}^{OrchardZSA}}, \mathsf{balance_{AId}^{NewPool}}, \ldots), \mathsf{final_{AId}})\)
- , with one balance entry for each pool that supports ZSAs.
+ map can be as specified above, but in future when there are multiple pools, the map will need to be extended to store the balance for the Asset in each pool. The map will be from a tuple of the Asset Digest and an identifier for a shielded pool that supports ZSAs,
+ \((\mathsf{AssetDigest}, \mathsf{Pool})\!\)
+ , to a tuple of the form
+ \((\mathsf{balance}, \mathsf{final})\!\)
+ , where the balance is for the specific shielded pool.
Specification: Issuance Action, Issuance Bundle and Issuance Protocol
diff --git a/zips/zip-0226.rst b/zips/zip-0226.rst
index 6b7d3d37d..837c2fef0 100644
--- a/zips/zip-0226.rst
+++ b/zips/zip-0226.rst
@@ -185,7 +185,7 @@ Additional Consensus Rules
1. Check that for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{AssetBase} \neq \mathcal{V}^{\mathsf{Orchard}}\!`. That is, ZEC or TAZ is not allowed to be burnt by this mechanism.
2. Check that for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{v} \neq 0\!`.
3. Check that there is no duplication of Custom Assets in the :math:`\mathsf{assetBurn}` set. That is, every :math:`\mathsf{AssetBase}` has at most one entry in :math:`\mathsf{assetBurn}\!`.
-4. Check that for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}\!`, :math:`\mathsf{v} \leq \mathsf{issued\_assets(AssetDigest).balance}\!`, where the map :math:`\mathsf{issued\_assets}` is defined in ZIP 227 [#zip-0227]_. That is, it is not possible to burn more of an Asset than is currently in circulation.
+4. Check that for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}\!`, :math:`\mathsf{v} \leq \mathsf{issued\_assets(AssetDigest).balance}\!`, where the map :math:`\mathsf{issued\_assets}` is defined in ZIP 227 [#zip-0227-specification-global-issuance-state]_. That is, it is not possible to burn more of an Asset than is currently in circulation.
If all these checks pass, then for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}\!`, reduce the value of :math:`\mathsf{issued\_assets(AssetDigest).balance}` in the global state by :math:`\mathsf{v}\!`.
@@ -494,6 +494,7 @@ References
.. [#zip-0209] `ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances `_
.. [#zip-0224] `ZIP 224: Orchard `_
.. [#zip-0227] `ZIP 227: Issuance of Zcash Shielded Assets `_
+.. [#zip-0227-specification-global-issuance-state] `ZIP 227: Issuance of Zcash Shielded Assets: Specification: Global Issuance State `_
.. [#zip-0227-assetidentifier] `ZIP 227: Issuance of Zcash Shielded Assets: Specification: Asset Identifier `_
.. [#zip-0227-txiddigest] `ZIP 227: Issuance of Zcash Shielded Assets: TxId Digest - Issuance `_
.. [#zip-0227-sigdigest] `ZIP 227: Issuance of Zcash Shielded Assets: Signature Digest `_
diff --git a/zips/zip-0227.rst b/zips/zip-0227.rst
index 621f23837..cf5f56ee3 100644
--- a/zips/zip-0227.rst
+++ b/zips/zip-0227.rst
@@ -221,13 +221,12 @@ Specification: Global Issuance State
Issuance requires the following additions to the global state defined at block boundaries:
-A map, :math:`\mathsf{issued\_assets}\!`, from the Asset Digest, :math:`\mathsf{AssetDigest}` corresponding to an Asset Identifier :math:`\mathsf{AId}`, to a tuple :math:`(\mathsf{balance_{AId}}, \mathsf{final_{AId}})`, for every Asset that has been issued up until the block boundary.
+A map, :math:`\mathsf{issued\_assets}\!`, from the Asset Digest, :math:`\mathsf{AssetDigest}`, to a tuple :math:`(\mathsf{balance}, \mathsf{final})\!`, for every Asset that has been issued up until the block boundary. For each Asset:
-- The amount of the Asset in circulation, computed as the amount of the Asset that has been issued less the amount of the Asset that has been burnt, is stored in :math:`\mathsf{balance_{AId}}`.
-- The boolean :math:`\mathsf{final_{AId}}` stores the finalization status of the Asset (i.e.: whether the :math:`\mathsf{finalize}` flag has been set to :math:`1` in some issuance transaction for Asset :math:`\mathsf{AId}` preceding the block boundary).
+- The amount of the Asset in circulation, computed as the amount of the Asset that has been issued less the amount of the Asset that has been burnt, is stored in :math:`\mathsf{balance}\!`.
+- The boolean :math:`\mathsf{final}` stores the finalization status of the Asset (i.e.: whether the :math:`\mathsf{finalize}` flag has been set to :math:`1` in some issuance transaction for the Asset preceding the block boundary).
-We use the notation :math:`\mathsf{issued\_assets}(AssetDigest)` to refer to the tuple, :math:`(\mathsf{balance_{AId}}, \mathsf{final_{AId}})`.
-Further, we use the notation :math:`\mathsf{issued\_assets}(AssetDigest).balance` and :math:`\mathsf{issued\_assets}(AssetDigest).final` to refer to the balance and finalization status of the Asset, respectively.
+We use the notation :math:`\mathsf{issued\_assets}(\mathsf{AssetDigest}).\!\mathsf{balance}` and :math:`\mathsf{issued\_assets}(\mathsf{AssetDigest}).\!\mathsf{final}` to access, respectively, the balance and finalization status of the Asset stored in the global state.
Rationale for Global Issuance State
-----------------------------------
@@ -238,10 +237,10 @@ Therefore, we require that all nodes maintain a record of the current amount in
This allows for efficient detection of balance violations for any Asset, in which scenario we specify a consensus rule to reject the block.
Nodes also need to ensure the rejection of blocks in which issuance of Custom Assets that have been previously finalized.
-The :math:`\mathsf{issued\_assets}\!` map allows nodes to store whether or not a given Asset has been finalized.
+The :math:`\mathsf{issued\_assets}` map allows nodes to store whether or not a given Asset has been finalized.
Note that while there is only a single pool for ZSAs, the :math:`\mathsf{issued\_assets}` map can be as specified above, but in future when there are multiple pools, the map will need to be extended to store the balance for the Asset in each pool.
-That is, the map will be from the Asset Digest :math:`\mathsf{AssetDigest}` to a tuple of the form :math:`((\mathsf{balance_{AId}^{OrchardZSA}}, \mathsf{balance_{AId}^{NewPool}}, \ldots), \mathsf{final_{AId}})`, with one balance entry for each pool that supports ZSAs.
+The map will be from a tuple of the Asset Digest and an identifier for a shielded pool that supports ZSAs, :math:`(\mathsf{AssetDigest}, \mathsf{Pool})\!`, to a tuple of the form :math:`(\mathsf{balance}, \mathsf{final})\!`, where the balance is for the specific shielded pool.
Specification: Issuance Action, Issuance Bundle and Issuance Protocol
=====================================================================
From d3a93fc38269f8b0a324248d569df07c65132fe2 Mon Sep 17 00:00:00 2001
From: Vivek Arte
Date: Tue, 13 Aug 2024 15:43:05 +0530
Subject: [PATCH 4/4] adding updates based on discussion
---
rendered/zip-0226.html | 4 ++--
rendered/zip-0227.html | 44 ++++++++++++++----------------------------
zips/zip-0226.rst | 4 ++--
zips/zip-0227.rst | 20 +++++++------------
4 files changed, 25 insertions(+), 47 deletions(-)
diff --git a/rendered/zip-0226.html b/rendered/zip-0226.html
index 8003fc738..5fdacb6ce 100644
--- a/rendered/zip-0226.html
+++ b/rendered/zip-0226.html
@@ -230,7 +230,7 @@
Check that for every
\((\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}\!\)
,
- \(\mathsf{v} \leq \mathsf{issued\_assets(AssetDigest).balance}\!\)
+ \(\mathsf{v} \leq \mathsf{issued\_assets(AssetBase).balance}\!\)
, where the map
\(\mathsf{issued\_assets}\)
is defined in ZIP 227 6. That is, it is not possible to burn more of an Asset than is currently in circulation.
@@ -238,7 +238,7 @@
If all these checks pass, then for every
\((\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}\!\)
, reduce the value of
- \(\mathsf{issued\_assets(AssetDigest).balance}\)
+ \(\mathsf{issued\_assets(AssetBase).balance}\)
in the global state by
\(\mathsf{v}\!\)
.
Issuance requires the following additions to the global state defined at block boundaries:
A map,
\(\mathsf{issued\_assets}\!\)
- , from the Asset Digest,
- \(\mathsf{AssetDigest}\)
+ , from the Asset Base,
+ \(\mathsf{AssetBase}\)
, to a tuple
\((\mathsf{balance}, \mathsf{final})\!\)
, for every Asset that has been issued up until the block boundary. For each Asset:
@@ -329,25 +329,24 @@
\(\mathsf{finalize}\)
flag has been set to
\(1\)
- in some issuance transaction for the Asset preceding the block boundary).
+ in some issuance transaction for the Asset preceding the block boundary). The value of
+ \(\mathsf{final}\)
+ for any Asset cannot be changed from
+ \(1\)
+ to
+ \(0\)
+ .
We use the notation
- \(\mathsf{issued\_assets}(\mathsf{AssetDigest}).\!\mathsf{balance}\)
+ \(\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{balance}\)
and
- \(\mathsf{issued\_assets}(\mathsf{AssetDigest}).\!\mathsf{final}\)
+ \(\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{final}\)
to access, respectively, the balance and finalization status of the Asset stored in the global state.
Rationale for Global Issuance State
It is necessary to ensure that the balance of any issued Custom Asset never becomes negative within a shielded pool, along the lines of ZIP 209 8. However, unlike for the shielded ZEC pools, there is no individual transaction field that directly corresponds to both the issued and burnt amounts for a given Asset. Therefore, we require that all nodes maintain a record of the current amount in circulation for every issued Custom Asset, and update this record at the block boundary based on the issuance and burn transactions within the block. This allows for efficient detection of balance violations for any Asset, in which scenario we specify a consensus rule to reject the block.
Nodes also need to ensure the rejection of blocks in which issuance of Custom Assets that have been previously finalized. The
\(\mathsf{issued\_assets}\)
map allows nodes to store whether or not a given Asset has been finalized.
-
Note that while there is only a single pool for ZSAs, the
- \(\mathsf{issued\_assets}\)
- map can be as specified above, but in future when there are multiple pools, the map will need to be extended to store the balance for the Asset in each pool. The map will be from a tuple of the Asset Digest and an identifier for a shielded pool that supports ZSAs,
- \((\mathsf{AssetDigest}, \mathsf{Pool})\!\)
- , to a tuple of the form
- \((\mathsf{balance}, \mathsf{final})\!\)
- , where the balance is for the specific shielded pool.
Specification: Issuance Action, Issuance Bundle and Issuance Protocol
@@ -365,21 +364,6 @@
\(\mathsf{finalize}\)
boolean that defines whether the issuance of that specific Custom Asset is finalized or not.
-
The value of
- \(\mathsf{issued\_assets}(AssetDigest).final\)
- is set to
- \(1\)
- after a block that contains any issuance transaction for the Asset corresponding to
- \(\mathsf{AssetDigest}`\)
- with
- \(\mathsf{finalize} = 1\!\)
- . The value of
- \(\mathsf{issued\_assets}(AssetDigest).final\)
- cannot be changed from
- \(1\)
- to
- \(0\)
- .
An asset's
\(\mathsf{AssetDigest}\)
is added to the
@@ -593,7 +577,7 @@
\(\mathsf{asset\_desc}\)
as described in the Specification: Asset Identifier section.
check that
- \(\mathsf{issued\_assets(AssetDigest).final} \neq 1\)
+ \(\mathsf{issued\_assets(AssetBase).final} \neq 1\)
in the global state.
check that every note in the IssueAction contains the same
\(\mathsf{AssetBase}\)
@@ -612,7 +596,7 @@
\(\mathsf{cm}\)
to the Merkle tree of note commitments.
Increase the value of
- \(\mathsf{issued\_assets(AssetDigest).balance}\)
+ \(\mathsf{issued\_assets(AssetBase).balance}\)
by the value of the note,
\(\mathsf{v}\)
.
@@ -621,7 +605,7 @@
If
\(\mathsf{finalize} = 1\!\)
, set
- \(\mathsf{issued\_assets(AssetDigest).final}\)
+ \(\mathsf{issued\_assets(AssetBase).final}\)
to
\(1\)
in the global state immediately after the block in which this transaction occurs.
diff --git a/zips/zip-0226.rst b/zips/zip-0226.rst
index 837c2fef0..34341c0bd 100644
--- a/zips/zip-0226.rst
+++ b/zips/zip-0226.rst
@@ -185,9 +185,9 @@ Additional Consensus Rules
1. Check that for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{AssetBase} \neq \mathcal{V}^{\mathsf{Orchard}}\!`. That is, ZEC or TAZ is not allowed to be burnt by this mechanism.
2. Check that for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{v} \neq 0\!`.
3. Check that there is no duplication of Custom Assets in the :math:`\mathsf{assetBurn}` set. That is, every :math:`\mathsf{AssetBase}` has at most one entry in :math:`\mathsf{assetBurn}\!`.
-4. Check that for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}\!`, :math:`\mathsf{v} \leq \mathsf{issued\_assets(AssetDigest).balance}\!`, where the map :math:`\mathsf{issued\_assets}` is defined in ZIP 227 [#zip-0227-specification-global-issuance-state]_. That is, it is not possible to burn more of an Asset than is currently in circulation.
+4. Check that for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}\!`, :math:`\mathsf{v} \leq \mathsf{issued\_assets(AssetBase).balance}\!`, where the map :math:`\mathsf{issued\_assets}` is defined in ZIP 227 [#zip-0227-specification-global-issuance-state]_. That is, it is not possible to burn more of an Asset than is currently in circulation.
-If all these checks pass, then for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}\!`, reduce the value of :math:`\mathsf{issued\_assets(AssetDigest).balance}` in the global state by :math:`\mathsf{v}\!`.
+If all these checks pass, then for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}\!`, reduce the value of :math:`\mathsf{issued\_assets(AssetBase).balance}` in the global state by :math:`\mathsf{v}\!`.
**Note:** Even if this mechanism allows having transparent ↔ shielded Asset transfers in theory, the transparent protocol will not be changed with this ZIP to adapt to a multiple Asset structure. This means that unless future consensus rules changes do allow it, unshielding will not be possible for Custom Assets.
diff --git a/zips/zip-0227.rst b/zips/zip-0227.rst
index cf5f56ee3..3da87f248 100644
--- a/zips/zip-0227.rst
+++ b/zips/zip-0227.rst
@@ -221,12 +221,13 @@ Specification: Global Issuance State
Issuance requires the following additions to the global state defined at block boundaries:
-A map, :math:`\mathsf{issued\_assets}\!`, from the Asset Digest, :math:`\mathsf{AssetDigest}`, to a tuple :math:`(\mathsf{balance}, \mathsf{final})\!`, for every Asset that has been issued up until the block boundary. For each Asset:
+A map, :math:`\mathsf{issued\_assets}\!`, from the Asset Base, :math:`\mathsf{AssetBase}`, to a tuple :math:`(\mathsf{balance}, \mathsf{final})\!`, for every Asset that has been issued up until the block boundary. For each Asset:
- The amount of the Asset in circulation, computed as the amount of the Asset that has been issued less the amount of the Asset that has been burnt, is stored in :math:`\mathsf{balance}\!`.
-- The boolean :math:`\mathsf{final}` stores the finalization status of the Asset (i.e.: whether the :math:`\mathsf{finalize}` flag has been set to :math:`1` in some issuance transaction for the Asset preceding the block boundary).
+- The boolean :math:`\mathsf{final}` stores the finalization status of the Asset (i.e.: whether the :math:`\mathsf{finalize}` flag has been set to :math:`1` in some issuance transaction for the Asset preceding the block boundary). The value of :math:`\mathsf{final}` for any Asset cannot be changed from :math:`1` to :math:`0`.
-We use the notation :math:`\mathsf{issued\_assets}(\mathsf{AssetDigest}).\!\mathsf{balance}` and :math:`\mathsf{issued\_assets}(\mathsf{AssetDigest}).\!\mathsf{final}` to access, respectively, the balance and finalization status of the Asset stored in the global state.
+
+We use the notation :math:`\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{balance}` and :math:`\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{final}` to access, respectively, the balance and finalization status of the Asset stored in the global state.
Rationale for Global Issuance State
-----------------------------------
@@ -239,9 +240,6 @@ This allows for efficient detection of balance violations for any Asset, in whic
Nodes also need to ensure the rejection of blocks in which issuance of Custom Assets that have been previously finalized.
The :math:`\mathsf{issued\_assets}` map allows nodes to store whether or not a given Asset has been finalized.
-Note that while there is only a single pool for ZSAs, the :math:`\mathsf{issued\_assets}` map can be as specified above, but in future when there are multiple pools, the map will need to be extended to store the balance for the Asset in each pool.
-The map will be from a tuple of the Asset Digest and an identifier for a shielded pool that supports ZSAs, :math:`(\mathsf{AssetDigest}, \mathsf{Pool})\!`, to a tuple of the form :math:`(\mathsf{balance}, \mathsf{final})\!`, where the balance is for the specific shielded pool.
-
Specification: Issuance Action, Issuance Bundle and Issuance Protocol
=====================================================================
@@ -255,10 +253,6 @@ An issuance action, ``IssueAction``, is the instance of issuing a specific Custo
- ``vNotes``: an array of ``Note`` containing the unencrypted output notes of the recipients of the Asset.
- ``flagsIssuance``: a byte that stores the :math:`\mathsf{finalize}` boolean that defines whether the issuance of that specific Custom Asset is finalized or not.
-The value of :math:`\mathsf{issued\_assets}(AssetDigest).final` is set to :math:`1` after a block that contains any issuance transaction for the Asset corresponding to :math:`\mathsf{AssetDigest}`` with :math:`\mathsf{finalize} = 1\!`.
-The value of :math:`\mathsf{issued\_assets}(AssetDigest).final` cannot be changed from :math:`1` to :math:`0`.
-
-
An asset's :math:`\mathsf{AssetDigest}` is added to the :math:`\mathsf{previously\_finalized}` set after a block that contains any issuance transaction for that asset with :math:`\mathsf{finalize} = 1\!`. It then cannot be removed from this set. For Assets with :math:`\mathsf{AssetDigest} \in \mathsf{previously\_finalized}\!`, no further tokens can be issued, so as seen below, the validators will reject the transaction. For Assets with :math:`\mathsf{AssetDigest} \not\in \mathsf{previously\_finalized}\!`, new issuance actions can be issued in future transactions. These must use the same Asset description, :math:`\mathsf{asset\_desc}\!`, and can either maintain :math:`\mathsf{finalize} = 0` or change it to :math:`\mathsf{finalize} = 1\!`, denoting that this Custom Asset cannot be issued after the containing block.
@@ -350,7 +344,7 @@ For each ``IssueAction`` in ``IssueBundle``:
- check that :math:`\mathsf{asset\_desc}` is a string of length :math:`\mathtt{assetDescSize}` bytes.
- retrieve :math:`\mathsf{AssetBase}` from the first note in the sequence and check that :math:`\mathsf{AssetBase}` is derived from the issuance validating key :math:`\mathsf{ik}` and :math:`\mathsf{asset\_desc}` as described in the `Specification: Asset Identifier`_ section.
-- check that :math:`\mathsf{issued\_assets(AssetDigest).final} \neq 1` in the global state.
+- check that :math:`\mathsf{issued\_assets(AssetBase).final} \neq 1` in the global state.
- check that every note in the ``IssueAction`` contains the same :math:`\mathsf{AssetBase}` and is properly constructed as :math:`\mathsf{note} = (\mathsf{g_d}, \mathsf{pk_d}, \mathsf{v}, \text{ρ}, \mathsf{rseed}, \mathsf{AssetBase})\!`.
If all of the above checks pass, do the following:
@@ -359,9 +353,9 @@ If all of the above checks pass, do the following:
- compute the note commitment as :math:`\mathsf{cm} = \mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase})` as defined in the Note Structure and Commitment section of ZIP 226 [#zip-0226-notestructure]_.
- Add :math:`\mathsf{cm}` to the Merkle tree of note commitments.
- - Increase the value of :math:`\mathsf{issued\_assets(AssetDigest).balance}` by the value of the note, :math:`\mathsf{v}`.
+ - Increase the value of :math:`\mathsf{issued\_assets(AssetBase).balance}` by the value of the note, :math:`\mathsf{v}`.
-- If :math:`\mathsf{finalize} = 1\!`, set :math:`\mathsf{issued\_assets(AssetDigest).final}` to :math:`1` in the global state immediately after the block in which this transaction occurs.
+- If :math:`\mathsf{finalize} = 1\!`, set :math:`\mathsf{issued\_assets(AssetBase).final}` to :math:`1` in the global state immediately after the block in which this transaction occurs.
- (Replay Protection) If issue bundle is present, the fees MUST be greater than zero.