ZIP: 227 Title: Issuance of Zcash Shielded Assets Owners: Pablo Kogan <pablo@qed-it.com> Vivek Arte <vivek@qed-it.com> Daira-Emma Hopwood <daira-emma@electriccoin.co> Jack Grigg <str4d@electriccoin.co> Credits: Daniel Benarroch Aurelien Nicolas Deirdre Connolly Teor Status: Draft Category: Consensus Created: 2022-05-01 License: MIT Discussions-To: <https://github.com/zcash/zips/issues/618> Pull-Request: <https://github.com/zcash/zips/pull/680>
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 9.
We define the following additional terms:
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.
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.
The design presented in this ZIP enables issuance of shielded Assets in various modes:
See the Concrete Applications section for more details.
For every new Asset, there must be a new and unique Asset Identifier, denoted \(\mathsf{AssetId}\!\) . We define this to be a globally unique pair \(\mathsf{AssetId} := (\mathsf{ik}, \mathsf{asset\_desc})\!\) , where \(\mathsf{ik}\) is the issuance key and \(\mathsf{asset\_desc}\) is a byte string.
A given Asset Identifier is used across all Zcash protocols that support ZSAs -- that is, the Orchard-ZSA protocol and potentially future Zcash shielded protocols. For this Asset Identifier, we derive an Asset Digest, \(\mathsf{AssetDigest}\!\) , which is simply is a \(\textsf{BLAKE2b-512}\) hash of the Asset Identifier. From the Asset Digest, we derive a specific Asset Base within each shielded protocol using the applicable hash-to-curve algorithm. This Asset Base is included in shielded notes.
Let
Define \(\mathsf{AssetDigest_{AssetId}} := \textsf{BLAKE2b-512}(\texttt{“ZSA-Asset-Digest”},\; \mathsf{EncodeAssetId}(\mathsf{AssetId}))\!\) , where
Define \(\mathsf{AssetBase_{AssetId}} := \mathsf{ZSAValueBase}(\mathsf{AssetDigest_{AssetId}})\)
In the case of the Orchard-ZSA protocol, we define \(\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 22.
The relations between the Asset Identifier, Asset Digest, and Asset Base are shown in the following diagram:
Note: To keep notations light and concise, we may omit \(\mathsf{AssetId}\) (resp. \(\mathsf{Protocol}\!\) ) in the subscript (resp. superscript) when the Asset Identifier (resp. Protocol) is clear from the context.
Wallets MUST NOT display just the \(\mathsf{asset\_desc}\) string to their users as the name of the Asset. Some possible alternatives include:
Issuance requires the following additions to the global state defined at block boundaries:
A map, \(\mathsf{issued\_assets}\!\) , 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:
We use the notation \(\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{balance}\) and \(\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{final}\) to access, respectively, the balance and finalization status of the Asset stored in the global 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.
An issuance action, IssueAction
, is the instance of issuing a specific Custom Asset, and contains the following fields:
assetDescSize
: the size of the Asset description, a number between
\(0\)
and
\(512\!\)
, stored in two bytes.asset_desc
: the Asset description, a byte string of up to 512 bytes as defined in the Specification: Asset Identifier section.vNotes
: an array of Note
containing the unencrypted output notes of the recipients of the Asset.flagsIssuance
: a byte that stores the
\(\mathsf{finalize}\)
boolean that defines whether the issuance of that specific Custom Asset is finalized or not.An asset's \(\mathsf{AssetDigest}\) is added to the \(\mathsf{previously\_finalized}\) set after a block that contains any issuance transaction for that asset with \(\mathsf{finalize} = 1\!\) . It then cannot be removed from this set. For Assets with \(\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 \(\mathsf{AssetDigest} \not\in \mathsf{previously\_finalized}\!\) , new issuance actions can be issued in future transactions. These must use the same Asset description, \(\mathsf{asset\_desc}\!\) , and can either maintain \(\mathsf{finalize} = 0\) or change it to \(\mathsf{finalize} = 1\!\) , denoting that this Custom Asset cannot be issued after the containing block.
Bytes | Name | Data Type | Description |
---|---|---|---|
2 |
assetDescSize |
byte |
The length of the asset_desc string in bytes. |
assetDescSize |
asset_desc |
byte[assetDescSize] |
A byte sequence of length assetDescSize bytes which SHOULD be a well-formed UTF-8 code unit sequence according to Unicode 15.0.0 or later. |
varies |
nNotes |
compactSize |
The number of notes in the issuance action. |
noteSize * nNotes |
vNotes |
Note[nNotes] |
A sequence of note descriptions within the issuance action, where noteSize is the size, in bytes, of a Note. |
1 |
flagsIssuance |
byte |
|
We note that the output note commitment of the recipient's notes are not included in the actual transaction, but when added to the global state of the chain, they will be added to the note commitment tree as a shielded note. This prevents future usage of the note from being linked to the issuance transaction, as the nullifier key is not known to the validators and chain observers.
An issuance bundle, IssueBundle
, is the aggregate of all the issuance-related information. Specifically, contains all the issuance actions and the issuer signature on the transaction SIGHASH that validates the issuance itself. It contains the following fields:
vIssueActions
: an array of issuance actions, of type IssueAction
.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 24.
Bytes | Name | Data Type | Description |
---|---|---|---|
varies |
nIssueActions |
compactSize |
The number of issuance actions in the bundle. |
IssueActionSize * nIssueActions |
vIssueActions |
IssueAction[nIssueActions] |
A sequence of issuance action descriptions, where IssueActionSize is the size, in bytes, of an IssueAction description. |
32 |
ik |
byte[32] |
The issuance validating key of the issuer, used to validate the signature. |
64 |
issueAuthSig |
byte[64] |
The signature of the transaction SIGHASH, signed by the issuer, validated as in Issuance Authorization Signature Scheme. |
The issuer program performs the following operations:
For all actions IssueAction
:
IssueAction
into the vector vIssueActions
of the bundle.For the IssueBundle
:
vIssueActions
vector.Note: that the commitment is not included in the IssuanceAction
itself. As explained below, it is computed later by the validators and added to the note commitment tree.
For the IssueBundle
:
For each IssueAction
in IssueBundle
:
IssueAction
contains the same
\(\mathsf{AssetBase}\)
and is properly constructed as
\(\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:
The following is a list of rationale for different decisions made in the proposal:
Asset Features
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:
issuance_digest ├── issue_actions_digest │ ├── issue_notes_digest │ ├── assetDescription │ └── flagsIssuance └── issuanceValidatingKey
In the specification below, nodes of the tree are presented in depth-first order.
A BLAKE2b-256 hash of the following values
T.5a: issue_actions_digest (32-byte hash output) T.5b: issuanceValidatingKey (32 bytes)
The personalization field of this hash is set to:
"ZTxIdSAIssueHash"
In case the transaction has no issuance components, ''issuance_digest'' is:
BLAKE2b-256("ZTxIdSAIssueHash", [])
A BLAKE2b-256 hash of Issue Action information for all Issuance Actions belonging to the transaction. For each Action, the following elements are included in the hash:
T.5a.i : notes_digest (32-byte hash output) T.5a.ii : assetDescription (field encoding bytes) T.5a.iii: flagsIssuance (1 byte)
The personalization field of this hash is set to:
"ZTxIdIssuActHash"
A BLAKE2b-256 hash of Note information for all Notes belonging to the Issuance Action. For each Note, the following elements are included in the hash:
T.5a.i.1: recipient (field encoding bytes) T.5a.i.2: value (field encoding bytes) T.5a.i.3: assetBase (field encoding bytes) T.5a.i.4: rho (field encoding bytes) T.5a.i.5: rseed (field encoding bytes)
The personalization field of this hash is set to:
"ZTxIdIAcNoteHash"
In case the transaction has no Issue Notes, ''issue_notes_digest'' is:
BLAKE2b-256("ZTxIdIAcNoteHash", [])
This is the raw encoding of an Orchard shielded payment address as defined in the protocol specification 23.
Note value encoded as little-endian 8-byte representation of 64-bit unsigned integer (e.g. u64 in Rust) raw value.
Asset Base encoded as the 32-byte representation of a point on the Pallas curve.
Nullifier encoded as 32-byte representation of a point on the Pallas curve.
The ZIP 212 32-byte seed randomness for a note.
The Asset description byte string.
An 8-bit value representing a set of flags. Ordered from LSB to MSB:
A byte encoding of issuance validating key for the bundle as defined in the Issuance Key Derivation section.
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:
signature_digest ├── header_digest ├── transparent_sig_digest ├── sapling_digest ├── orchard_digest └── issuance_digest [ADDED FOR ZSA]
A BLAKE2b-256 hash of the following values
S.1: header_digest (32-byte hash output) S.2: transparent_sig_digest (32-byte hash output) S.3: sapling_digest (32-byte hash output) S.4: orchard_digest (32-byte hash output) S.5: issuance_digest (32-byte hash output) [ADDED FOR ZSA]
The personalization field remains the same as in ZIP 244 13.
Identical to that specified for the transaction identifier.
Wallets need to communicate the names of the Assets in a non-confusing way to users, since the byte representation of the Asset Identifier would be hard to read for an end user. Possible solutions are provided in the Specification: Asset Identifier section.
The design of this protocol does not currently allow for rotation of the issuance validating key that would allow for replacing the key of a specific Asset. In case of compromise, the following actions are recommended:
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.
Although not enforced in the global state, it is RECOMMENDED that Zcash full validators keep track of the total supply of Assets as a mutable mapping \(\mathsf{issuanceSupplyInfoMap}\) from \(\mathsf{AssetId}\) to \((\mathsf{totalSupply}, \mathsf{finalize})\) 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.
The fee mechanism described in this ZIP will follow the mechanism described in ZIP 317 16.
TBD
1 | Information on BCP 14 — "RFC 2119: Key words for use in RFCs to Indicate Requirement Levels" and "RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words" |
---|
2 | ZIP 32: Shielded Hierarchical Deterministic Wallets |
---|
3 | ZIP 32: Shielded Hierarchical Deterministic Wallets - Specification: Hardened-only key derivation |
---|
4 | ZIP 32: Shielded Hierarchical Deterministic Wallets - Hardened-only child key derivation |
---|
5 | ZIP 32: Shielded Hierarchical Deterministic Wallets - Key path levels |
---|
6 | ZIP 32: Shielded Hierarchical Deterministic Wallets - Orchard key path |
---|
7 | ZIP 200: Network Upgrade Mechanism |
---|
8 | ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances |
---|
9 | ZIP 224: Orchard |
---|
10 | ZIP 226: Transfer and Burn of Zcash Shielded Assets |
---|
11 | ZIP 226: Transfer and Burn of Zcash Shielded Assets - Note Structure & Commitment |
---|
12 | ZIP 226: Transfer and Burn of Zcash Shielded Assets - TxId Digest |
---|
13 | ZIP 244: Transaction Identifier Non-Malleability |
---|
14 | ZIP 244: Transaction Identifier Non-Malleability: Signature Digest |
---|
15 | ZIP 244: Transaction Identifier Non-Malleability: Authorizing Data Commitment |
---|
16 | ZIP 317: Proportional Transfer Fee Mechanism |
---|
17 | BIP 43: Purpose Field for Deterministic Wallets |
---|
18 | BIP 340: Schnorr Signatures for secp256k1 |
---|
19 | Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 2: Notation |
---|
20 | Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.1: Payment Addresses and Keys |
---|
21 | Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.2.3: Orchard Key Components |
---|
22 | Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.4.9.8: Group Hash into Pallas and Vesta |
---|
23 | Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.6.4.2: Orchard Raw Payment Addresses |
---|
24 | Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.1: Transaction Encoding and Consensus |
---|