Unified Addresses & Full-node RPC API

Подскажите, есть ли где-нибудь примеры использования адресов нового формата Unified Addresses в полной годе (не в лёгких кошельках) посредством RPC-вызовов? Т.е. как посмотреть баланс, как забекапить/импортировать приватный ключ, как с такого адреса отправить монеты и так далее?
Со старыми адресами было понятно: вот приватный ключ, вот t-адрес, вот z-адрес, так можно извлечь приватный ключ, так импортировать, так отправить. А с новыми адресами как это всё делать?

1 Like

In the zcashd full node wallet, we expose Unified Addresses via “accounts”. An account corresponds to the set of spending keys that can spend the funds received by a Unified Address. Every account has a single Unified Full Viewing Key (1-to-1 mapping), and can also have multiple Unified Addresses (via the “diversified addresses” feature we introduced in Sapling and kept in Orchard).

  • You create a new account with z_getnewaccount, which gives you the account number ACCOUNT (0 for the first account).
  • You then generate a Unified Address ADDRESS with z_getaddressforaccount ACCOUNT. Calling this multiple times will return sequential Unified Addresses.
  • Check balance with z_getbalanceforaccount ACCOUNT.
  • Send funds from the account by using z_sendmany ADDRESS ...
    • That is, if you specify any address from an account as the source of funds, z_sendmany will select funds from the whole account. There isn’t a perfect match between old-style addresses and accounts; we’re planning a new account-focused spending API.
  • Backup using z_exportwallet which exports the wallet’s mnemonic phrase, from which all accounts are derived. The new zcashd-wallet-tool can also be used (and in fact you are prompted to use it IIRC).
  • We don’t support importing keys for Unified Addresses or accounts. We are planning to add some way to initialize a wallet from an existing mnemonic (the full node UX of the zcashd wallet makes this rather hard).
8 Likes

This is amazing @str4d! A new era has launched!

To summarise above, I easily set up a test UA wallet like this:

Step 1 (create account):

zcash-cli z_getnewaccount

Step 2 (create address):

zcash-cli z_getaddressforaccount 0 '["orchard"]' 1

In my case, I want to guarantee that no one can even send me a ‘shielding’ Tx - which publicly leaks sender and amount - by sending me ZEC from a pesky taddr, or to leak other data when sending from a UA but with a specified privacyPolicy string that isn’t “FullPrivacy”.

(I need to test this. Hopefully also would block situations like from a Sapling Z-address to my Orchard U-address, which would undesirably force the amount to be revealed.)

The mere possibility of receiving exposed amounts/senders/recipients, out of your control, is not acceptable if you want full privacy in all directions. It seems UA could fully block it by specifying “orchard”.

This spat out a brand new U-address:

u19r2vknhmuk2v4nc6vgyja27kguvqeuv2er6qlfgc85lqx9d5dqh44z2u5fdmyj6sqghs8eehu7pdvlf7a639nr5h7tvt2v7sy50j44v7

(I don’t mind sharing this one in public, it’s just for testing.)

Then I did:

zcash-cli z_getbalanceforaccount 0

It looks like if I put funds in there it would show relevant funds data. Anyone want to send me dust just to try doing a U-to-U or Orchard pool Z-to-U?

I assume one can do like this:

zcash-cli z_sendmany "YOUR_SENDER_ORCHARD-ONLY_ZADDR_OR_UADDR" '[{"address": "u19r2vknhmuk2v4nc6vgyja27kguvqeuv2er6qlfgc85lqx9d5dqh44z2u5fdmyj6sqghs8eehu7pdvlf7a639nr5h7tvt2v7sy50j44v7", "amount": 0.00002}]'

This tech is so far ahead of Monero, since it’s now with default privacy. U-address is the gold standard going forward! (No it’s not, clarified in post(s) below, doesn’t guarantee default privacy.)

Now all we need is:

  1. Make UA - and the default privacy like in CLI - be default in every major GUI ZEC wallet offering.

  2. Big marketing and community lobbying to get vendors, platforms and sites to add support for UA. E.g. coin swapper sites to add support for UA strings in their webforms (most of whom only support taddr - indeed two types of addresses was too complicated for adoption).


Some questions on this @str4d:

  • If someone attempts to send ZEC from a taddr to my Orchard-only uaddr, what will happen? Their official client software just blocks it pre-broadcast? What about ‘evil’ custom third party software that will try to broadcast it, does the cryptography running in majority of nodes simply not have ability to verify and thus process the attempted transaction? Hopefully yes, also to prevent accidental burning of ZEC during this transition era.

  • I will test, but may as well ask: if a UA sender uses any custom privacyPolicy string such as "AllowRevealedAmounts", "AllowRevealedSenders", or "NoPrivacy", can that somehow bypass the fully shielded policy of my “orchard” only U-address?

  • OPSEC question: diversifier_index: is there a difference in public U-address encoding between between specifying nothing vs. a value like 1? We need to not stand out from other metadata patterns used by other people.


