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.