diff --git a/zip-0320.html b/zip-0320.html index 6087999bf..e6c2e6bf0 100644 --- a/zip-0320.html +++ b/zip-0320.html @@ -3,6 +3,7 @@
The key words "MUST", "SHOULD", and "MAY" in this document are to be interpreted as described in BCP 14 1 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 5.
+The terms "Testnet" and "Mainnet" are to be interpreted as described in section 3.12 of the Zcash Protocol Specification 9.
+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.
+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 2.
+In the course of that discussion thread, wallet developer and community member @hanh 3 suggested a wallet-oriented approach 4 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.
+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.
+This alternative was suggested by @hanh in 4.
+A TEX Address is a Bech32m 14 reencoding of a transparent Zcash P2PKH address 10.
+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.
+A TEX address is produced from a Mainnet Zcash P2PKH Address by executing the following steps:
+"tex"
.For Testnet addresses, the required lead bytes of a P2PKH address in step 2 are
+ \([\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.
+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)+
A Traceable Unified Address is a reencoding of a transparent Zcash P2PKH address into a Unified Address 6.
+Traceable Unified Addresses fit into the existing Zcash Unified Address ecosystem. Existing Consumers that support Unified Addresses will automatically be able to recognize a Traceable Unified Address as a valid Zcash address, but will not be able to send to that address unless they update their code to understand the new Receiver Typecode defined in this ZIP. Even in the case that Traceable P2PKH Receivers are not understood by the sending wallet, a Unified Address-supporting wallet will be able to automatically provide good error messages for their users to indicate that the wallet needs to be updated to understand and send to these addresses.
+In addition, 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 8 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 11.
+Upon activation of this ZIP, the section Encoding of Unified Addresses of ZIP 316 6 will be modified to define a new Traceable P2PKH Receiver Type having Typecode + \(\mathtt{0x04}\) + , the value of which MUST be the 20-byte validating key hash of a Zcash P2PKH Address as defined in 10.
+The "Requirements for both Unified Addresses and Unified Viewing Keys" section of ZIP 316 7 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 MUST contain at least one Receiver and any number +of Metadata Items. The selection of Receivers is further restricted +such that a Unified Address MUST **either**: +* contain at least one shielded Receiver (Typecodes :math:`\mathtt{0x02}` and :math:`\mathtt{0x03}`), + and no Traceable P2PKH Receiver (Typecode :math:`\mathtt{0x04}`); **or** +* contain **only** a Traceable P2PKH Receiver (Typecode :math:`\mathtt{0x04}`). + +A Unified Viewing Key MUST contain at least one shielded Item (Typecodes +:math:`\mathtt{0x02}` and :math:`\mathtt{0x03}`).+
A Traceable Unified Address is produced from a Mainnet Zcash P2PKH address by executing the following steps:
+For Testnet addresses, the required lead bytes of a P2PKH address in step 2 are + \([\mathtt{0x1D}, \mathtt{0x25}]\) + .
+The HRP of the resulting Unified Address is the same as for any other Unified Address on the relevant network as specified in 6, i.e. "u"
for Mainnet and "utest"
for Testnet.
Wallets and other Senders sending to a Traceable P2PKH Receiver MUST ensure that only transparent UTXOs are spent in the creation of a transaction.
+Javascript using zcash_address_wasm 15:
+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+
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 don’t 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 wallet’s developer and ask that the wallet be updated.
+1 | +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" | +
---|
2 | +Zcash Community Forum thread "Important: Potential Binance Delisting" | +
---|
3 | +'Zcash Community Forum user @hanh <https://forum.zcashcommunity.com/u/hanh/summary>'_ | +
---|
4 | +'Ywallet developer @hanh's proposal <https://forum.zcashcommunity.com/t/important-potential-binance-delisting/45954/112>'_ | +
---|
5 | +ZIP 316: Unified Addresses and Unified Viewing Keys — Terminology | +
---|
6 | +ZIP 316: Unified Addresses and Unified Viewing Keys — Encoding of Unified Addresses | +
---|
7 | +ZIP 316: Unified Addresses and Unified Viewing Keys — Requirements for both Unified Addresses and Unified Viewing Keys | +
---|
8 | +ZIP 316: Unified Addresses and Unified Viewing Keys — Address Expiration Metadata | +
---|
9 | +Zcash Protocol Specification, Version 2023.4.0. Section 3.12: Mainnet and Testnet | +
---|
10 | +Zcash Protocol Specification, Version 2023.4.0. Section 5.6.1.1 Transparent Addresses | +
---|
11 | +Zcash Community Forum post describing motivations for address expiry | +
---|
12 | +Base58Check encoding — Bitcoin Wiki | +
---|
13 | +ZIP 316: F4Jumble encoding | +
---|
14 | +BIP 350: Bech32m format for v1+ witness addresses | +
---|
15 | +zcash_address_wasm: Proof-of-concept library for Traceable Unified Address Encoding | +
---|