Final questions, for wide-scale UA adoption:

  • Is it too early for us to ask vendors to set up a UA address and move to UA? (Are GUI wallets not all there yet?)

  • Is UA fully backwards compatible so I can tell them they have nothing to lose by moving to UA already?

Thanks for the amazing work!

2 Likes

If the sender’s wallet doesn’t support Orchard recipients then they won’t be able to create a transaction. If it does, the send will work.

Unified Addresses enable recipients to specify their preference for how they want to receive funds, but the sender is always the final arbiter of what goes into a transaction, being the one creating it. A UA that contains multiple receivers is indicating that it is okay for the sender to choose any of the receivers (since it is impossible to distinguish between a sender whose wallet cannot send to a more preferred recipient type that may be unknown to them, and one lying about not being able to do so). Providing an Orchard-only UA requires that the sender creates an Orchard output for you (you are preventing them creating a transparent or Sapling output instead), but places no obligation on where their funds come from.

The privacy policy field that we added to z_sendmany is to help the sender control what they reveal in the transactions they create (with a default of FullPrivacy if UAs are involved, so the sender needs to make an explicit choice). From the perspective of a receiver with an Orchard-only UA, they can receive transactions under sender-chosen FullPrivacy, AllowRevealedAmounts, and AllowRevealedSenders policies. (They can also receive transactions under weaker sender policies like AllowRevealedRecipients, but those can only reveal information about other recipients, not the Orchard-only UA recipient.)

The reason that diversifier indices exist is precisely for this reason. Sapling and Orchard receivers contain diversifiers that are visible to whoever has the address, and we desired a security property where two diversified addresses can’t be linked solely from the addresses alone. If diversifiers were picked sequentially then that would provide a pretty strong heuristic for linking addresses to the same account. Instead, we use Format-Preserving Encryption (specifically the FF1 algorithm) to map sequential diversifier indices to pseudorandom diversifiers.

Long story short: you can pick diversifier indices that are meaningful to you however you want, and they will only be visible to someone who can obtain a viewing key for the corresponding account. One use case we imagined is having diversifier indices map to client numbers, for a business that wants to give out unique addresses to each client (and therefore be able to determine which client paid them based on which diversified address the payment was received on) while still having a single account of funds to manage.

UAs are just an address encoding mechanism, and internally support both transparent and Sapling receivers. So if a vendor currently supports Zcash (transparent and/or Sapling) then they can absolutely start accepting UAs from customers (from which they can extract the receivers they are able to work with, if any), and generating UAs to give to customers (this is where customer wallets would need to know how to parse UAs in order to send funds to them, but any transparent or Sapling receiver inside a UA can be extracted and encoded in its legacy format for compatibility).

3 Likes

OK, seems it doesn’t make a difference publicly, so I’ll just opt to specify nothing in my case.

OK, it’s early days but I will start to encourage entities to move to UA and thus get rid of the taddr pestilence.

(My emphasis added.)

This is disappointing - false alarm - I thought UA would finally enable you to block incoming T-to-U transactions, but I was wrong, thanks for clarifying. Because of this, I don’t consider it meaningful to check exactly what’s exposed by AllowRevealedAmounts and AllowRevealedSenders (a feature introduced since 4.7.0) when a Tx is sent to an Orchard-only UA from various kinds of sender addresses, because there is no wider privacy guarantee breakthrough anyway - we still can’t escape the entire category of ‘shielding’ transactions.

Default privacy settings are a huge deal - so UA UX is very welcome. But unless it’s guaranteed privacy both ways, I fear wide adoption will be stunted. Time will tell if new wallet defaults will change the optics to make Zcash be taken more seriously as a privacy coin (as it should be, since it’s the best). Monero’s success - despite having woefully inadequate privacy coin tech - teaches us that it’s not about the truth* so much as the idea, the intent - optics, branding, mythology. Monero is a full-blown religion. Its ideological fervour - its rampant hope to be private, no matter what, no questions asked (irrespective of whether it is private or not) - is what this project lacks. (No wonder ZEC has been forked to remove the transparent part.)

If Zcash wants more adoption, and to even bill itself as a privacy coin, this concession to bow to certain regulatory entities is the thorn in its side. The inability to block incoming transparent inputs is a lingering loophole that actually feels like a pro-regulatory backdoor, as if designed to say: “It’s OK, law enforcement, our users aren’t uncontrollably private - you can still catch a criminal by sending them shielding transactions or via AllowRevealedSenders / AllowRevealedAmounts - they might not even notice!”

(Zcash really needs to become jurisdictionally and politically independent, as @zooko has been recently expressing. 100% agree with that.)

Monero’s own privacy policy isn’t 100% perfect, but at least it doesn’t have the major loopholes Zcash has. By design, Zcash is still only a privacy-possible coin (now becoming a privacy-default coin), not a privacy-only coin. People don’t want to TOUCH the transparent.

