“Transparent” refers specifically to the fact that the on-chain value associated with a TZE-encumbered output is public, in the same way that the value in a coin sent to a t-address (which is a P2PKH or P2SH Bitcoin script encumbrance) is public.
There is nothing that prevents a specific extension from being implemented internally using ZKPs - Bolt, for example, uses ZKPs to provide privacy for its off-chain aspects. There is also nothing that prevents an extension from making assertions about existing Zcash shielded pools, including proofs that reference mined shielded notes via the commitment tree, or requiring that a transaction containing a specific TZE output also contain a shielded output with some properties. All of this can be implemented by interacting with the Zcash chain through an extension-defined Context
(as long as it’s reasonably efficient for a full node to provide the necessary context).
You could even implement an entirely new shielded pool as a TZE, by having the public value encumbered by the TZE correspond to the total value inside the new shielded pool. This amounts to running a shielded pool in a sidechain, where you lock up / release main-chain ZEC in the TZE output, and mint / burn corresponding side-chain ZEC. On-chain updates to the new shielded pool’s state would be implemented as spends from one TZE output to another; these updates would be created by the entities that control the sidechain (either a single controller, or a group of them creating the necessary state update proofs via an MPC). If you squint a bit, a Bolt state channel is basically this, where the only two entities using a particular “shielded pool” are the merchant and customer.
However, there are things that you can’t do with TZEs, due to their base-layer use of transparent value. For example:
- You can’t create a new shielded pool that can be used globally with no user coordination (beyond agreeing on what the Zcash chain is). The side-chain example above requires users to coordinate on the side-chain, and to trust the entities making the side-chain state updates.
- You can’t send funds between different TZEs (or from an existing global shielded value pool like Sapling into a TZE) without revealing the value being sent between them.
- TZEs that have internal anonymity sets can’t share those anonymity sets with each other (it’s always obvious on-chain which TZE is being used in a given transaction).
These use cases require some form of shielded programmability, where there is a base “execution framework” with shielded values, upon which almost-arbitrary shielded encumbrances could be built. This is what a future Shielded Zcash Extensions framework would provide. I believe that the pathway from TZEs to SZEs should be relatively straightforward (though no small amount of engineering effort), once we have an understanding of the kinds of protocols users want to deploy, and how flexible the shielded programmability model would need to be.