Skip to content
Merged
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 39 additions & 26 deletions zip-0227.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,35 @@ The key word "MUST" in this document is to be interpreted as described in RFC 21

The term "network upgrade" in this document is to be interpreted as described in ZIP 200 [#zip-0200]_.

The term "Orchard" in this document is to be interpreted as described in ZIP 224 [#zip-0224]_.

The terms "Asset", "custom Asset", and "Wrapped Asset" in this document are to be interpreted as described in ZIP 226 [#zip-0226]_.
The terms "Orchard" and "Action" in this document are to be interpreted as described in
ZIP 224 [#zip-0224]_.

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 :ref:`Asset Identifier`.

- ZEC is the default (and currently the only defined) Asset for the Zcash mainnet.
- TAZ is the default (and currently the only defined) Asset for the Zcash testnet.
- We use the term "Custom Asset" to refer to any Asset other than ZEC and TAZ.

- Native Asset: a Custom Asset with issuance defined on the Zcash blockchain.
- Wrapped Asset: a Custom Asset with native issuance defined outside the Zcash blockchain.
- Issuance Action: an instance of a single issuance of a Zcash Shielded Asset. It defines the issuance of a single Asset Identifier.
- Issuance Bundle: the bundle in the transaction that contains all the issuance actions of that transaction.

Abstract
========

ZIP 226 [#zip-0226]_ and ZIP 227 [#zip-0227]_ propose in conjunction the Zcash Shielded Assets (ZSA) protocol, which 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 ZIP 227 [#zip-0227]_. The transfer and burn of such Assets is defined in ZIP 226 [#zip-0226]_. This ZIP must only be implemented in conjuction with ZIP 226 [#zip-0226]_, as the issuance mechanism is only valid for the ZSA transfer protocol, because it produces notes that can only be transferred under ZSA.
ZIP 227 [#zip-0227]_ proposes, in conjunction with ZIP 226 [#zip-0226]_, the Zcash Shielded Assets (ZSA) protocol. 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 [#zip-0226]_. This ZIP must only be implemented in conjuction with ZIP 226 [#zip-0226]_. The proposed issuance mechanism is only valid for the ZSA transfer protocol, because it produces notes that can only be transferred under ZSA.

Motivation
==========

This ZIP is a supporting ZIP for ZIP 226 [#zip-0226]_, which lays out its motivations, but requires an issuance mechanism to be defined (which is substantial enough to stand on its own) in order to function.

This ZIP enables only *transparent* issuance, since 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.
This ZIP introduces the issuance mechanism for custom Assets on the Zcash chain. While originally part of a same ZSA ZIP (ZIP 226 [#zip-0226]_) 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 [#zip-0226]_.

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 block chain), 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.
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.

Use Cases
=========
Expand All @@ -63,8 +69,8 @@ See the `Concrete Applications`_ section for more details.
Requirements
============

- Any user of the Zcash block chain can issue custom Assets on chain.
- The issuance mechanism should enable public tracking of the supply of the Assets on the Zcash block chain.
- Any user of the Zcash blockchain can issue custom Assets on chain.
- The issuance mechanism should enable public tracking of the supply of the Assets on the Zcash blockchain.
- Issuing or changing the attributes of a specific Asset should require cryptographic authorization.
- The Asset identification should be unique (among all shielded pools) and different issuer public keys should not be able to generate the same Asset Identifier.
- An issuer should be able to issue different Assets in the same transaction. In other words, in a single "issuance bundle", the issuer should be able publish many "issuance actions", potentially creating multiple Custom Assets.
Expand All @@ -80,7 +86,7 @@ The ZSA Protocol adds the following three keys to the key components [#protocol-

2. The issuance authorizing key is the key that is used to sign the issuance transaction, and is denoted as :math:`\mathsf{isk}`. This key is used to authorize the issuance of a specific Asset Identifier, and is only used by the issuer.

3. The issuance validating key, denoted as :math:`\mathsf{ik}`, is the key that is used to validate the issuance transaction. This key is used to validate the issuance of a specific Asset Identifier, and is used by all block chain users (specifically the Asset owners and consensus validators) to associate the Asset in question with the issuer.
3. The issuance validating key, denoted as :math:`\mathsf{ik}`, is the key that is used to validate the issuance transaction. This key is used to validate the issuance of a specific Asset Identifier, and is used by all blockchain users (specifically the Asset owners and consensus validators) to associate the Asset in question with the issuer.

The relations between these keys are shown in the following diagram:

Expand Down Expand Up @@ -114,9 +120,9 @@ We define the master extended issuance key :math:`m_{\mathsf{Issuance}} := \math
As in ZIP 32 for Orchard [#zip-0032-orchard-child-key-derivation]_, we only use hardened child key derivation for the issuance master key.
We reuse the :math:`\mathsf{CDKsk}` function for Orchard child key derivation from ZIP 32.

We use the notation of ZIP 32 [#zip-0032-orchard-key-path]_ for shielded HD paths, and define the issuance master key path as :math:`m_\mathsf{Issuance} / purpose / coin\_type' / account'`. We fix the path levels as follows:
We use the notation of ZIP 32 [#zip-0032-orchard-key-path]_ for shielded HD paths, and define the issuance master key path as :math:`m_\mathsf{Issuance} / purpose' / coin\_type' / account'`. We fix the path levels as follows:

- :math:`purpose`: a constant set to :math:`227'` (or :math:`\texttt{0x800000e3}`) following the BIP 43 recommendation.
- :math:`purpose`: a constant set to :math:`227` (i.e. :math:`\texttt{0xe3}). :math:`purpose'` is thus :math:`227'` (or :math:`\texttt{0x800000e3}`) following the BIP 43 recommendation.
- :math:`coin\_type`: Defined as in ZIP 32 [#zip-0032-key-path-levels]_.
- :math:`account`: fixed to index :math:`0`.

Expand All @@ -137,10 +143,12 @@ The issuance authorizing key and issuance validating key are derived from the is

This allows the issuer to use the same wallet it usually uses to transfer Assets, while keeping a disconnect from the other keys. Specifically, this method is aligned with the requirements and motivation of ZIP 32 [#zip-0032]_. It provides further anonymity and the ability to delegate issuance of an Asset (or in the future, generate a multi-signature protocol) while the rest of the keys remain in the wallet safe.

.. _Asset Identifier:

Specification: Asset Identifier
===============================

For every new Asset, there must be a new and unique Asset Identifier. We define this to be a globally unique pair :math:`(\mathsf{ik}, \mathsf{asset\_desc})`, where :math:`\mathsf{ik}` is the issuance key and :math:`\mathsf{asset\_desc}` is a byte string.
For every new Asset, there must be a new and unique Asset Identifier, denoted :math:`\mathsf{AssetId}`. We define this to be a globally unique pair :math:`\mathsf{AssetId} := (\mathsf{ik}, \mathsf{asset\_desc})`, where :math:`\mathsf{ik}` is the issuance key and :math:`\mathsf{asset\_desc}` is a byte string.

A given Asset Identifier is used across all Zcash protocols that support ZSAs -- that is, the Orchard-based ZSA protocol and potentially future Zcash shielded protocols. For this Asset Identifier, we derive an Asset Digest, :math:`\mathsf{AssetDigest}`, which is simply is a :math:`\textsf{BLAKE2b-512}` hash of the Asset Identifier.
From the Asset Digest, we derive a specific Asset Base within each such shielded protocol (for example :math:`\mathsf{AssetBase}^{\mathsf{Orchard}}_{\mathsf{AssetId}}` for the Orchard-based ZSA protocol), using the applicable hash-to-curve algorithm. This Asset Base is included in shielded notes.
Expand All @@ -153,12 +161,12 @@ Let
Define :math:`\mathsf{AssetDigest_{\mathsf{AssetId}}} := \textsf{BLAKE2b-512}(\texttt{"ZSA-Asset-Digest"},\; \mathsf{EncodeAssetId}(\mathsf{AssetId}))`,
where

- :math:`\mathsf{EncodeAssetId}(\mathsf{AssetId}) = \mathsf{EncodeAssetId}(\mathsf{ik}, \mathsf{asset\_desc}) := \mathsf{0x00} || \mathsf{repr}_{\mathbb{P}}(\mathsf{ik}) || \mathsf{asset\_desc}\!`.
- :math:`\mathsf{EncodeAssetId}(\mathsf{AssetId}) = \mathsf{EncodeAssetId}((\mathsf{ik}, \mathsf{asset\_desc})) := \mathsf{0x00} || \mathsf{repr}_{\mathbb{P}}(\mathsf{ik}) || \mathsf{asset\_desc}\!`.

Define :math:`\mathsf{AssetBase^{Protocol}_{\mathsf{AssetId}}} := \mathsf{ZSAValueBase^{Protocol}}(\mathsf{AssetDigest}_{\mathsf{AssetId}})`,
where

In the case of Orchard, we define :math:`\mathsf{ZSAValueBase^{Orchard}}(\mathsf{asset\_digest}) := \mathsf{GroupHash}^\mathbb{P}(\texttt{"z.cash:OrchardZSA"}, \mathsf{asset\_digest})`
In the case of Orchard, we define :math:`\mathsf{ZSAValueBase^{Orchard}}(\mathsf{AssetDigest}_{\mathsf{AssetId}}) := \mathsf{GroupHash}^\mathbb{P}(\texttt{"z.cash:OrchardZSA"}, \mathsf{AssetDigest}_{\mathsf{AssetId}})`
where :math:`\mathsf{GroupHash}^\mathbb{P}` is defined as in [#protocol-concretegrouphashpallasandvesta]_.

The relations between the Asset Identifier, Asset Digest, and Asset Base are shown in the following diagram:
Expand All @@ -171,6 +179,8 @@ The relations between the Asset Identifier, Asset Digest, and Asset Base are sho
Diagram relating the Asset Identifier, Asset Digest, and Asset Base in the ZSA Protocol


**Note:** To keep notations light and concise, we may omit :math:`\mathsf{AssetId}` (resp. :math:`\mathsf{Protocol}`) in the subscript (resp. superscript) when the Asset Identifier (resp. Protocol) is clear from the context.

Specification: Global Issuance State
====================================

Expand All @@ -189,19 +199,20 @@ An issuance action, `IssueAction`, is the instance of issuing a specific custom

- :math:`\mathsf{assetDescSize}`: the size of the Asset description, a number between :math:`0` and :math:`512`, stored in two bytes.
- :math:`\mathsf{asset\_desc}`: the Asset description, a byte string of up to 512 bytes as defined in the `Specification: Asset Identifier`_ section.
- `notes`: an array containing the unencrypted output notes of the recipients of the Asset, of type `Note`
- `notes`: an array of `Note` containing the unencrypted output notes of the recipients of the Asset.
- ``finalize``: a boolean that defines whether the issuance of that specific custom Asset is finalized or not

An asset's :math:`\mathsf{AssetId}` is added to the :math:`\mathsf{previously\_finalized}` set after a block that contains any issuance transaction for that asset with ``finalize = 1``. It then cannot be removed from this set. For Assets with :math:`\mathsf{AssetId} \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{AssetId} \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 ``finalize = 0`` or change it to ``finalize = 1``, denoting that this custom Asset cannot be issued after the containing block.

================= =============================== ========================== ===========================================================================================
Size Name Data Type Description
Bytes Name Data Type Description
================= =============================== ========================== ===========================================================================================
2 bytes :math:`\mathsf{assetDescSize}` byte The length of the :math:`\mathsf{asset\_desc}` string in bytes
Varies :math:`\mathsf{asset\_desc}` byte UTF-8 encoded string, of size :math:`\mathsf{assetDescSize}` bytes
2 assetDescSize byte The length of the asset\_desc string in bytes
Varies asset\_desc byte UTF-8 encoded string, of size assetDescSize bytes
Varies nNotes compactSize The number of notes in the issuance action
TBD noteSize byte The size, in bytes, of a Note

@AntoineRondelet AntoineRondelet May 28, 2023

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per: #20 (comment) it'd be nice to document the noteSize

noteSize * nNotes vNotes Note[nNotes] A sequence of note descriptions within the issuance action
1 byte ``flagsIssuance`` byte An 8-bit value with the ``finalize`` boolean value as the LSB, and the other bits set to 0.
1 ``flagsIssuance`` byte An 8-bit value with the ``finalize`` boolean value as the LSB, and the other bits set to 0.
Comment thread
AntoineRondelet marked this conversation as resolved.
Outdated
================= =============================== ========================== ===========================================================================================

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 `NoteCommitmentTree` 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.
Expand All @@ -221,8 +232,9 @@ The issuance bundle is then added within the transaction format as a new bundle.
Bytes Name Data Type Description
======= ==================== ========================== ==========================================================================================================================
Varies nIssueActions compactSize The number of issuance actions in the bundle
Varies vIssueActions IssueAction[nIssueActions] A sequence of issuance actions descriptions
32 :math:`\mathsf{ik}` byte[32] The issuance validating key of the issuer, used to validate the signature
TBD IssueActionSize byte The size, in bytes, of an IssueAction description
Comment thread
AntoineRondelet marked this conversation as resolved.
Outdated
IssueActionSize * nIssueActions vIssueActions IssueAction[nIssueActions] A sequence of issuance actions descriptions
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`_
======= ==================== ========================== ==========================================================================================================================

Expand All @@ -235,7 +247,7 @@ For all actions `IssueAction`:
- encode :math:`\mathsf{asset\_desc}` as a UTF-8 byte string of size up to 512.
- compute :math:`\mathsf{AssetDigest}` from the issuance validating key :math:`\mathsf{ik}` and :math:`\mathsf{asset\_desc}` as decribed in the `Specification: Asset Identifier`_ section.
- compute :math:`\mathsf{AssetBase^{Protocol}}` from :math:`\mathsf{AssetDigest}` as decribed in the `Specification: Asset Identifier`_ section.
- set the ``finalize`` boolean as desired (if more more issuance actions are to be created for this Asset Identifier, set ``finalize = 0``, otherwise set ``finalize = 1``)
- set the ``finalize`` boolean as desired (if more issuance actions are to be created for this Asset Identifier, set ``finalize = 0``, otherwise set ``finalize = 1``)
- For each recipient :math:`i`:

- generate a ZSA output note that includes the Asset Base. For an Orchard-based ZSA note this is :math:`\mathsf{note}_i = (\mathsf{d}_i, \mathsf{pk}_{\mathsf{d},i}, \mathsf{v}_i, \rho_i, \psi_i, \mathsf{AssetBase^{Orchard}}, \mathsf{rcm}_i)\!`.
Expand All @@ -249,7 +261,7 @@ For the `IssueBundle`:
- sign the `SIGHASH` of the transaction with the issuance authorizing key, :math:`\mathsf{isk}`, using the :math:`\mathsf{IssueAuthSig}` signature scheme. The signature is then added to the issuance bundle.


NOTE that the commitment is not included in the `IssuanceAction` itself. As explained below, it is later computed by the validators and added to the `NoteCommitmentTree`.
**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 `NoteCommitmentTree`.


Specification: Consensus Rule Changes
Expand All @@ -263,6 +275,7 @@ For each `IssueAction` in `IssueBundle`:

- check that :math:`0 < \mathsf{assetDescSize} <= 512`.
- check that :math:`\mathsf{asset\_desc}` is a string of length :math:`\mathsf{assetDescSize}` bytes.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

asset_desc is defined as "UTF-8 encoded string, of size assetDescSize bytes" in the table. Yet, it's Byte size is set to Varies and its type is set as byte.

It seems like it's Byte size shouldn't be Varies but assetDescSize instead and it's type should be a byte array byte[assetDescSize]

- 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{AssetId}` does not exist in the ``previously_finalized`` set in the global state.
- check that every note in the `IssueAction` contains the same :math:`\mathsf{AssetBase}` and is properly constructed as :math:`note = (\mathsf{g_d, pk_d, v, \rho, \psi, AssetBase})`.
Expand Down Expand Up @@ -378,7 +391,7 @@ This is the raw encoding of an Orchard shielded payment address as defined in th

T.5a.i.2: value
...............
Note value encoded as little-endian 8-byte representation of u64 raw value.
Note value encoded as little-endian 8-byte representation of 64-bit unsigned integer (e.g. u64 in Rust) raw value.

T.5a.i.3: assetBase
...................
Expand Down