The competition is strong. The best doesn’t always win. The one with the most appeal does.

(*) The truth: Many fingerprinting attacks are possible from senders, from ‘dust’ to other imaginative ideas such as custom Tx fees right down to the Zatoshi that contain a quasi UUID or even steganographic watermark, and more. (Also, a malicious sender can leak all details of the trade to any other party off-chain.) This is why, since the beginning, I have discovered the under-appreciated necessity of privately churning your ZEC ONE TIME, within the fully shielded pool, where you fully control BOTH sender and recipient policy. It guarantees cleaning of any possible on-chain fingerprinting metadata engineered by a malicious sender, like dust. It’s not superstition or OCD. Churning ZEC creates a truly trustless black hole and achieves what sovereign cash is supposed to be. No amount of trustless design, in either Monero or Zcashm can guarantee against crafty senders, so extra OPSEC steps and vigilance is needed. Is this the point of this post’s rant, though? No.

Privacy question about UA’s here:

If you create a full UA and display it in a blockchain explorer, it breaks it down into 3 separate addresses: 1 UA, 1 Zaddy, 1 Taddy.

Any privacy recommendations regarding which of these addresses to display / use ? If you post 1 address, can the others be discovered? Is displaying your full UA ok or since its linked to a Taddy is that not optimal :student: ?

Technically you aren’t supposed to give out any of the unified receivers because of privacy risks but umm… yes that’s correct anyone can derive ALL of the specific receivers from a given UA on zcashblockexplorer. I don’t think this was intended (and if so then I’m pretty confused)
@str4d

A Unified Address is effectively just a map from a receiver type to a receiver. Anyone who is given a UA can read this map to determine the receivers it contains; this is intended behaviour, because it’s what enables a user to allow senders to send them funds to one or more pools.

What I presume zcashblockexplorer is doing is using zcash-cli z_listunifiedreceivers (which is intended for this purpose). If a UA breaks down into 3 addresses, that means the UA contained 3 receivers. Note that for Orchard there is no separately-defined encoding, so to show the Orchard component of a UA, we render an Orchard-only UA.

If you give a multi-receiver UA to someone, the internal receivers can obviously be linked. If you give out a single component receiver of a UA, then it can’t directly be linked to the other receivers unless the UA itself is also known.

If you have two UAs from the same account, then on their own they cannot be linked. However, if both UAs contain transparent receivers, and the wallet is not careful when transparent funds are shielded, the transparent receivers can be linked on chain, and therefore the UAs can be linked. This can be avoided by wallets not spending transparent funds from different transparent receivers in the same transaction. You can also choose to generate UAs that don’t contain transparent receivers, if you don’t need interoperability with transparent-only services; in that case, on-chain data can’t link two UAs together.

Note that this only considers on-chain linkability; obviously if two people are given separate UAs, they can compare notes to figure out if they were given their respective UAs by the same person.

2 Likes

I know I could do that with my own addresses and I guess I should have assumed I could have done it with any of them but I was confused about the actual reasoning why you shouldn’t pass along the receivers.
But UA of a single component isn’t immediately discernible by a human as having only one component or what it is. A UI tool could make that easier by showing you immediately (else the explorer or RPC) but by themselves one would have to memorize the random alpha-numeric prefix so that I give them the right one.

1 Like

I’m curious as to why you would like to send an Orchard only UA?

Say in the future there’s a light wallet implementation that’s highly efficient for Orchard but not for other shielded pools? Also, if someone who would like to use shielded Zcash but trust only the Orchard pool. A niche, but definitely feasible scenario for some Zcash users.

1 Like

I’d still give the multi-receiver UA and let the wallet implementation decide. It should know which receiver to use better than the user.

Both the single sapling or orchard component UA and an orchard addy itself begin with ‘u1’ and both would be the exact same length since it is just one component I think.

I think the mode selection might lend itself nicely here, like beginner, advanced and maybe like professional (or maybe just advanced) where the underlying receivers of the given account are exposed like normal in the wallet but that the 6 (right?) possible UA’s for those given addresses are a feature and that it’s more clearly understood “this one for that one, this one for those two, that one for the three etc.” and that the wallet will decide based on the preferred method.

In general, splitting an existing UA into fewer-receiver UAs is not necessary or desirable, not least because the existing UA has likely already been given to someone (if a UA with a specific set of receivers was desired, it should be generated that way). The main reason to have UX for extracting some receivers is for legacy compatibility with senders that understand either Sapling or transparent address encodings. Any sender that understands a UA encoding should just be given the full UA (containing whichever receivers the user wants to allow funds to be sent to).

2 Likes

Thanks @str4d , great information here. And as talked about in discord, you can tell the difference between receivers by how long they are:

Screenshot_2022-10-03_19-56-05