zips/zip-0320.rst

389 lines
19 KiB
ReStructuredText
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

::
ZIP: 320
Title: Defining an Address Type to which funds can only be sent from Transparent Addresses
Owners: Daira-Emma Hopwood <daira@electriccoin.co>
Kris Nuttycombe <kris@nutty.land>
Credits: Hanh
Status: Draft
Category: Standards / Wallet
Created: 2024-01-12
License: MIT
Discussions-To: <https://github.com/zcash/zips/issues/757>
Pull-Request: <https://github.com/zcash/zips/pull/760>
<https://github.com/zcash/zips/pull/766>
Terminology
===========
The key words "MUST", "SHOULD", and "MAY" in this document are to be
interpreted as described in BCP 14 [#BCP14]_ when, and only when, they appear
in all capitals.
The terms "Recipient", "Producer", "Consumer", "Sender", "Receiver", "Item",
"Metadata Item", "Typecode", "Address", "Unified Address" (UA), "Unified
Viewing Key" (UVK), "Unified Full Viewing Key" (UFVK), and "Unified Incoming
Viewing Key" (UIVK) are to be interpreted as described in ZIP 316
[#zip-0316-terminology]_.
The terms "Testnet" and "Mainnet" are to be interpreted as described in section
3.12 of the Zcash Protocol Specification [#protocol-networks]_.
Abstract
========
This ZIP defines a new encoding for transparent Zcash addresses. Wallets must
ensure that no shielded notes are spent in transactions that send to a
transparent address encoded in the specified fashion.
This ZIP is presently in Draft status, and defines two alternate encodings for
consideration. Analysis of the benefits and drawbacks of each of the proposed
alternatives is presented at the end of this document.
Background
==========
In November of 2023, the Zcash community received notice from the Binance
cryptocurrency exchange that Zcash was at risk of being delisted from the
exchange unless the community could provide a mechanism by which Binance could
refuse deposits from shielded addresses and return them to the depositor. This
issue was raised and discussed at length in the Zcash Community forum
[#binance-delisting]_.
In the course of that discussion thread, wallet developer and community member
@hanh [#hanh-profile]_ suggested a wallet-oriented approach [#hanh-suggestion]_
that involved defining a new encoding for Zcash transparent P2PKH addresses. A
Consumer of such an address, whether it be a wallet or an exchange, could
recognize this encoding as a directive that the wallet should only spend
transparent funds when creating an output to that address.
Motivation
==========
The Binance cryptocurrency exchange requires that funds sent to their deposit
addresses come from source addresses that are readily identifiable using
on-chain information, such that if necessary funds may be rejected by sending
them back to the source address(es). This ZIP is intended to standardize a
transparent address encoding that is not yet understood by preexisting
Consumers, in order to prevent inadvertent shielded spends when sending to such
addresses. Then, Consumers that upgrade to support the new encoding will do so
with the understanding that they must respect the restrictions on sources of
funds described in this ZIP.
Requirements
============
1. A Recipient wishing to receive funds from exclusively transparent sources
must be able to generate a receiving address such that only transparent
funds will be spent in transactions with an output to this address.
2. Wallets and other Consumers that have not been upgraded to recognize the new
address format cannot mistake the address for another address type or
inadvertently send shielded funds to the address.
3. No changes to Recipient infrastructure beyond changes to address encoding
and decoding should be required as a consequence of this ZIP.
Alternative 1
=============
This alternative was suggested by @hanh in [#hanh-suggestion]_.
TEX Addresses
-------------
A TEX Address is a Bech32m [#bip-0350]_ reencoding of a transparent Zcash
P2PKH address [#protocol-transparentaddrencoding]_.
Motivations for Alternative 1
-----------------------------
The TEX Address is the simplest possible approach to creating a new address
type that indicates that only transparent sources of funds should be used.
Specification (Alternative 1)
-----------------------------
A TEX address is produced from a Mainnet Zcash P2PKH Address by executing the
following steps:
1. Decode the address to a byte sequence using the Base58Check decoding
algorithm [#Base58Check]_.
2. If the length of the resulting byte sequence is not 22 bytes or if its two-byte
address prefix is not :math:`[\mathtt{0x1C}, \mathtt{0xB8}]`, return an error. Otherwise,
let the **validating key hash** be the remaining 20 bytes of the sequence after
removing the two-byte address prefix.
3. Reencode the 20-byte **validating key hash** using the Bech32m encoding
defined in [#bip-0350]_ with the human-readable prefix (HRP) ``"tex"``.
For Testnet addresses, the required lead bytes of a P2PKH address in step 2 are
:math:`[\mathtt{0x1D}, \mathtt{0x25}]`, and the ``"textest"`` HRP is used when
reencoding in step 3.
Wallets and other Senders sending to a TEX address (as any output) MUST
ensure that only transparent UTXOs are spent in the creation of a
transaction.
Reference Implementation (Alternative 1)
----------------------------------------
Javascript::
import bs58check from 'bs58check'
import {bech32m} from 'bech32'
// From t1 to tex
var b58decoded = bs58check.decode('t1VmmGiyjVNeCjxDZzg7vZmd99WyzVby9yC')
console.assert(b58decoded.length == 22, 'Invalid length');
console.assert(b58decoded[0] == 0x1C && b58decoded[1] == 0xB8, 'Invalid address prefix');
var pkh = b58decoded.slice(2)
var tex = bech32m.encode('tex', bech32m.toWords(pkh))
console.log(tex)
// From tex to t1
var bech32decoded = bech32m.decode('tex1s2rt77ggv6q989lr49rkgzmh5slsksa9khdgte')
console.assert(bech32decoded.prefix == 'tex', 'Invalid address prefix')
var pkh2 = Uint8Array.from(bech32m.fromWords(bech32decoded.words))
console.assert(pkh2.length == 20, 'Invalid length');
var t1 = bs58check.encode(Buffer.concat([Uint8Array.from([0x1C, 0xB8]), pkh2]))
console.log(t1)
Alternative 2
=============
Traceable Unified Addresses
---------------------------
A Traceable Unified Address is a reencoding of a transparent Zcash P2PKH
address into a Unified Address [#zip-0316-unified-addresses]_.
Motivations for Alternative 2
-----------------------------
Traceable Unified Addresses fit into the Zcash Unified Address ecosystem
defined by ZIP 316, Revision 1 [#zip-0316-revision-1]_. Existing Consumers of
Unified Addresses will not be able to send to these address unless they update
their code to understand the new MUST-understand Metadata Typecode defined in
this ZIP.
By integrating with the Unified Address framework, it becomes possible for the
addresses being generated to include extra metadata; in particular, metadata
items such as an Address Expiry Height or Address Expiry Date
[#zip-0316-address-expiry]_ may be included. For exchange use cases such as
Binance's, it is useful to ensure that an address provided to a user has a
limited utility life, such that after expiration the user must obtain a new
address in order to be able to continue to send funds
[#binance-address-expiry]_.
Specification (Alternative 2)
-----------------------------
Upon activation of this ZIP, the section `Metadata Items` of ZIP 316
[#zip-0316-metadata-items]_ will be modified to define a new MUST-understand
Metadata Item type: Source Restriction Metadata, having Typecode
:math:`\mathtt{0xE2}`, the value of which MUST be a single byte:
* :math:`\mathtt{0x00}` - Transparent Source Only
Additional Source Restriction Metadata values can be defined in the future,
but a Consumer that does not recognise the value MUST reject the entire
UA/UVK as invalid.
The "Requirements for both Unified Addresses and Unified Viewing Keys" section
of ZIP 316 [#zip-0316-unified-requirements]_ will be modified as follows — the
text:
A Unified Address or Unified Viewing Key MUST contain at least one
shielded Item (Typecodes :math:`\mathtt{0x02}` and :math:`\mathtt{0x03}`).
The rationale is that the existing P2SH and P2PKH transparent-only
address formats, and the existing P2PKH extended public key format,
suffice for representing transparent Items and are already supported
by the existing ecosystem.
will be replaced by:
A Unified Address or Unified Viewing Key MUST **either**:
* contain at least one shielded Item (Typecodes :math:`\mathtt{0x02}`
and :math:`\mathtt{0x03}`), and **no** Source Restriction Metadata Item
having value :math:`\mathtt{0x00}`; **or**
* contain **both** a Transparent Item (Typecode :math:`\mathtt{0x00}` or
Typecode :math:`\mathtt{0x01}`) **and** a Source Restriction Metadata Item
(Typecode :math:`\mathtt{0xE2}`) having value :math:`\mathtt{0x00}`, and
**no other** non-Metadata Items.
In the following, the “``u+``” Human Readable Part of Revision 1 Unified
Addresses is a placeholder value, pending the finalization of Revision 1
[#zip-0316-revision-1]_.
A Traceable Unified Address is produced from a Mainnet Zcash P2PKH address by
executing the following steps:
1. Decode the address to a byte sequence using the Base58Check decoding
algorithm [#Base58Check]_.
2. If the length of the resulting byte sequence is not 22 bytes or if its
two-byte address prefix is not :math:`[\mathtt{0x1C}, \mathtt{0xB8}]`,
return an error. Otherwise, let the **validating key hash** be the remaining
20 bytes of the array after removing the two-byte address prefix.
3. Construct a new Revision 1 Unified Address using a single P2PKH Receiver
:math:`\mathtt{0x04}` with the 20-byte **validating key hash** as its value,
and a Source Restriction Metadata Item (Typecode :math:`\mathtt{0xE2}`)
having value :math:`\mathtt{0x00}` (Transparent Source Only). In addition,
metadata items such as an Address Expiry Height or Address Expiry Date
[#zip-0316-address-expiry]_ MAY be included.
4. Encode the Unified Address using the “``u+``” Human Readable Part as
specified for Revision 1 of ZIP 316 [#zip-0316-unified-addresses]_.
For Testnet addresses, the required lead bytes of a P2PKH address in step 2
are :math:`[\mathtt{0x1D}, \mathtt{0x25}]`.
The HRP of the resulting Unified Address is the same as for any other Revision 1
Unified Address on the relevant network as specified in [#zip-0316-revision-1]_,
i.e. ``"u+"`` for Mainnet and ``"u+test"`` for Testnet.
Wallets and other Senders MUST ensure that only transparent UTXOs are spent in
the creation of a transaction to any Unified Address containing a Source
Restriction Metadata Item having value :math:`\mathtt{0x00}`.
Any Source Restriction Metadata Item MUST be preserved with the same value
when deriving a UIVK from a UFVK, or a UA from a UIVK. It has no other effect
on the meaning of the UFVK or UIVK.
Reference Implementation (Alternative 2)
----------------------------------------
Javascript using `zcash_address_wasm` [#zcash_address_wasm]_::
import init, { to_traceable_address, traceable_to_p2pkh, addr_expiry_time } from 'zcash_address_wasm';
init().then(() => {
var t_address = "t1VmmGiyjVNeCjxDZzg7vZmd99WyzVby9yC";
console.log("original P2PKH address: " + t_address);
var expiry_time = new Date();
// Add 30 days in UTC.
expiry_time.setUTCDate(expiry_time.getUTCDate() + 30);
// Date.getTime() returns UTC time since 1970-01-01T00:00:00Z in milliseconds.
var expiry_unix_seconds = BigInt(Math.floor(expiry_time.getTime() / 1000));
var traceable_address = to_traceable_address(t_address, expiry_unix_seconds);
console.log("Traceable Unified Address: " + traceable_address);
var p2pkh_addr = traceable_to_p2pkh(traceable_address);
console.log("decoded P2PKH address: " + p2pkh_addr);
var expiry = addr_expiry_time(traceable_address);
// Ignore far-future expiry times not representable as a Date.
if (expiry !== null && expiry <= 8_640_000_000_000n) {
console.log("expiry time: " + new Date(Number(expiry) * 1000).toUTCString());
}
});
Example output::
original P2PKH address: t1VmmGiyjVNeCjxDZzg7vZmd99WyzVby9yC
Traceable Unified Address: u1p3temdfuxr6vcfr2z3n5weh652rg0hv7q44c652y3su77d0pyktt47am3tng7uxxtk553hhka75r6cvfs5j
decoded P2PKH address: t1VmmGiyjVNeCjxDZzg7vZmd99WyzVby9yC
expiry time: Mon Feb 13 2024 01:14:18 GMT
Analysis of Alternative 1
=========================
Pros to Alternative 1
---------------------
- The reencoding from Zcash P2PKH addresses is extremely straightforward and
relies only upon widely available encoding libraries.
Cons to Alternative 1
---------------------
- Existing wallets and other Consumers will regard the new address type as
entirely invalid, and will not automatically prompt their users that they
need to upgrade in order to send to this type of address.
- Creation of a new fully distinct address type further fragments the Zcash
address ecosystem. Avoiding such fragmentation and providing smooth upgrade
paths and good error messages to users is exactly the problem that Unified
Addresses [#zip-0316-unified-addresses]_ were intended to avoid.
- The TEX address type does not provide any mechanism for address expiration.
One of the questions Binance has asked has been what to do about users who
have stored their existing transparent deposit address in their wallets, or
use them as a withdrawal address for other exchanges or services. This is a
challenging problem to mitigate now because address expiration was not
previously implemented. We should not further compound this problem by
defining a new distinct address type that does not provide a mechanism for
address expiry.
Analysis of Alternative 2
=========================
Pros To Alternative 2
---------------------
- By integrating with the Unified Address framework, Consumers of Revision 1
Unified Addresses that have not yet been upgraded to recognize these
addresses can automatically be prompted to upgrade their wallets or services
to understand the unrecognized MUST-understand Metadata Typecode.
- It is possible to include address expiration metadata in a Traceable Unified
Address, which can help to mitigate problems related to stored addresses in
the future.
- The Source Restriction Metadata feature can easily be extended to express
other kinds of source restriction, such as "Shielded Source Only" or
"Fully Shielded with No Pool Crossing".
- Traceable Unified Addresses benefit from the robustness to errors and
protection against malleation of Unified Addresses [#F4Jumble]_.
- Regardless of which proposal is adopted, the Zcash Community will need to
work with exchanges other than Binance to update their address parsing logic
to understand the new address format. By encouraging Consumers such as
exchanges to adopt parsing for Unified Addresses, this proposal furthers the
original goal of Unified Addresses to reduce fragmentation in the address
ecosystem.
Whenever any new feature is added, wallets have a choice whether or not to
support that new feature. The point of Unified Address parsing is that
wallets dont have to upgrade to recognize a different address format as a
valid Zcash address. Instead of returning a “Not a valid Zcash address”
error, which could be confusing for users, they can return an error more like
“This is a valid Zcash address, but this wallet does not support sending to
it.” This can be used as a prompt to upgrade the wallet to a version (or
alternative) that does support that feature.
For example: numerous wallets have already upgraded to being able to parse
Unified Addresses. Those wallets, on seeing a Traceable Unified Address from
Binance, will report to their users that the address is a valid Zcash
address, but not yet supported by the wallet. Instead of a user thinking that
Binance has made some error, they can contact the wallets developer and ask
that the wallet be updated.
Cons to Alternative 2
---------------------
- Existing wallets and other Consumers of Revision 0 Unified Addresses will
regard the new address type as entirely invalid, and will not automatically
prompt their users that they need to upgrade in order to send to this type of
address.
- Unified Address encoding is slightly more complex than the proposed TEX
address encoding, and requires use of the F4Jumble encoding algorithm
[#F4Jumble]_. However, this can be readily mitigated by providing a
purpose-built library for Traceable Unified Address encoding to Producers.
- A Traceable Unified Address is somewhat longer than a TEX address, although
not excessively so.
References
==========
.. [#BCP14] `Information on BCP 14 — "RFC 2119: Key words for use in RFCs to Indicate Requirement Levels" and "RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words" <https://www.rfc-editor.org/info/bcp14>`_
.. [#binance-delisting] `Zcash Community Forum thread "Important: Potential Binance Delisting" <https://forum.zcashcommunity.com/t/important-potential-binance-delisting/45954>`_
.. [#hanh-profile] `Zcash Community Forum user @hanh <https://forum.zcashcommunity.com/u/hanh/summary>`_
.. [#hanh-suggestion] `Ywallet developer @hanh's proposal <https://forum.zcashcommunity.com/t/important-potential-binance-delisting/45954/112>`_
.. [#zip-0316-terminology] `ZIP 316: Unified Addresses and Unified Viewing Keys — Terminology <zip-0316#terminology>`_
.. [#zip-0316-unified-addresses] `ZIP 316: Unified Addresses and Unified Viewing Keys — Encoding of Unified Addresses <zip-0316#encoding-of-unified-addresses>`_
.. [#zip-0316-revision-1] `ZIP 316: Unified Addresses and Unified Viewing Keys — Revision 1 <https://github.com/zcash/zips/pull/765>`_
.. [#zip-0316-unified-requirements] `ZIP 316: Unified Addresses and Unified Viewing Keys — Requirements for both Unified Addresses and Unified Viewing Keys <zip-0316#requirements-for-both-unified-addresses-and-unified-viewing-keys>`_
.. [#zip-0316-address-expiry] `ZIP 316: Unified Addresses and Unified Viewing Keys — Address Expiration Metadata <zip-0316#address-expiration-metadata>`_
.. [#zip-0316-metadata-items] `ZIP 316: Unified Addresses and Unified Viewing Keys — Metadata Items <zip-0316#metadata-items>`_
.. [#protocol-networks] `Zcash Protocol Specification, Version 2023.4.0. Section 3.12: Mainnet and Testnet <protocol/protocol.pdf#networks>`_
.. [#protocol-transparentaddrencoding] `Zcash Protocol Specification, Version 2023.4.0. Section 5.6.1.1 Transparent Addresses <protocol/protocol.pdf#transparentaddrencoding>`_
.. [#binance-address-expiry] `Zcash Community Forum post describing motivations for address expiry <https://forum.zcashcommunity.com/t/unified-address-expiration/46564/6>`_
.. [#Base58Check] `Base58Check encoding — Bitcoin Wiki <https://en.bitcoin.it/wiki/Base58Check_encoding>`_
.. [#F4Jumble] `ZIP 316: Unified Addresses and Unified Viewing Keys — Jumbling <zip-0316#jumbling>`_
.. [#bip-0350] `BIP 350: Bech32m format for v1+ witness addresses <https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki>`_
.. [#zcash_address_wasm] `zcash_address_wasm: Proof-of-concept library for Traceable Unified Address Encoding <https://github.com/nuttycom/zcash_address_wasm>`_