ZIP: 320 Title: Defining an Address Type to which funds can only be sent from Transparent Addresses Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co> Kris Nuttycombe <kris@nutty.land> Credits: Hanh Status: Proposed Category: Standards / Wallet Created: 2024-01-12 License: MIT Discussions-To: <https://github.com/zcash/zips/issues/757> <https://github.com/zcash/zips/issues/795> Pull-Request: <https://github.com/zcash/zips/pull/760> <https://github.com/zcash/zips/pull/766> <https://github.com/zcash/zips/pull/798>
The key words "MUST", "SHOULD", "NOT RECOMMENDED", 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", "Address", and "Unified Address" are to be interpreted as described in ZIP 316 7.
The terms "Testnet" and "Mainnet" are to be interpreted as described in section 3.12 of the Zcash Protocol Specification 10.
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.
In November 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. This ZIP formalizes that proposal.
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 one of the source addresses. 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.
It is not expected that other exchanges or Producers of Zcash addresses will generate Transparent-Source-Only Addresses unless they have a specific need to be able to identify the address or addresses from which a payment was funded. However, all Consumers of Zcash addresses should implement this specification, in order to promote interoperability across the Zcash ecosystem.
A TEX Address, also called a Transparent-Source-Only Address, is a Bech32m 15 reencoding of a transparent Zcash P2PKH address 11.
Wallets and other Senders sending to a TEX address (as any output) MUST ensure that only transparent (P2SH or P2PKH) UTXOs are spent in the creation of the transaction. For simplicity of parsing and interpreting such transactions, they also SHOULD only send to transparent outputs.
A TEX address can be 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.
A TEX address can be parsed by reversing this encoding, i.e.:
"tex"
for a Mainnet TEX Address and "textest"
for a Testnet TEX Address.For a transaction that spends only from transparent funds to a TEX Address, this specification imposes no additional requirements.
If, on the other hand, a user desires to spend shielded funds to a TEX Address, a Sender supporting this ZIP MUST create two transactions: one that unshields the funds to an ephemeral transparent address, and one that spends from that ephemeral address to the destination TEX Address. This does not defeat the intent of the ZIP, because it is still possible for a Recipient to return the funds to the Sender by sending them back to the ephemeral address.
Wallets MUST be able to recognize funds that have been returned in this way and spend them if desired. In order for this to be possible without use of TEX Addresses increasing the risk of loss of funds, wallets based on ZIP 32 5 SHOULD choose ephemeral addresses in a way that allows the corresponding private keys to be recovered from a ZIP 32 master seed.
However, ephemeral addresses SHOULD NOT be chosen in a way that allows them to be linked between transactions, without knowledge of the wallet seed or the relevant transparent viewing keys. This also implies that they SHOULD be chosen in a way that avoids collisions with addresses for previously generated outputs (including change outputs), such as might have been created by a transparent-only wallet using Bitcoin-derived code based on BIP 44 14.
In order to show accurate transaction history to a user, wallets SHOULD remember when a particular transaction output was sent to a TEX Address, so that they can show that form rather than its P2PKH form. It is acceptable that this information may be lost on recovery from seed.
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)
TEX addresses are the simplest possible approach to creating a new address type that indicates that only transparent sources of funds should be used.
As required by Binance, it will be possible to convert between a TEX address and an unrestricted transparent P2PKH address using extremely straightforward code that depends only on Base58Check and Bech32m encoding/decoding, as shown in the above Reference Implementation.
An earlier version of this ZIP also described another alternative using metadata in Unified Addresses, as specified in ZIP 316 6. That alternative was designed to enable better integration with the Zcash Unified Address ecosystem, and had the advantage of being able to combine different types of metadata along with the Transparent-Source-Only indicator, such as an expiration block height or time 9 12.
However, ultimately the Unified Address-based approach did not meet all of the requirements, since it would in practice have required dependencies on address handling libraries that Binance did not want to depend on in their front-end code.
Some design elements of that approach that apply to metadata in general have been incorporated into ZIP 316 Revision 1 8. A more general form of Source Restriction Metadata is also under consideration.
A disadvantage of TEX Addresses (and also of the alternative approach using Unified Addresses) is that the information that a TEX Address was used does not appear on-chain, i.e. a transaction sending to a TEX Address is indistinguishable from one sending to the underlying P2PKH address. This is inevitable given the desire not to change the underlying consensus protocol to support this functionality.
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 |
---|
4 | Ywallet developer @hanh's proposal |
---|
5 | ZIP 32: Shielded Hierarchical Deterministic Wallets |
---|
6 | ZIP 316: Unified Addresses and Unified Viewing Keys |
---|
7 | ZIP 316: Unified Addresses and Unified Viewing Keys — Terminology |
---|
8 | ZIP 316: Unified Addresses and Unified Viewing Keys — Revision 1 |
---|
9 | ZIP 316: Unified Addresses and Unified Viewing Keys — Address Expiration Metadata |
---|
10 | Zcash Protocol Specification, Version 2023.4.0. Section 3.12: Mainnet and Testnet |
---|
11 | Zcash Protocol Specification, Version 2023.4.0. Section 5.6.1.1 Transparent Addresses |
---|
12 | Zcash Community Forum post describing motivations for address expiry |
---|
13 | Base58Check encoding — Bitcoin Wiki |
---|
14 | BIP 44: Multi-Account Hierarchy for Deterministic Wallets |
---|
15 | BIP 350: Bech32m format for v1+ witness addresses |
---|