-
Notifications
You must be signed in to change notification settings - Fork 159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[outdated] ZIPs 226 & 227 - ZSA Protocol: Transfer, Issuance and Burn #649
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we might need to track all issued assets in the global state, not just finalized ones.
zip-0227.rst
Outdated
--------------------- | ||
|
||
Issuance requires the following additions to the global state: | ||
- `previously_finalized`, a set of `AssetId` that have been finalized (i.e.: the `finalize` flag has been set to `1`). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we also need to store a global list of AssetId
s or asset_desc
that have been previously issued?
How will the same assets be recognised across pools, if we don't store asset_desc
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Storing assetId
s and asset_desc
for non finalized assets is not required for properly verify consensus.
However, this information is very relevant and can be tracked by the client as part of an analytics service.
Across polls, assets are uniquely identified by the assetId
(which is driven from asset_desc
), so I don't think we need anything else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this commit us to always using the Pallas group hash to generate AssetId
, even if we deprecate or remove Orchard?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Specifically, the Orchard issuance action includes the asset_desc
, not the AssetId
, so we will always need the Pallas hash to be able to convert asset_desc
to AssetId
for verification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The design has now been updated such that the AssetId
is global, even across possible future shielded pools, with hashing done into the Orchard shielded pool at present. In future, a different hash could be used for a different pool.
zip-0317b.rst
Outdated
There are two main factors that will affect the fee mechanism: | ||
|
||
- The transaction size, which may take a big part of the block | ||
- The computational power needed to verify and mine the transaction |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about the storage size and lookup cost for the asset global state?
This might include the AssetId
, asset_desc
, and finalized
flag for every asset, which could be large in the case of NFTs.
(We could say that this covered because the global state size is proportional to the transaction size, and the lookup cost is proportional to the verification cost.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, we need to track the finalized assets as part of the global state.
So we need to consider having a bigger fee for finalized
assets which will make NFT minting more expansive then fungible tokens.
zip-0227.rst
Outdated
|
||
The design presented in this ZIP enables issuance of shielded assets in various modes: | ||
|
||
- The issuer knows in advance the receivers of the issued asset. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The issuer knows in advance the receivers of the issued asset. | |
- The issuer may or may not know the receivers of the issued asset in advance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We suggest that every asset is always issued into a specific address. If you issue to yourself, we still call this "receiver is known". Did you have another use in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So what you're saying is "the address of the receiver is always known in advance".
Does that statement belong in the requirements or consequences of the design, not in a section that specifically provides alternative modes?
(If there is no alternative, then "issuance of shielded assets in various modes" doesn't really apply.)
However, if you meant "the identity of the receiver is always known in advance", then here are some example use cases: - an address that is cryptographically impossible to spend from,
- an address that depends on solving a specific calculation, or
- a multi-signature address where most of the parties aren't known to the issuer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense, yes, thanks! Adding in the suggestion.
zip-0317b.rst
Outdated
------------------- | ||
|
||
As reasoned above, we propose a fee for each issuance action, `issuance_fee`, in order to prevent users from issuing "garbage" assets and to incentivize miners to maintain a more complex blockchain state. | ||
The proposed fee mechanism is that for each new asset type (i.e.: for each issuance action), the issuer will pay a fixed fee for the action itself, of `0.01 ZEC` or `1,000,000 ZATS`, and a proportional fee for each output note generated for that asset (which is kept in line with the proportional fee mechanism from ZIP 317 [#zip-0317]_). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As well as a finalization fee, do we want to add a specific burn fee here? Or is a burn enough like a transfer that the action fee is enough?
(Is it even possible to distinguish between burns and transfers?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We haven't included a burn fee, the action fee should be sufficient due to the similarity. However, note that burns are transparent, not shielded, so they aren't indistinguishable from transfers.
zip-0227.rst
Outdated
Requirements | ||
============ | ||
|
||
- Any user of the Zcash block chain can issue custom assets on chain |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reminder: wallets need to communicate the names of assets in a non-confusing way to users. This could be done with a petname system or with a list of well-known assets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
zip-0317b.rst
Outdated
------------------- | ||
|
||
As reasoned above, we propose a fee for each issuance action, `issuance_fee`, in order to prevent users from issuing "garbage" assets and to incentivize miners to maintain a more complex blockchain state. | ||
The proposed fee mechanism is that for each new asset type (i.e.: for each issuance action), the issuer will pay a fixed fee for the action itself, of `0.01 ZEC` or `1,000,000 ZATS`, and a proportional fee for each output note generated for that asset (which is kept in line with the proportional fee mechanism from ZIP 317 [#zip-0317]_). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The proposed fee mechanism is that for each new asset type (i.e.: for each issuance action), the issuer will pay a fixed fee for the action itself, of `0.01 ZEC` or `1,000,000 ZATS`, and a proportional fee for each output note generated for that asset (which is kept in line with the proportional fee mechanism from ZIP 317 [#zip-0317]_). | |
The proposed fee mechanism is that for each new asset type (i.e.: for each issuance action), the issuer will pay a fixed fee for the action itself, of `0.01 ZEC` or `1,000,000 ZATS`, and a proportional fee for each output note generated for that asset, including issuance outputs (which is kept in line with the proportional fee mechanism from ZIP 317 [#zip-0317]_). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file has been updated and is now tracked in PR#667.
zip-0317b.rst
Outdated
@@ -0,0 +1,161 @@ | |||
:: | |||
|
|||
ZIP: 0317b |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note for ZIP editors: Since this ZIP will be deployed with a network upgrade, and ZIP-317 will be deployed before the next network upgrade, we might want to:
- keep this ZIP separate from ZIP-317, and assign a different ZIP number for it.
(ZIP numbering is controlled by the ZIP editors.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ZIP editors discussed two other alternatives:
2. adding separate sections to the existing ZIP-317 which say what changes need to be made for ZSAs, with a deployment section that says they are made in whichever network upgrade ZSAs are scheduled in
3. adding separate sections to the relevant ZSA ZIP which describe the changes that need to be made to ZIP-317 due to that ZIP
If the changes are small, we have a preference for option 3, because all the changes for the ZSA ZIPs are together in the one place.
Otherwise, option 2 would be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: We have added separate sections to ZIP 317 to say the changes that occur for ZSAs, which corresponds to option 2 above. These changes are in PR#667.
zip-0227.rst
Outdated
- at the time of issuance, the issuer can already allocate all the tokens to the corresponding owners by creating the corresponding (shielded) output notes to the respective addresses. As is implied, the issuance mechanism is itself transparent, but the allocation is totally private | ||
- in a single issuance bundle, the issuer can publish many issuance actions, or in other words, create multiple custom assets | ||
- every issuance action contains the `finiteIssuance` boolean that defines whether that specific custom asset can have further tokens issued or not |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- at the time of issuance, the issuer can already allocate all the tokens to the corresponding owners by creating the corresponding (shielded) output notes to the respective addresses. As is implied, the issuance mechanism is itself transparent, but the allocation is totally private | |
- in a single issuance bundle, the issuer can publish many issuance actions, or in other words, create multiple custom assets | |
- every issuance action contains the `finiteIssuance` boolean that defines whether that specific custom asset can have further tokens issued or not | |
- At the time of issuance, the issuer can already allocate all the tokens to the corresponding owners by creating the corresponding (shielded) output notes to the respective addresses. As is implied, the issuance mechanism is itself transparent, but the allocation is totally private. | |
- In a single issuance bundle, the issuer can publish many issuance actions, or in other words, create multiple custom assets. | |
- Every issuance action defines whether that specific custom asset can have further tokens issued or not. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
zip-0227.rst
Outdated
1. The `issuanceAuthorizingKey`, denoted as `isk`, is the key that is used to sign the issuance transaction. This key is used to authorize the issuance of a specific asset type, and is only used by the issuer. Throughout we also call this key the issuer signature key. | ||
|
||
2. The `issuanceValidatingKey`, denoted as `ik`, is the key that is used to validate the issuance transaction. This key is used to validate the issuance of a specific asset type, and is used by all blockchain users (specifically the asset owners and consensus validators) to associate the asset in question with the issuer. Throughout we also call this key the issuer verification key. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's unfortunate that these names start with i
given the use of ivk
already for incoming viewing keys in Sapling and Orchard.
zip-0227.rst
Outdated
The two keys are derived in an analogous manner to the `spendAuthorizingKey` and `spendValidatingKey` keys, using the same signature scheme, as described in ZIP 32 [#zip-0032]_ and in accordance with ZIP 316 [#zip-0316]_. | ||
|
||
- The `issuanceAuthorizingKey` is derived directly from the `spendingKey`, `sk`, as a private signature key: | ||
|
||
:math:`\mathsf{isk := ToScalar^{Orchard}(︀ PRF^{expand}_{sk} ([0x0a])}` | ||
|
||
- The `issuanceValidatingKey` is derived from the `issuanceAuthorizingKey`, `isk`, as a public verification key: | ||
|
||
:math:`\mathsf{ik := SpendAuthSig^{Orchard}.DerivePublic(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 [#zip-0032]_, and can further be in 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's unclear what "the spendingKey
" refers to. If this is the Orchard spending key for a ZIP32 account, we think this is undesirable because the issuance protocol might need to be used for multiple shielded pools.
It is not necessary to tie the issuance key to a Orchard spending key in order for the issuance key to be recoverable from a wallet seed. We should instead carve out a namespace within the ZIP 32 hierarchy so that issuance keys can be derived from a wallet's seed phrase without being dependent on a particular protocol's key tree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we were referring to the Orchard spending key. Is the undesirability due to having to revert back to Orchard key generation for issuance even after moving to a future shielded pool, for example? Are there other reasons as well?
We should instead carve out a namespace within the ZIP 32 hierarchy so that issuance keys can be derived from a wallet's seed phrase without being dependent on a particular protocol's key tree
Issuance keys could instead be derived from a key generated from a wallet seed like in Orchard master key generation with a new personalisation (eg. ZcashIP32Issuance
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have recently made these changes, moving to a separately generated issuance key structure that gets generated from the wallet seed.
zip-0227.rst
Outdated
================= ================== ========================== ======================================================================== | ||
Size Name Data Type Description | ||
================= ================== ========================== ======================================================================== | ||
Varies asset_desc byte Uni-code encoded string of varied size, up to 512 bytes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Varies asset_desc byte Uni-code encoded string of varied size, up to 512 bytes | |
Varies asset_desc byte UTF-8 encoded string of varied size, up to 512 bytes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
zip-0227.rst
Outdated
|
||
**Bridging Assets** | ||
Issuers can wrap assets defined in other chains and issue them at once in a single transaction. The specifics of the bridge are not implemented in the protocol, but there are several ways we conceive issuers can build these bridges (at least centralized bridges): | ||
- First, the issuance and burn mechanism can be used in conjunction to determine the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ends incompletely?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have fixed this
zip-0227.rst
Outdated
Concrete applications | ||
--------------------- | ||
|
||
**Bridging Assets** | ||
Issuers can wrap assets defined in other chains and issue them at once in a single transaction. The specifics of the bridge are not implemented in the protocol, but there are several ways we conceive issuers can build these bridges (at least centralized bridges): | ||
- First, the issuance and burn mechanism can be used in conjunction to determine the | ||
|
||
**Asset Features** | ||
- By using the `finalize` boolean and the burning mechanism defined in [#zip-0226]_, issuers can control the supply production of any asset associated to their issuer keys. For example, | ||
- by setting `finalize = 1` from the first issuance action for that asset type, the issuer is in essence creating a one-time issuance transaction. This is useful when the max supply is capped from the beginning and the distribution is known in advance. All tokens are issued at once and distributed as needed. | ||
- Issuers can also stop the existing supply production of any asset associated to their issuer keys. This could be done by | ||
- issuing a last set of tokens of that specific `AssetId`, while at the same time setting `finalize = 1`, or by | ||
- issuing a transaction with a single note in the issuance action pertaining to that `AssetId`, where the note will contain a `value = 0`. This can be used for application-specific purposes (NFT collections) or for security purposes to revoke the asset issuance (see Security and Privacy Considerations). | ||
- Furthermore, NFT issuance is enabled by issuing in a single bundle several issuance actions, where each `AssetId` corresponds to `value = 1` at the fundamental unit level. Issuers and users should make sure that `finalize = 1` for each of the actions in this scenario. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section feels like a hybrid of use-case and rationale; should this be in the Specification
section?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A section after would allow using the Specification
for particular applications such as wrapping
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have rearranged this
zip-0227.rst
Outdated
- By using the `finalize` boolean and the burning mechanism defined in [#zip-0226]_, issuers can control the supply production of any asset associated to their issuer keys. For example, | ||
- by setting `finalize = 1` from the first issuance action for that asset type, the issuer is in essence creating a one-time issuance transaction. This is useful when the max supply is capped from the beginning and the distribution is known in advance. All tokens are issued at once and distributed as needed. | ||
- Issuers can also stop the existing supply production of any asset associated to their issuer keys. This could be done by | ||
- issuing a last set of tokens of that specific `AssetId`, while at the same time setting `finalize = 1`, or by |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- issuing a last set of tokens of that specific `AssetId`, while at the same time setting `finalize = 1`, or by | |
- issuing a last set of tokens of that specific `AssetId` during which `finalize = 1`, or by |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused by this wording; we decided I think that setting finalization would take effect after all of the transactions in the block (on the grounds that a miner could in any case reorder transactions to put all the finalization ones last). That should be clarified.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have added a bullet clarifying this.
zip-0227.rst
Outdated
- `notes`: an array containing the unencrypted output notes of the recipients of the asset, of type `Note` | ||
- `finalize`: a boolean that defines whether the issuance of that specific custom asset is finalized or not | ||
|
||
Once `finiteSupply` is set to 1, it cannot be unset. For assets whose `finalize = 1`, no further tokens can be issued, so as seen below, the validators will reject the transaction. For assets whose `finalize = 0`, new issuance actions can be issued in future transactions. These must use the same asset description, `asset_desc`, and can either maintain `finalize = 0` or change it to `1`, denoting the last transaction containing issuance of such custom asset. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once `finiteSupply` is set to 1, it cannot be unset. For assets whose `finalize = 1`, no further tokens can be issued, so as seen below, the validators will reject the transaction. For assets whose `finalize = 0`, new issuance actions can be issued in future transactions. These must use the same asset description, `asset_desc`, and can either maintain `finalize = 0` or change it to `1`, denoting the last transaction containing issuance of such custom asset. | |
Once `finalize` is set to 1, it cannot be unset. For assets whose `finalize = 1`, no further tokens can be issued, so as seen below, the validators will reject the transaction. For assets whose `finalize = 0`, new issuance actions can be issued in future transactions. These must use the same asset description, `asset_desc`, and can either maintain `finalize = 0` or change it to `1`, denoting the last transaction containing issuance of such custom asset. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If finalize = 1
takes effect only after the block containing the finalization tx, then we cannot conclude that it is the last tx issuing the asset (see also #649 (comment)).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been removed, we no longer say it is the last transaction
zip-0227.rst
Outdated
---------------------- | ||
|
||
For the IssueBundle, | ||
- Verify the RedPallas-based issuance authorization signature on `SIGHASH`, `authorization` is valid, based on `authorization.VerifySig(ik, SIGHASH)` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
authorization
field in the IssuanceBundle is 64 bytes, this needs to be explicitly serialized / deserialized and have parsing rules for the signature type itself
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have resolved this comment in our sync and made the updates.
|
||
Let | ||
|
||
- :math:`\mathsf{asset\_desc}` be the asset description, a UTF-8 encoded string of up to 512 bytes, which includes any information pertaining to the issuance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which version of UTF-8?
Here's how another project defined UTF-8 in a way that doesn't change with unicode versions:
https://github.com/torproject/torspec/blob/main/proposals/285-utf-8.txt#L70-L105
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As in the next comment, we fixed this to recommend it be a well-formed UTF-8 code sequence, without making it a MUST.
|
||
Let | ||
|
||
- :math:`\mathsf{asset\_desc}` be the asset description, a UTF-8 encoded string of up to 512 bytes, which includes any information pertaining to the issuance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is not currently any case in which Zcash consensus depends on the definition of UTF-8. (For memo fields in decrypted shielded coinbase outputs, the plaintext memo is not required to be well-formed UTF-8, since the relevant consensus rule only requires that decryption with the zero
Also, "UTF-8 encoded string" is ambiguous as to whether it is required to be well-formed and the applicable version of Unicode (the definition of "well-formed" UTF-8 changed in Unicode 3.1 and again in Unicode 3.2, for example).
Either:
- Define the asset description as a byte sequence and say that it SHOULD be a well-formed UTF-8 code unit sequence according to Unicode 15.0.0 or later; or
- Say that it is a consensus rule that the asset description MUST be a well-formed UTF-8 code unit sequence according to exactly Unicode 15.0.0 chapter 3, clause D92.
In either case, clarify that it MAY include encoded characters that are unassigned in any particular version of Unicode. I suggest 1. rather than 2. (partly because checking UTF-8 well-formedness would be annoying in a circuit, and although this consensus rule does not currently need to be enforced in a circuit, that might change later).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Went ahead with alternative 1.
Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com>
Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com>
* changes to issuance_txid_digest to align with ZIP 244 * using flagsIssuance in place of a single bit boolean for the issue actions as well * fixing small typo
* changes to issuance_txid_digest to align with ZIP 244 * using flagsIssuance in place of a single bit boolean for the issue actions as well * adding assetDescSize field to IssueAction, and corresponding changes to the consensus rule changes section * rename authorization to issueAuthSig
This Pr is deprecated in favor of #676 |
This PR includes the three core zips defining the ZSA protocol, and is a continuation of the work started in the PR #628