# ZIP 227: Issuance of Zcash Shielded Assets

Status: Draft

Owners: Pablo Kogan, Vivek Arte, Daira-Emma Hopwood, Jack Grigg

Snapshot: a34cfc091434275120ff017c92c3b50d3cef623a

Source date: 2026-10-16T02:56:04+01:00

[Source revision](https://github.com/zcash/zips/commit/a34cfc091434275120ff017c92c3b50d3cef623a)

[Official source](https://zips.z.cash/zip-0227) · [Source file](https://github.com/zcash/zips/blob/a34cfc091434275120ff017c92c3b50d3cef623a/zips/zip-0227.rst) · [Discussion](https://github.com/zcash/zips/issues/618)

## Document parts

[Part 1](https://zips.tools/zip/227) · [Part 2](https://zips.tools/zip/227?part=2)

Reading part 1 of 2. Follow all parts for the complete proposal.

Preamble

**ZIP**: 227

**Title**: Issuance of Zcash Shielded Assets

**Owners**: 

- [Pablo Kogan](mailto:pablo@qed-it.com)
- [Vivek Arte](mailto:vivek@qed-it.com)
- [Daira-Emma Hopwood](mailto:daira@jacaranda.org)
- [Jack Grigg](mailto:thestr4d@gmail.com)

**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](https://github.com/zcash/zips/issues/618)

**Pull-Request**: [https://github.com/zcash/zips/pull/680](https://github.com/zcash/zips/pull/680)

<a id="terminology"></a>

## Terminology

The key words "MUST", "MUST NOT", "SHOULD", "RECOMMENDED", and "MAY" in this document are to be interpreted as described in BCP 14<a id="fnref1"></a>
[1](/zip/227?part=2#fn1) 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<a id="fnref2"></a>
[2](/zip/227?part=2#fn2).

The character § is used when referring to sections of the Zcash Protocol Specification.<a id="fnref3"></a>
[3](/zip/227?part=2#fn3)

The terms "Orchard" and "Action" in this document are to be interpreted as described in ZIP 224<a id="fnref4"></a>
[4](/zip/227?part=2#fn4).

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, Asset Digest, and Asset Base](#specification-asset-identifier-asset-digest-and-asset-base).
  
  
  
  - 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.

- 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.

<a id="abstract"></a>

## Abstract

This ZIP (ZIP 227) proposes the Orchard Zcash Shielded Assets (OrchardZSA) protocol, in conjunction with ZIP 226<a id="fnref5"></a>
[5](/zip/227?part=2#fn5). 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<a id="fnref6"></a>
[6](/zip/227?part=2#fn6). This ZIP must only be implemented in conjunction with ZIP 226<a id="fnref7"></a>
[7](/zip/227?part=2#fn7). The proposed issuance mechanism is only valid for the OrchardZSA transfer protocol, because it produces notes that can only be transferred via this protocol.

<a id="motivation"></a>

## 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<a id="fnref8"></a>
[8](/zip/227?part=2#fn8).

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 issue Assets that wrap tokens from those chains. This enables what we hope will be a useful set of applications.

<a id="use-cases"></a>

## Use Cases

The design presented in this ZIP enables issuance of shielded Assets in various modes:

- The issuer may or may not know the receivers of the issued Asset in advance.

- The Asset can be of non-fungible type, where each Asset type can be made part of a single “series”.

- The supply of the Asset can be limited in advance or not.

- The Asset can be a wrapped version of an Asset issued by another chain (as long as there is a bridge that supports transfer of that Asset between chains).

See the [Concrete Applications](/zip/227?part=2#concrete-applications) section for more details.

<a id="requirements"></a>

## Requirements

- 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.

- Every "issuance action" should contain a $\mathsf{finalize}$ boolean that defines whether the specific Custom Asset can have further tokens issued or not.

<a id="specification-issuance-keys-issuer-identifier-and-issuance-authorization-signature-scheme"></a>

## Specification: Issuance Keys, Issuer Identifier, and Issuance Authorization Signature Scheme

<a id="issuance-keys"></a>

### Issuance Keys

The OrchardZSA Protocol adds the following keys used for issuance:

1. The issuance authorizing key, denoted as $\mathsf{isk}$, is the key used to authorize the issuance of Asset Identifiers by a given issuer, and is only used by that issuer.

2. The issuance validating key, denoted as $\mathsf{ik}$, is the key that is used to validate issuance transactions. This key is used to validate the issuance of Asset Identifiers by a given issuer.

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

![Diagram of Issuance Key Components for the OrchardZSA Protocol](https://raw.githubusercontent.com/zcash/zips/a34cfc091434275120ff017c92c3b50d3cef623a/rendered/assets/images/zip-0227-key-components-zsa.png)
Diagram of Issuance Key Components for the OrchardZSA Protocol

<a id="issuer-identifier"></a>

### Issuer Identifier

The identifier for a particular issuer is denoted by $\mathsf{issuer}$. This identifier is used by all blockchain users (specifically the owners of notes for that Asset, and consensus validators) to associate the Asset in question with the issuer.

$\mathsf{issuer}$ is equal to the encoding $\mathsf{ik\_encoding}$ (specified below in [Derivation of issuance validating key](#derivation-of-issuance-validating-key)) of the issuance validating key $\mathsf{ik}$ used to validate the issuance of Asset Identifiers by that issuer.

Note: the equality of $\mathsf{issuer}$ and $\mathsf{ik\_encoding}$ might not hold in future when key rotation is specified for issuance key pairs.

<a id="issuance-authorization-signature-scheme"></a>

### Issuance Authorization Signature Scheme

The issuance authorization signature, encoded in the `issueAuthSig` field of an issuance bundle, is used to authorize the issuance of Custom Assets by the issuer.

The issuance authorization signature scheme, $\mathsf{IssueAuthSig}$, comprises all the associated types and algorithms required for a signature scheme in §4.1.7 ‘Signature’<a id="fnref9"></a>
[9](/zip/227?part=2#fn9).

Batch verification MAY be used. Precomputation MAY be used if and only if it produces equivalent results.

<a id="orchard-zsa-issuance-authorization-signature-scheme"></a>

#### Orchard ZSA Issuance Authorization Signature Scheme

In the OrchardZSA protocol, we instantiate the issuance authorization signature scheme $\mathsf{IssueAuthSig}$ as a BIP-340 Schnorr signature over the secp256k1 curve. We define the constants as per the secp256k1 standard parameters, as described in BIP 340.

The associated types of the $\mathsf{IssueAuthSig}$ signature scheme, which are identical to BIP 340, are as follows:

- $\mathsf{IssueAuthSig.Message} = \mathbb{B}^{\mathbb{Y}^{[\mathbb{N}]}}$

- $\mathsf{IssueAuthSig.Signature} = \mathbb{B}^{\mathbb{Y}^{[64]}} \cup \{\bot\}$

- $\mathsf{IssueAuthSig.Public} = \mathbb{B}^{\mathbb{Y}^{[32]}} \cup \{\bot\}$

- $\mathsf{IssueAuthSig.Private} = \mathbb{B}^{\mathbb{Y}^{[32]}}$

where $\mathbb{B}^{\mathbb{Y}^{[k]}}$ denotes the set of sequences of $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<a id="fnref10"></a>
[10](/zip/227?part=2#fn10).

The issuance authorizing key generation algorithm and the issuance validating key derivation algorithm are defined in the [Issuance Key Derivation](#issuance-key-derivation) section, while the corresponding signing and validation algorithms are defined in the [Issuance Authorization Signing and Validation](#issuance-authorization-signing-and-validation) section.

<a id="issuance-key-derivation"></a>

### Issuance Key Derivation

<a id="issuance-authorizing-key-generation-for-hierarchical-deterministic-wallets"></a>

#### Issuance authorizing key generation for hierarchical deterministic wallets

The issuance authorizing key is generated using the Hardened-only key derivation process defined in ZIP 32<a id="fnref11"></a>
[11](/zip/227?part=2#fn11). For the $\mathsf{Issuance}$ context, we define the following constants:

- $\mathsf{Issuance.MKGDomain} := \texttt{“ZcashSA\_Issue\_V1”}$

- $\mathsf{Issuance.CKDDomain} := \mathtt{0x81}$

Let $S$ be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes. We define the master extended issuance key $m_{\mathsf{Issuance}} := \mathsf{MKGh}^{\mathsf{Issuance}}(S)$.

We use hardened-only child key derivation as defined in ZIP 32<a id="fnref12"></a>
[12](/zip/227?part=2#fn12) for the issuance authorizing key.

$\mathsf{CKDsk}((\mathsf{sk}_{par},\mathsf{c}_{par}), i) \rightarrow (\mathsf{sk}_{i}, \mathsf{c}_{i})$ :

- Return $\mathsf{CKDh}^{\mathsf{Issuance}}((\mathsf{sk}_{par},\mathsf{c}_{par}), i)$

We use the notation of ZIP 32<a id="fnref13"></a>
[13](/zip/227?part=2#fn13) for shielded HD paths, and define the issuance authorizing key path as $m_{\mathsf{Issuance}} / \mathit{purpose}' / \mathit{coin\_type}' / \mathit{account}'$. We fix the path levels as follows:

- $\mathit{purpose}$: a constant set to $227$ (i.e. $\mathtt{0xe3}$). $\mathit{purpose}'$ is thus $227'$ (or $\mathtt{0x800000e3}$) following the BIP 43 recommendation.<a id="fnref14"></a>
  [14](/zip/227?part=2#fn14)

- $\mathit{coin\_type}$: Defined as in ZIP 32<a id="fnref15"></a>
  [15](/zip/227?part=2#fn15).

- $\mathit{account}$: fixed to index $0$.

From the generated $(\mathsf{sk}, \mathsf{c})$, we set the issuance authorizing key to be $\mathsf{isk} := \mathsf{sk}$.

<a id="derivation-of-issuance-validating-key"></a>

#### Derivation of issuance validating key

Define $\mathsf{IssueAuthSig.DerivePublic} \;{\small ⦂}\; (\mathsf{isk} \;{\small ⦂}\; \mathsf{IssueAuthSig.Private}) \to \mathsf{IssueAuthSig.Public}$ as:

- $\mathsf{ik} := \textit{PubKey}(\mathsf{isk})$

- Return $\bot$ if the $\textit{PubKey}$ algorithm invocation fails, otherwise return $\mathsf{ik}$.

where the $\textit{PubKey}$ algorithm is defined in BIP 340<a id="fnref16"></a>
[16](/zip/227?part=2#fn16), and the output of the algorithm is in big-endian order as defined in BIP 340.

The encoding of this validating key, $\mathsf{ik\_encoding}$, includes an initial byte indicating the signature scheme, which MUST be $\mathtt{0x00}$ indicating BIP 340. That is, $\mathsf{ik\_encoding} = [\mathtt{0x00}] \,||\, \mathsf{ik}$. This enables future ZIPs to specify alternative signature schemes. Note that this encoding currently only appears in the `issuer` field of an issuance bundle.

It is possible for the $\textit{PubKey}$ algorithm to fail with very low probability, which means that $\mathsf{IssueAuthSig.DerivePublic}$ could return $\bot$ with very low probability. If this happens, discard the keys and repeat with a different $\mathsf{isk}$.

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<a id="fnref17"></a>
[17](/zip/227?part=2#fn17). It provides further anonymity and the ability to delegate issuance of an Asset (or in the future, use a multi-signature protocol) while the rest of the keys remain safe in the wallet.

<a id="issuance-authorization-signing-and-validation"></a>

### Issuance Authorization Signing and Validation

Define $\mathsf{IssueAuthSig.Sign} \;{\small ⦂}\; (\mathsf{isk} \;{\small ⦂}\; \mathsf{IssueAuthSig.Private}) \times (M \;{\small ⦂}\; \mathsf{IssueAuthSig.Message}) \to \mathsf{IssueAuthSig.Signature}$ as:

- Let the auxiliary data $a = [\mathtt{0x00}]^{32}$.

- Let $\text{σ} = \mathsf{Sign}(\mathsf{isk}, M)$ with auxiliary data $a$.

- Return $\bot$ if the $\mathsf{Sign}$ algorithm fails in the previous step, otherwise return $\text{σ}$.

where the $\mathsf{Sign}$ algorithm is defined in BIP 340<a id="fnref18"></a>
[18](/zip/227?part=2#fn18). Note that $\mathsf{IssueAuthSig.Sign}$ could return $\bot$ with very low probability.

Define $\mathsf{IssueAuthSig.Validate} \;{\small ⦂}\; (\mathsf{ik} \;{\small ⦂}\; \mathsf{IssueAuthSig.Public}) \times (M \;{\small ⦂}\; \mathsf{IssueAuthSig.Message}) \times (\text{σ} \;{\small ⦂}\; \mathsf{IssueAuthSig.Signature}) \to \mathbb{B}$ as:

- Return $0$ if $\text{σ} = \bot$.

- Return $1$ if $\mathsf{Verify}(\mathsf{key}, M, \text{σ})$ succeeds, otherwise $0$.

where the $\mathsf{Verify}$ algorithm is defined in BIP 340<a id="fnref19"></a>
[19](/zip/227?part=2#fn19).

The $\mathtt{issueAuthSig}$ field of an issuance bundle encodes the signature with an initial byte indicating the signature scheme, which MUST be $\mathtt{0x00}$ indicating BIP 340. That is, $\mathtt{issueAuthSig} = [\mathtt{0x00}] \,||\, \text{σ}$. This enables future ZIPs to specify alternative signature schemes.

<a id="specification-asset-identifier-asset-digest-and-asset-base"></a>

## Specification: Asset Identifier, Asset Digest, and Asset Base

The definition of the Asset Identifier, and that of the Asset Digest and Asset Base for a given Asset Identifier, will be described in this section. For context, the relations between the Asset Identifier, Asset Digest, and Asset Base are shown in the following diagram:

![Diagram relating the Asset Identifier, Asset Digest, and Asset Base.](https://raw.githubusercontent.com/zcash/zips/a34cfc091434275120ff017c92c3b50d3cef623a/rendered/assets/images/zip-0227-asset-identifier-relation.png)
Diagram relating the Asset Identifier, Asset Digest, and Asset Base.

**Note:** To keep notations light and concise, we may omit $\mathsf{AssetId}$ in the subscript when the Asset Identifier is clear from the context.

<a id="asset-identifier"></a>

### Asset Identifier

Every Asset has a globally-unique Asset Identifier, denoted $\mathsf{AssetId}$. A given Asset Identifier is used across all Zcash protocols that support ZSAs -- that is, the OrchardZSA protocol and potentially future Zcash shielded protocols.

<a id="zip-227-asset-identifiers"></a>

#### ZIP 227 Asset Identifiers

Assets issued using the protocol specified in this ZIP are scoped to the $\mathsf{issuer}$ that issued them. Within that scope, Asset Identifier uniqueness is obtained by way of an asset description, $\mathsf{asset\_desc}$, which includes any information pertaining to the issuance. $\mathsf{asset\_desc}$ is a non-empty byte sequence which SHOULD be a well-formed UTF-8 code unit sequence according to Unicode 15.0.0 or later.

Define

$\mathsf{assetDescHash} := \textsf{BLAKE2b-256}(\texttt{“ZSA-AssetDescCRH”},\; \mathsf{asset\_desc}),$

We define Asset Identifiers for Assets issued under this ZIP as

$\mathsf{AssetId} := (\mathsf{issuer}, \mathsf{assetDescHash})$

and define their canonical encoding as

$\mathsf{EncodeAssetId}(\mathsf{AssetId}) = \mathsf{EncodeAssetId}((\mathsf{issuer}, \mathsf{assetDescHash})) := [\mathtt{0x00}] \,||\, \mathsf{issuer}\,||\,\mathsf{assetDescHash}$

Note that the initial $\mathtt{0x00}$ byte is a version byte, enabling future ZIPs to specify alternative issuance protocols and Asset Identifiers. (This should not be confused with the first byte of $\mathsf{issuer}$, currently equal to the first byte of $\mathsf{ik\_encoding}$, that indicates the issuance signature scheme.)

Wallets MUST NOT display just the $\mathsf{asset\_desc}$ string to their users as the name of the Asset. Some possible alternatives include:

- Wallets could allow clients to provide an additional configuration file that stores a one-to-one mapping of names to Asset Identifiers via a petname system<a id="fnref20"></a>
  [20](/zip/227?part=2#fn20). This allows clients to rename the Assets in a way they find useful. Default versions of this file with well-known Assets listed can be made available online as a starting point for clients.

- The Asset Digest could be used as a more compact byte sequence to uniquely determine an Asset, and wallets could support clients scanning QR codes to load Asset information into their wallets.

<a id="asset-digests"></a>

### Asset Digests

From the Asset Identifier, we derive an Asset Digest

$\mathsf{AssetDigest_{AssetId}} := \textsf{BLAKE2b-512}(\texttt{“ZSA-Asset-Digest”},\; \mathsf{EncodeAssetId}(\mathsf{AssetId})),$

where $\mathsf{EncodeAssetId}(\mathsf{AssetId})$ is the canonical encoding scheme for the Asset Identifier.

<a id="asset-bases"></a>

### Asset Bases

From the Asset Digest, we derive a specific Asset Base that represents the Custom Asset within each shielded protocol:

$\mathsf{AssetBase_{AssetId}} := \mathsf{ZSAValueBase}(\mathsf{AssetDigest_{AssetId}})$

This Asset Base is included in shielded notes within the shielded protocol.

<a id="orchardzsa-asset-bases"></a>

#### OrchardZSA Asset Bases

In the case of the OrchardZSA protocol, we define

$\mathsf{ZSAValueBase}(\mathsf{AssetDigest}) := \mathsf{GroupHash}^\mathbb{P}(\texttt{"z.cash:OrchardZSA"}, \mathsf{AssetDigest})$

where $\mathsf{GroupHash}^\mathbb{P}$ is defined as in<a id="fnref21"></a>
[21](/zip/227?part=2#fn21).

![Diagram relating the Issuer identifier, asset description, asset description hash, Asset Identifier, Asset Digest, and Asset Base for the OrchardZSA Protocol.](https://raw.githubusercontent.com/zcash/zips/a34cfc091434275120ff017c92c3b50d3cef623a/rendered/assets/images/zip-0227-asset-identifier-relation-orchard-zsa.png)
Diagram relating the Issuer identifier, asset description, asset description hash, Asset Identifier, Asset Digest, and Asset Base for the OrchardZSA Protocol.

<a id="specification-issue-note-issuance-action-issuance-bundle-and-issuance-protocol"></a>

## Specification: Issue Note, Issuance Action, Issuance Bundle and Issuance Protocol

<a id="issue-note"></a>

### Issue Note

Let $\ell_{\mathsf{value}}$ be as defined in §5.3 ‘Constants’<a id="fnref22"></a>
[22](/zip/227?part=2#fn22). An Issue Note represents that a value $\mathsf{v} : \{0 .. 2^{\ell_{\mathsf{value}}} - 1\}$ of a specific Custom Asset is issued to a recipient. An Issue Note is a tuple $(\mathsf{d}, \mathsf{pk_d}, \mathsf{v}, \mathsf{AssetBase}, \text{ρ}, \mathsf{rseed})$, where:

- $\mathsf{d}: \mathbb{B}^{[\ell_{\mathsf{d}}]}$ is the diversifier of the recipient's shielded payment address, as in §3.2 ‘Notes’<a id="fnref23"></a>
  [23](/zip/227?part=2#fn23).

- $\mathsf{pk_d}: \mathsf{KA}^{\mathsf{Orchard}}.\mathsf{Public}$ is the recipient's diversified transmission key, as in §3.2 ‘Notes’<a id="fnref24"></a>
  [24](/zip/227?part=2#fn24).

- $\mathsf{v} : \{0 .. 2^{\ell_{\mathsf{value}}} - 1\}$ is the value of the note in terms of the number of Asset tokens.

- $\mathsf{AssetBase}: \mathbb{P}^*$ is the Asset Base corresponding to the ZSA being issued in the Issue Note.

- $\text{ρ}: \mathbb{F}_{q_{\mathbb{P}}}$ is used to derive the nullifier of the note, and is computed as in [Computation of ρ](#computation-of-ρ).

- $\mathsf{rseed}: \mathbb{B}^{[\mathbb{Y}^{32}]}$ MUST be sampled uniformly at random by the issuer.

ZIP 230<a id="fnref25"></a>
[25](/zip/227?part=2#fn25) defines, in `IssueNoteDescription`, field encodings which together with $\mathsf{issuer}$ from the parent [Issuance Bundle](#issuance-bundle) and $\mathsf{AssetDescHash}$ from the parent [Issuance Action](#issuance-action), specify an Issue Note.

Let $\mathsf{Note^{Issue}}$ be the type of an Issue Note, i.e.

$\mathsf{Note^{Issue}} := \mathbb{B}^{[\ell_{\mathsf{d}}]} \times \mathsf{KA}^{\mathsf{Orchard}}.\mathsf{Public} \times \{0 .. 2^{\ell_{\mathsf{value}}} - 1\} \times \mathbb{P}^* \times \mathbb{F}_{q_{\mathbb{P}}} \times \mathbb{B}^{[\mathbb{Y}^{32}]}.$

The note commitments of Issue Notes are computed in the same manner as for OrchardZSA Notes. They will be added to the note commitment tree as any other shielded note when the transaction issuing the Asset is included on chain. 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.

<a id="issuance-action"></a>

### Issuance Action

An issuance action, `IssueAction`, is the instance of issuing a specific Custom Asset, and contains the following fields:

- `assetDescHash`: the hash of the Asset description, as defined in the [ZIP 227 Asset Identifiers](#zip-227-asset-identifiers) section.

- `vNotes`: an array of Issue Notes containing the unencrypted output notes to 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.

The $\mathsf{finalize}$ boolean is set by the Issuer to signal that there will be no further issuance of the specific Custom Asset. As we will see in [Specification: Consensus Rule Changes](#specification-consensus-rule-changes), transactions that attempt to issue further amounts of a Custom Asset that has previously been finalized will be rejected.

The complete encoding of these fields into an `IssueAction` is defined in ZIP 230<a id="fnref26"></a>
[26](/zip/227?part=2#fn26).

<a id="issuance-bundle"></a>

### Issuance Bundle

An issuance bundle 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:

- `issuer`: the issuer identifier, that allows the validators to verify that the $\mathsf{AssetId}$ is properly associated with the issuer.

- `vIssueActions`: an array of issuance actions, of type `IssueAction`.

- `issueAuthSig`: the encoding of a signature of the transaction SIGHASH, signed by the issuance authorizing key, $\mathsf{isk}$, that validates the issuance.

The issuance bundle is added within the transaction format as a new bundle. The detailed encoding of the issuance bundle as a part of the V6 transaction format is defined in ZIP 230<a id="fnref27"></a>
[27](/zip/227?part=2#fn27).

<a id="computation-of-ρ"></a>

### Computation of ρ

We define a function $\mathsf{DeriveIssuedRho} : \mathbb{F}_{q_{\mathbb{P}}} \times \{0 .. 2^{32} - 1\} \times \{0 .. 2^{32} - 1\} \to \mathbb{F}_{q_{\mathbb{P}}}$ for Issue Notes in the OrchardZSA Protocol as follows:

$\mathsf{DeriveIssuedRho}(\mathsf{nf}, \mathsf{i_{A}}, \mathsf{i_{N}}) := \mathsf{ToBase}^{\mathsf{Orchard}}\big(\mathsf{PRF}^{\mathsf{expand}}\big(\mathsf{I2LEOSP}_{256}(\mathsf{nf}), [\mathtt{0x84}] \,||\, \mathsf{I2LEOSP}_{32}(\mathsf{i_{A}}) \,||\, \mathsf{I2LEOSP}_{32}(\mathsf{i_{N}})\big)\big),$

where $\mathsf{ToBase}^{\mathsf{Orchard}}$ is defined in §4.2.3 ‘Orchard Key Components’<a id="fnref28"></a>
[28](/zip/227?part=2#fn28), and $\mathsf{PRF}^{\mathsf{expand}}$ is defined in §5.4.2 ‘Pseudo Random Functions’<a id="fnref29"></a>
[29](/zip/227?part=2#fn29).

The $\text{ρ}$ field of an Issue Note is computed as

$\text{ρ} := \mathsf{DeriveIssuedRho}(\mathsf{nf}_{0,0}, \mathsf{index_{Action}}, \mathsf{index_{Note}}),$

where $\mathsf{nf}_{0,0}$ is the nullifier for the input note in the first Action in the first Action Group of the OrchardZSA Bundle of the transaction, $\mathsf{index_{Action}}$ is the zero-based index of the Issuance Action in the Issuance Bundle, and $\mathsf{index_{Note}}$ is the zero-based index of the Issue Note in the Issuance Action.

**NOTE:** This implicitly requires that there always is an Action Group in the OrchardZSA bundle of the transaction. This is enforced by a consensus rule in the [Specification: Consensus Rule Changes](#specification-consensus-rule-changes) section.

<a id="issuance-protocol"></a>

### Issuance Protocol

The issuer program performs the following operations:

For all actions `IssueAction`:

- encode $\mathsf{asset\_desc}$ as a UTF-8 byte string.

- compute $\mathsf{assetDescHash}$

- compute $\mathsf{AssetDigest}$ from the issuer identifier $\mathsf{issuer}$ and $\mathsf{assetDescHash}$ as decribed in the [Specification: Asset Identifier, Asset Digest, and Asset Base](#specification-asset-identifier-asset-digest-and-asset-base) section.

- compute $\mathsf{AssetBase}$ from $\mathsf{AssetDigest}$ as decribed in the [Specification: Asset Identifier, Asset Digest, and Asset Base](#specification-asset-identifier-asset-digest-and-asset-base) section.

- set the $\mathsf{finalize}$ boolean as desired (if more issuance actions are to be created for this $\mathsf{AssetBase}$, set $\mathsf{finalize} = 0$, otherwise set $\mathsf{finalize} = 1$).

- for each recipient $i$:
  
  
  
  
  > - generate an Issue Note, $\mathsf{note}_i = (\mathsf{d}_i, \mathsf{pk}_{\mathsf{d}_i}, \mathsf{v}_i, \mathsf{AssetBase}, \text{ρ}_i, \mathsf{rseed}_i)$.
  > 
  > - encode the $\mathsf{note}_i$ into the vector `vNotes` of the `IssueAction`.

- encode the `IssueAction` into the vector `vIssueActions` of the bundle.

For the `IssueBundle` (see “ZSA Issuance Bundle Fields” in<a id="fnref30"></a>
[30](/zip/227?part=2#fn30)):

- encode the `vIssueActions` vector.

- fill the `issuerLength` and `issuer` fields using $\mathsf{issuer}$.

- sign the SIGHASH transaction hash with the issuance authorizing key, $\mathsf{isk}$, using the $\mathsf{IssueAuthSig}$ signature scheme. The signature is then added to the issuance bundle.

**Note:** The note 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.

<a id="specification-reference-notes-and-global-issuance-state"></a>

## Specification: Reference Notes and Global Issuance State

<a id="reference-notes"></a>

### Reference Notes

A reference note for a Custom Asset MUST be included by the issuer as the first Note in the Action of the Issuance Bundle where that Custom Asset is being issued for the first time.

A reference note for a Custom Asset is an Issue Note where the value $\mathsf{v}$ is set to $0$, the Asset Base ($\mathsf{AssetBase}$) corresponds to that of the Custom Asset, and the recipient address $(\mathsf{d}, \mathsf{pk}_{\mathsf{d}})$ is set to the default diversified payment address (i.e. the diversified payment address with diversifier index $0$) derived from the all-zero Orchard spending key using the algorithm specified in §4.2.3 ‘Orchard Key Components’<a id="fnref31"></a>
[31](/zip/227?part=2#fn31). This corresponds to a 43-byte `u8` array with the following entries:

```
[
  204, 54, 96, 25, 89, 33, 59, 107, 12, 219, 150, 167, 92, 23, 195, 166, 104, 169, 127, 13, 106,
  140, 92, 225, 100, 165, 24, 234, 155, 169, 165, 14, 167, 81, 145, 253, 134, 27, 15, 241, 14,
  98, 176,
]
```

<a id="global-issuance-state"></a>

### Global Issuance State

The maximum total supply of any issued Custom Asset is denoted by the constant $\mathsf{MAX\_ISSUE} := 2^{64} - 1$.

Issuance requires the following additions to the global state:

A map, $\mathsf{issued\_assets} : \mathbb{P}^* \to \{0 .. \mathsf{MAX\_ISSUE}\} \times \mathbb{B} \times \mathsf{Note^{Issue}}$, from the Asset Base, $\mathsf{AssetBase} : \mathbb{P}^*$, to a tuple $(\mathsf{balance}, \mathsf{final}, \mathsf{note_{ref}})$, for every Asset that has been issued. We use the notation $\mathsf{issued\_assets}(\mathsf{AssetBase}).\mathsf{balance}$, $\mathsf{issued\_assets}(\mathsf{AssetBase}).\mathsf{final}$, and $\mathsf{issued\_assets}(\mathsf{AssetBase}).\mathsf{note_{ref}}$ to access, respectively, the elements of the tuple stored in the global state for a given $\mathsf{AssetBase}$. If $\mathsf{issued\_assets}(\mathsf{AssetBase}) = \bot$, it is assumed that $\mathsf{issued\_assets}(\mathsf{AssetBase}).\mathsf{balance} = 0$, $\mathsf{issued\_assets}(\mathsf{AssetBase}).\mathsf{final} = 0$, and $\mathsf{issued\_assets}(\mathsf{AssetBase}).\mathsf{note_{ref}} = \bot$.

For any Asset represented by $\mathsf{AssetBase}$:

- $\mathsf{issued\_assets}(\mathsf{AssetBase}).\mathsf{balance} \in \{0 .. \mathsf{MAX\_ISSUE}\}$ stores 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.

- $\mathsf{issued\_assets}(\mathsf{AssetBase}).\mathsf{final} : \mathbb{B}$ is a Boolean that stores the finalization status of the Asset (i.e.: whether the $\mathsf{finalize}$ flag has been set to $1$ in any preceding issuance transaction for the Asset). The value of $\mathsf{issued\_assets}(\mathsf{AssetBase}).\mathsf{final}$ for any $\mathsf{AssetBase}$ cannot be changed from $1$ to $0$.

- $\mathsf{issued\_assets}(\mathsf{AssetBase}).\mathsf{note_{ref}} : \mathsf{Note^{Issue}}$ stores the reference note for the Asset, as defined in the [Reference Notes](#reference-notes) section.

<a id="management-of-the-global-issuance-state"></a>

### Management of the Global Issuance State

The issuance state, that is, the $\mathsf{issued\_assets}$ map, MUST be updated by a node during the processing of any transaction that contains burn information, or an issuance bundle. The issuance state is chained as follows:

- The input issuance state for the activation block of the OrchardZSA protocol is the empty map.

- The input issuance state for the first transaction of a block is the final issuance state of the immediately preceding block.

- The input issuance state of each subsequent transaction in the block is the output issuance state of the immediately preceding transaction.

- The final issuance state of a block is the output issuance state of the last transaction in the block.

We describe the consensus rule changes that govern the management of the global issuance state in the [Specification: Consensus Rule Changes](#specification-consensus-rule-changes) section. We use $\mathsf{issued\_assets}_{\mathsf{IN}}$ and $\mathsf{issued\_assets}_{\mathsf{OUT}}$ to denote the input issuance state and output issuance state for a transaction, respectively.

<a id="specification-consensus-rule-changes"></a>

## Specification: Consensus Rule Changes

Let $\mathsf{SigHash}$ be the SIGHASH transaction hash of this transaction, as defined in §4.10 ‘SIGHASH Transaction Hashing’<a id="fnref32"></a>
[32](/zip/227?part=2#fn32) with the modifications described in ZIP 226<a id="fnref33"></a>
[33](/zip/227?part=2#fn33), using $\mathsf{SIGHASH\_ALL}$.

For every transaction:

- The `nActionGroupsOrchard` field MUST have a value of either `0` or `1` and the `nAGExpiryHeight` field MUST have a value of `0`.

- The output issuance state of the transaction MUST be initialized to be the same as the input issuance state, $\mathsf{issued\_assets}_{\mathsf{OUT}} = \mathsf{issued\_assets}_{\mathsf{IN}}$.

- The $\mathsf{assetBurn}$ set MUST satisfy the consensus rules specified in ZIP 226<a id="fnref34"></a>
  [34](/zip/227?part=2#fn34).

- It MUST be the case that for all $(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}$, $\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\mathsf{balance} \geq \mathsf{v}$. The node then MUST update $\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase})$ prior to processing the issuance bundle in the following manner. For every $(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{AssetBurn}$, $\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\mathsf{balance} = \mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\mathsf{balance} - \mathsf{v}$.

If the transaction contains an issuance bundle:

- It MUST also contain at least one OrchardZSA Action Group.

- The encoding $\mathsf{ik\_encoding}$ of the issuance key $\mathsf{ik}$ used to validate the issuance authorization signature MUST be taken from the `issuer` field, and MUST start with the byte value $\mathtt{0x00}$ indicating a BIP 340 public key.

- The issuance authorization signature, $\mathsf{issueAuthSig}$, MUST be a valid $\mathsf{IssueAuthSig}$ signature over $\mathsf{SigHash}$, i.e. $\mathsf{IssueAuthSig}.\!\mathsf{Validate}(\mathsf{ik}, \mathsf{SigHash}, \mathsf{issueAuthSig}) = 1$.

- For every issuance action description ($\mathsf{IssueAction}_\mathsf{i},\ 1 \leq i \leq \mathtt{nIssueActions}$) in the issuance bundle:
  
  
  
  - Every `IssueNoteDescription` in the `IssueAction` MUST be a valid field encoding as defined in ZIP 230<a id="fnref35"></a>
    [35](/zip/227?part=2#fn35).
  
  - Let an Issue Note (with type $\mathsf{Note^{Issue}}$) be constructed from the fields of each `IssueNoteDescription`, with the $\mathsf{AssetBase}$ derived from the `assetDescHash` field of the `IssueAction` and the `issuer` field of the issuance bundle, as described in the [Specification: Asset Identifier, Asset Digest, and Asset Base](#specification-asset-identifier-asset-digest-and-asset-base) section.
  
  - It MUST be the case that $\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\mathsf{final} \neq 1$.
  
  - If $\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\mathsf{note_{ref}} = \bot$, then let $\mathsf{new\_note_{ref}}$ be the first Issue Note in the Issuance Action.
    
    
    
    
    > - The recipient address $(\mathsf{d}, \mathsf{pk}_{\mathsf{d}})$ of $\mathsf{new\_note_{ref}}$ MUST be the default diversified payment address derived from the all-zero Orchard spending key, as described in the [Reference Notes](#reference-notes) section.
    > 
    > - The value of $\mathsf{new\_note_{ref}}$ MUST be $0$.
    > 
    > - The node MUST update $\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\mathsf{note_{ref}} = \mathsf{new\_note_{ref}}$.
  
  - For every Issue Note, $\mathsf{note}_j$ for $1 \leq j \leq \mathtt{nNotes}$ in `IssueAction`:
    
    
    
    
    
    - The $\text{ρ}$ field of the issue note MUST have been computed as described in the [Computation of ρ](#computation-of-ρ) section.
    
    - It MUST be the case that $\mathsf{issued\_assets}_{\mathsf{OUT}}.\mathsf{balance} + \mathsf{v}_j \leq \mathsf{MAX\_ISSUE}$, where $\mathsf{v}_j$ is the value of $\mathsf{note}_j$. The node then MUST update $\mathsf{issued\_assets}_{\mathsf{OUT}}.\mathsf{balance} = \mathsf{issued\_assets}_{\mathsf{OUT}}.\mathsf{balance} + \mathsf{v}_j$.
    
    - The node MUST compute the note commitment, $\mathsf{cm}_{\mathsf{i,j}}$, as defined in the Note Structure and Commitment section of ZIP 226<a id="fnref36"></a>
      [36](/zip/227?part=2#fn36).
  
  - If $\mathsf{finalize} = 1$ within the `flagsIssuance` field of `IssueAction`, the node MUST set $\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\mathsf{final} = 1$.

<a id="addition-to-the-note-commitment-tree"></a>

### Addition to the Note Commitment Tree

If the transaction is added to the block chain, the note commitments of all the OrchardZSA Notes and the Issue Notes in the transaction are added to the note commitment tree of the associated treestate. The order of addition to the tree is as specified below:

- For each Action Group in the OrchardZSA Bundle:
  
  
  
  - For every Action in the Action Group, append the note commitment of every new OrchardZSA note in the Action to the note commitment tree.

- For each Issue Action in the Issue Bundle:
  
  
  
  - For every Issue Note in the Issue Action, append the note commitment of the Issue Note to the note commitment tree.

<a id="rationale"></a>

## Rationale

The following is a list of rationale for different decisions made in the proposal:

- The issuance key structure is independent of the original key tree, but derived in an analogous manner (via ZIP 32). This keeps the issuance details and the Asset Identifiers consistent across multiple shielded pools. It also separates the issuance authority from the spend authority, allowing for the potential transfer of issuance authority without compromising the spend authority.

- The Custom Asset is described via a combination of the issuer identifier and an asset description string, to preclude the possibility of two different issuers creating colliding Custom Assets.

- The requirement of at least one OrchardZSA Action Group in the presence of an issue bundle is both to allow for the computation of the $\text{ρ}$ field of the issue notes, as well as to prevent replay attacks. 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.

<a id="hash-of-the-asset-description"></a>

### Hash of the asset description

In an earlier version of this ZIP, the asset description was a direct component of the Asset Identifier, and was stored on-chain in each issuance transaction. The Asset Identifier and issuance transactions now instead include a collision-resistant hash of the asset description, for the following reasons:

## Citation relationships

Cites: [ZIP 32](https://zips.tools/zip/32), [ZIP 200](https://zips.tools/zip/200), [ZIP 209](https://zips.tools/zip/209), [ZIP 224](https://zips.tools/zip/224), [ZIP 226](https://zips.tools/zip/226), [ZIP 230](https://zips.tools/zip/230), [ZIP 244](https://zips.tools/zip/244), [ZIP 246](https://zips.tools/zip/246), [ZIP 317](https://zips.tools/zip/317)

Cited by: [ZIP 226](https://zips.tools/zip/226), [ZIP 228](https://zips.tools/zip/228), [ZIP 230](https://zips.tools/zip/230), [ZIP 233](https://zips.tools/zip/233), [ZIP 248](https://zips.tools/zip/248), [ZIP 317](https://zips.tools/zip/317), [ZIP 321](https://zips.tools/zip/321), [ZIP 2005](https://zips.tools/zip/2005)