zips
zips copied to clipboard
Requirements for Unified Addresses
Unified Address Overview
Unified Addresses specify multiple methods for payment to a Recipient's Wallet. The Sender's Wallet can then non-interactively select the method of payment.
Importantly, any wallet can support Unified Addresses, even when that wallet only supports a subset of payment methods.
Despite having some similar characteristics, the Unified Address standard is orthogonal to Payment Request URIs and similar schemes, and the Unified Address format is likely to be incorporated into such schemes as a new address type.
Status
This ticket is a proposed set of requirements, which I'd like to refine with Zcash development community to see if we can agree on a standard along these lines. If there's enough support (especially from wallet vendors), the next step would be to draft a ZIP specification that meets these requirements.
At Electric Coin Co, we have a desire to see if the ecosystem can safely standardize on this approach prior to activating Orchard. The rationale for introducing Unified Addresses as a dependency is that it would avoid introducing the what these requirements call a "Legacy Address" for Orchard, because every Legacy Address introduces fragmentation costs to the ecosystem in usability (such as "address negotiation") and development/infrastructure support. We're sharing these requirements now to get feedback from Zcash core & wallet devs and the rest of the community on the requirements themselves, but also the timeline, the notion of combining this with Orchard, and other strategic factors.
(Note: these are a paraphrase of messy internal documents around requirements, so I don't guarantee these represent the full agreement/commitment of all ECC folks, and we can/should just continue to refine them with the broader community.)
Goals
The goals for a Unified Address Standard are as follows:
- Simplify coordination between receivers and senders of Zcash wallets by removing complexity from negotiating address types.
- Provide a “bridging mechanism” to allow shielded wallets to successfully interact with (conformant) Transparent Only wallets.
- Allow older conformant wallets to interact seamlessly with newer wallets.
- Enable users of newer wallets to upgrade to newer transaction technologies and/or pools while maintaining seamless interactions with counterparties with older wallets.
- Allow wallets to shoulder more sophisticated responsibilities for shielding and/or migrating user funds.
- Allow wallets to potentially develop new transfer mechanisms without underlying protocol changes.
- Provide forwards compatibility that's standard for all wallets across a range of potential future features. Some examples might include Layer 2 features, cross-chain interoperability and bridging, and decentralized exchange.
- The standard works well for Zcash today and upcoming potential upgrades, yet it also anticipates even broader use cases down the road such as cross-chain functionality.
Concepts and Terminology
- A Recipient is a wallet or other software that can receive ZEC transfers (or in the future potentially other assets or transaction-based state changes).
- A Sender is a wallet or other software that can send ZEC transfers (or other assets, or other future consensus state side-effects).
- Wallets follow a model Interaction Flow as follows:
- First, a Recipient generates an Address.
- Second, the Recipient wallet or human user distributes this Address through any number mechanisms which may be "out-of-band" (example: they spray paint a QR Code on a sign) or they may be more or less "in-band" (example: they include a
Reply-Toaddress in an encrypted memo following a common standard). - Third, a Sender wallet or user imports the Address through a variety of mechanisms (QR Code scanning, cut'n'paste, "in-band" protocols like Payment URIs or
Reply-Tomemos). - Fourth, the Sender wallet executes a Transfer of ZEC (or other assets or future protocol state changes) to the Address.
- These steps are a funnel: the same Address may be distributed 0 or more times through different means. Zero or more Senders may import addresses. Zero or more of those may execute a Transfer. A single Sender may execute multiple Transfers over time from a single import.
- An Address is either a Legacy Address or a Unified Address.
- A Unified Address (henceforth UA) combines multiple Receivers.
- A Legacy Address (or LA) is a Transparent, Sprout, or Sapling Address.
- A Receiver is the necessary information to transfer ZEC [1] to the Recipient which generated that Receiver using a specific Transfer Protocol.
- Each Receiver is associated unambiguously with a specific Receiver Type.
- Each Receiver Type by definition designates unambiguously a Transfer Protocol.
- A Transfer Protocol fully specifies how a Sender can transfer ZEC (or issue other kinds of relevant transaction actions) to the Recipient. For example, the Transfer Protocol for a Sapling Receiver is the subset of the Zcash protocol required to successfully transfer ZEC using either
Sapling Spend/Output Transfersas specified in the current Zcash Protocol Spec.- Clarification: A single Zcash transaction can contain transfers of multiple Transfer Protocols. For example a t→z transaction that shields to the Sapling pool requires both Transparent and Sapling Transfer Protocols.
- Clarification: All of the consensus rules around Transaction and Block validity as well as Proof-of-Work consensus and so on are dependencies of the current set of existing Transfer Protocols. This standard anticipates the possibility of future Transfer Protocols which do not rely on Zcash base layer consensus.
- A Transport Encoding is the externally visible encoding of an Address. It is common both in this document (where we believe it's unambiguous) and in casual usage for people to conflate an Address with it's Transport Encoding.
Examples:
- Example 1: A Transparent
P2PKHReceiver may be encoded with the existing well knownt1-prefixed base58 Legacy Address encoding for Transparent Addresses. - Example 2: A Transparent
P2PKHReceiver may be encoded as the sole Receiver within a Unified Address using the (single, standard) Unified Address encoding.
Requirements
Addresses
- A Unified Address (or UA for short) combines one or more Receivers.
- When new Transport Protocols are introduced to the Zcash protocol after Unified Addresses are standardized those SHOULD introduce new Receiver Types but not different address types outside of the UA standard. There needs to be a compelling reason to deviate from the standard, since the benefits of UA come precisely from their applicability across all new protocol upgrades.
Receivers
- Every Wallet MUST anticipate and properly parse a UA with any unknown arbitrary Receiver Type.
- When Transferring a Sender MUST behave as if any unknown Receiver Type is simply not present for the purposes of the transfer.
- A Wallet MAY process unknown Receiver Types by indicating to the user their presence or similar information for usability or diagnostic purposes.
Transport Encoding
- The encoding is "opaque" to human readers: it does NOT allow visual identification of which Receivers or Receiver Types are present.
- Rationale: The general thinking behind UAs is to allow wallets to streamline user experience. If human users can parse a UA and alter their behavior based on that, then different users will end up using the same wallet very differently. Note that this does not preclude a wallet from providing user-friendly displays or indications about Receiver support, and the wallet's UX design can decide when and how to do this and build a behavioral flow around that.
- The encoding is resilient against typos, transcription errors, cut'n'paste errors, unanticipated truncation, or other anticipated UX hazards. (FIXME: How resilient? I generally think "as good as base58 or bech32 is good enough" but I haven't studied this area well.)
- The encoding works well in QR Codes.
- The encoding fits into ZIP-321 Payment URIs and general URIs without introducing parse ambiguities.
- The encoding MUST support an arbitrary number of unknown Recipient Types without requiring centralized coordination around the encoding for those new Types.
- However, the encoding may provide for optimizations for a well known set of standardized Receiver Types where those optimizations require centralized coordination. For example there may be a distinction between a more optimized "reserved space" that's allocated through centralized coordination as long as there's also a possibility for permissionless experimentation (similar thinking to HTTP
X-headers or "small values are reserved, but large random values are open to all). - The encoding MUST allow all wallets to safely and correctly parse out unknown Receiver Types well enough to ignore them.
- However, the encoding may provide for optimizations for a well known set of standardized Receiver Types where those optimizations require centralized coordination. For example there may be a distinction between a more optimized "reserved space" that's allocated through centralized coordination as long as there's also a possibility for permissionless experimentation (similar thinking to HTTP
Transfer
- When executing a Transfer the Sender selects a transfer method via a Selection process.
- Selection MUST treat any unrecognized Receiver as if it were absent.
- By implication: Selection must behave identically between any two UAs where one is a subset of the other containing all of the same known Receivers and no unknown Receivers.
- This property is crucial for forwards compatibility to ensure users who upgrade to newer protocols / UAs don't lose the ability to smoothly interact with older wallets.
- This property is crucial for allowing Transparent-Only UA-Conformant wallets to interact with newer shielded wallets, removing a disincentive for adopting newer shielded wallets.
- This property also allows Transparent-Only wallets to upgrade to shielded support without re-acquiring counterparty UAs, or even when they are re-acquired the user flow and usability will be minimally disrupted.
Open Issues and Known Concerns
FIXME: We have a few of these I will add in future edits. This is especially true of privacy impacts of transparent or cross-pool transactions and the associated UX issues.
EDIT: I may not fully understand the proposed implementation based on this tweet https://twitter.com/jswihart/status/1381675869203132416. Does this mean wallets can still "opt-out" to receive funds in transparent addresses? In that case, the following still applies:
Apologies for not responding earlier, but I am first hearing of this today, and I have significant concerns.
Unified addresses have the potential to severely damage a user's privacy expectations, and senders will be far more likely to accidentally leak undesired metadata based on a misunderstanding caused by a bad wallet.
In the current implementation, somewhat informed users know that "t-address" = "transparent and "z-address" = "shielded."
Informed users may prefer to use Zcash as is actively encouraged: only using fully shielded transactions. There is significant research that indicates that using transparent and partially-shielded transactions leaks meaningful metadata, which may severely damage the user's privacy.
Thus, it is critical that a user understands if they are sending funds to a shielded or transparent pool. It is not sufficient to say that the sender is protected no matter which pool they are sending funds to. This is well understood based on Quesnelle-style analysis and others.
Unified addresses are not directly distinguishable to the sender as going to the shielded or transparent pool. The sender is reliant on the wallet to properly inform that 1) they are sending to a t-address, and 2) the risks of doing so. Relying on wallet implementations to properly inform users of these things is a step backwards from the current status quo. The ECC has no control over community wallets and how they present this information to senders.
By going forward with this implementation as I understand it, there will be more users who send funds to the transparent pool by mistake, who lose enormous privacy protections as a result.
Informed users may prefer to use Zcash as is actively encouraged: only using fully shielded transactions.
Unified addresses do not prevent this use case. A "Unified Address" encodes the preferences of the payment recipient (e.g. a user may not want to receive funds to a transparent address, or may only want to support transparent and Orchard but not Sapling). The sender's wallet then combines this recipient preference information with the sender's expressed preferences (e.g. that they don't want to send to a transparent address, in your example) and the wallet's own abilities (e.g. does it support creating Orchard outputs), to figure out the "best common denominator" - the combination of payment protocols that enables the sender and recipient to "communicate" (with an inherent / unavoidable preference to aiding the sender, since they are the one making the transaction).
Unified addresses are not directly distinguishable to the sender as going to the shielded or transparent pool. The sender is reliant on the wallet to properly inform that 1) they are sending to a t-address, and 2) the risks of doing so. Relying on wallet implementations to properly inform users of these things is a step backwards from the current status quo. The ECC has no control over community wallets and how they present this information to senders.
Senders are already reliant on the wallet for far more than this, e.g. they have to trust that the wallet correctly informs them of the address a transaction is going to send funds to, in order to protect against copy-paste-buffer attacks (or a malicious wallet). A wallet can also trivially break privacy by creating a "Sapling -> transparent -> Sapling" pair of transactions instead of a "Sapling -> Sapling" transaction, or publishing the private details of a shielded transaction on Pastebin.
Users are thus already required to trust their wallet in a myriad of ways to protect their privacy. UAs do not alter that dynamic, and in fact improve upon it:
- UAs will require a shielded address to be present. Thus a purely-transparent UA is not valid, and a "purely-transparent address" is just a normal t-addr, distinguishable from a UA by informed users.
- If a recipient provides a UA containing an address for a newer shielded protocol, to a sender whose wallet doesn't know about that protocol yet, then as soon as the sender's wallet upgrades to support sending to that protocol, it can immediately start using it with that address.
- Wallets SHOULD (in the RFC 2119 sense, though I wouldn't trust a wallet that did otherwise) select the recipient address that affords the best privacy. Thus the only time a UA-aware sender's wallet would send to a t-addr is if the sender's wallet does not know how to send to any shielded addresses that the recipient provides, and thus could not engage in the economic transaction that the sender is clearly expressing a desire to engage in.
If the recipient only provides Orchard and transparent but not Sapling (very unlikely for the initial rollout given that wallets today are either transparent-only, Sapling-only, or both, and if a receiving wallet is adding UA support then it will also likely be adding Orchard support), and the sender's wallet only supports sending to transparent and Sapling but not Orchard, and the sender wants to make a payment, then the sender is required to either send to a transparent address, or not make the payment at all. If the sender has expressed a "no transparent" preference (e.g. in wallet settings, or by using a shielded-only wallet) then the wallet would prevent this transaction from being made at all, by design.