Integrating Zcash Shielded Transactions on SideShift AI

Andreas Brekken
Jan 30 · 4 min read

Zcash has two types of addresses/payments. A transparent, t-address, is just like a Bitcoin address and uses the same commands as the Bitcoin Core API I’m used to. A shielded address, often referred to as a z-address conceals the sender, recipient, and amount of transactions. Using z-addresses appears to require a new set of commands prefixed with z_, such as z_getnewaddress.

SideShift AI already has support for shifting to and from t-addresses which uses the exact same code as used for Bitcoin, Litecoin, and more.

Detecting deposits

For detecting incoming deposits, we won’t be able to look through every transaction in every block and see if it’s to us. The privacy technology makes this impossible. I notice a couple of commands that can be helpful:

  • z_listreceivedbyaddress: We could assign a new z-address to every SideShift AI order and poll z_listreceivedbyaddress to see if it has returns a transaction previously not processed. This could become a performance issue if the number of addresses is large, but I’m fine with it.
  • z_listunspent: This command will list all the funds we’ve received that aren’t spent. We could poll this command to notice new transactions.

I’ll try z_listunspent first and see if I can make it work. But first I’ll need to let users choose it as a deposit option:

Most of the code from t-addresses can be re-used and I can add z-address as a deposit option quite quickly.

I usually test by changing to a coin with very low on-chain fees for sending and low confirmation times, such as Litecoin.

The order details page also renders fine.

I have a balance in ZEC, but it’s held in a t-address. Can I send from a t-address to a z-address? I’ll try to find out.

Nope, that doesn’t work. Maybe there’s a different command for this.

It seems there’s only z_sendmany:

It interestingly specifies the from-address. This can become useful when implementing withdrawals later. I use listunspent to see which addresses have funds in them:

z_commands are async, probably because they can be slow due to the advanced cryptography used. I check the progress:

The transaction was sent! I check z_getbalance for unconfirmed funds:

I wait for a confirmation and see what z_listunspent returns:

I’ll make some code that polls z_listunspent:

Only 60 lines. I try to run it:

I’ll try another just to be sure.

And wait for 10 confirmations.

The deposit was credited and the shift to LTC completed. Next I’ll look at handing shifts to z-addresses.

Sending settlements

By polling z_listunspent to detect deposits we have a problem when settling by sending outgoing z-address transactions. We could create a race condition where:

  • Alice starts a shift from z-addr to BTC
  • Bob starts a shift from BTC to the z-addr
  • Alice sends in 10 ZEC to the z-addr
  • Alice sends in 2.5 ZEC to the z-addr
  • Bob sends in 0.1 BTC to the Bitcoin address
  • SideShift AI detects and credits the 10 ZEC from Alice
  • SideShift AI detects and credits the 0.1 BTC from Bob
  • SideShift sends out 7 ZEC as settlement to Bob, which spends both the 2.5 ZEC and the 10 ZEC from Alice with a change output of 5.5 ZEC
  • SideShift polls z_listunspent but does not see the 2.5 ZEC from Alice, because it was already spent to settle for Bob

The command we’ll be using to send funds is z_sendmany. It looks like this:

We can supply a fromaddress! This means we can choose a single address and always send from that one. Sure, we might end up spending some extra money on fees when consolidating, but that’s acceptable.

I make a new z-address that’ll serve as the hot wallet.

Let’s try coding this up:

And give it a shot:

It settles in an acceptable time, in just under a minute:

Closing remarks

There are probably a thousand more clever ways of doing this, but at SideShift AI the focus is to get product out the door fast and then iterate.

I haven’t even checked that the amounts and fees are done exactly correct yet, which our dear TEST PILOTS will assist with.

Ready to become a TEST PILOT? See https://sideshift.ai/pilot

SideShift AI

Development updates from SideShift AI

Andreas Brekken

Written by

SideShift AI

Development updates from SideShift AI