Privatizing Ubiq with Tornado Cash

JP88
The Ubiq Report
Published in
8 min readMar 24, 2020

--

Welcome to this article on privatizing Ubiq, a guide written by members of the community, aimed at helping you through the newly implemented Tornado Cash contract.

What is Ubiq?

Quick primer: Ubiq is an enterprise stable, transparently governed, decentralized EVM platform. This write-up explains it in a lot more detail, and we’d like to keep this article about Tornado Cash.

Can transparency be a problem?

Blockchain projects like Ubiq are known for being entirely transparent ledger systems. And though transparency itself is by no means a problem, as the space evolved, people realized that adding selective privacy can be extremely useful. A few examples are:

  1. Enhancing privacy of your personal finances: One of the biggest advantages is privatizing financial transactions with UBQ.
  2. Private donations/payments: There may be times donations or payments need to be made without identifying the sender.
  3. Private Voting: If voting tokens are issued to certain addresses that are linked to people, those peoples’ votes will naturally be linked to them. This can be a problem when trying to preserve voter privacy.

What is Tornado Cash?

Tornado Cash is a no-fee smart contract running on the Ubiq network. The contract pools UBQ and ERC20 tokens together and privately redistributes them to new wallets by utilizing zk-SNARK technology to privatize them, without linking the “deposit” to the “withdrawal.”

In order to deposit, the client, on the front end, generates a secret key, and sends its hash (with the deposit amount of UBQ or token) to the tornado cash contract. The contract adds the hash to its list, and allows anyone with the secret key to privately withdraw the deposit amount later to a new wallet address without identifying the original sender. This creates a private, non-custodial transaction secured only by cryptography.

Let’s revisit the earlier examples of use cases:

  1. Enhancing privacy of your personal finances: If Alice has an address with UBQ linked to her, and she wants to enhance her privacy, she can send a portion of her funds into the smart contract and withdraw them to a new address.
  2. Private donations/payments: If Alice wants to send money to Bob, but she’d like to do it privately, she can send the money into the tornado contract, encrypt the key to the funds with Bob’s public key, and send it over so only Bob can withdraw the funds.
  3. Private Voting: If Alice, Bob, and Carol are each given 1 token to vote on their favorite candidate, and they don’t want anyone knowing who they voted for, all three of them can send their tokens into the tornado contract, and withdraw them before voting. Even though the tokens were identifiably distributed to each of them, they can now vote with complete privacy.

While this process may seem foolproof, there’s some irony here. In order to withdraw the funds into a new address, you’d technically need an address with some UBQ already in it for the gas to initiate the withdrawal. If the UBQ in this new address for gas is not private, the withdrawal won’t be either. This problem is solved by a “relayer.” Someone else will foot the bill for gas, but then take that amount out of the withdrawal before relaying to the destination wallet.

A few other things to keep in mind:

  1. 1 deposit always maps to 1 withdrawal. If 84.3482 UBQ are deposited into Tornado and withdrawn later, 84.3482 UBQ will be withdrawn at once. Even though the original sender won’t be “known,” not many people will be depositing that exact amount into the contract, so it wouldn’t be difficult to match the withdrawal amount to the deposit amount and derive the original sender’s address. This is why specific deposit amounts are predetermined and recommended for everyone to use. It’s better for everyone to deposit exactly 8, 88, or 888 UBQ so the pools for each amount (anonymity set) are fuller and therefore more private and harder to trace back.
  2. The more people using Tornado, the more privacy each individual person has. That being said, we would strongly encourage anyone reading to follow along in the mainnet tutorial.
  3. The note is the cryptographic proof of ownership to the UBQ held in deposit. If it’s lost, the deposit is lost. There’s no expiration or refund, it’s stuck in the contract.

Using Tornado Cash

Now that we have a good grasp of tornado cash and its uses, let’s go through a couple demos. Before we use tornado on the mainnet with real UBQ, we’ll go through steps for running it on a local Ganache chain. As mentioned above, the more people interacting with Tornado, the more privacy each account has, so I encourage anyone reading to follow along.

Prerequisites: You’ll need gubiq, git, and node & npm installed and runnable in a terminal.

Ganache Demo

  1. Pull down the tornado core project and navigate into it through the terminal. Type the following into the terminal:
git clone https://github.com/ubiq/tornado-core.git
cd tornado-core

2. Install npx with the following command (if its already installed it’ll throw an error you can ignore):

npm install -g npx

3. Download and install all the projects dependencies outlined in the package.json file with:

npm install

4. Set the env configuration. We’ll keep the default env for this demo, so we’ll need to copy it as the actual env the script will use, then build the project (the build will take a while).

cp .env.example .env
npm run build

5. Once that’s finished, we’ll set up our own private ganache blockchain locally. If you want to learn more about ganache and its purpose, you can read more here. But tl;dr, it’s a local version of the blockchain running only on your computer. As it loads, you’ll see ten dummy accounts and their private keys already loaded with ether. We’ll use two of them for this demo.

npx ganache-cli

6. Prepare and deploy the tornado contracts to our local private ganache chain. In a new terminal, navigate to the tornado-core directory again

cd tornado-core

and deploy with

npm run migrate:dev

7. Finally we’ll deposit and withdraw. To deposit, we simply run:

./cli.js deposit

This will send 8 fake ETH to the deployed tornado contract. By default, it will use the first account in the chain to deposit, and the amount will be defined in the .env file we copied earlier. Let’s copy and paste that first account to check its balance.

./cli.js balance <first address in ganache>

We should see a little more that 8 ETH gone for the amount and gas. The deposit command should have returned a ‘note.’ This is the secret, the key to withdrawing the funds. To withdraw, let’s run the withdrawal to the second address in ganache then check the balance.

./cli.js withdraw <NOTE> <NEW_ACCOUNT_ADDRESS>
./cli.js balance <NEW_ACCOUNT_ADDRESS>

While this was a simple example, it demonstrates the power of selective privacy in an otherwise public system. The mainnet process is similar, but a little more involved. Let’s go into it now. For the mainnet steps, you’ll need a Ubiq node running on your computer with either gubiq or fusion. Once that’s up, running, and synced, follow these steps.

MainNet Demo

  1. This time, pull down the official tornado ubiq cli from Octano Labs’ github, cd into it, and install dependencies by running the following in your terminal:
git clone https://github.com/octanolabs/tornado-cli.git
cd tornado-cli
npm install

2. Next, you’ll need to run gubiq with an rpc flag so that the tornado cli can access it, and the --unlock flag followed by your first address to unlock your wallet. Open a new terminal and list your accounts, then unlock the first one:

gubiq --unlock <YOUR_ACCOUNT_ADDRESS> --rpc

When prompted for a passphrase, enter it. Once you do, you’ll be running a gubiq node with your main account unlocked ready to send funds to the tornado cash contract. The --rpc flag creates a gateway into the chain with http calls.

3. Finally, we’ll run a deposit and withdrawal. There are a few differences in the args to add more flexibility like selecting the address you’d like to use for the deposit. In the first terminal window, in tornado-cli/, run:

./tornado.js --deposit --from <FROM_ADDRESS> --pool 1

Note: The <FROM_ADDRESS> must be the one you unlocked in step 2, and the mainnet deposit/withdrawal may take longer than Ganache because it’s waiting for inclusion in the next block on the mainnet. The last argument,

--pool 1

specifies which tornado cash pool on the Ubiq network the deposit is being made to.

4. If all went smoothly, you should see a “note” returned. Again, this note is the key to the 8 UBQ you just deposited into the contract. Now, to withdraw it, run:

./tornado.js --withdraw <NOTE> --to <RECIPIENT_ADDRESS>

Note: There is one additional argument for withdrawal:

--relay <RELAY_URL>

for using a relayer as mentioned above. For now, we will initiate the withdrawal with the same address we deposited with.

You’ve successfully run the tornado contract on the Ubiq mainnet! One thing worth noting is that the withdrawal was initiated with the first address that deposited funds. As mentioned above, this problem is solved by relayers, and as the ecosystem evolves, so too will ways to better enhance privacy. A solution to this in the meantime is to mine UBQ to a new private address and initiate the withdrawal from there.

Fungibility weeks

As has been mentioned above, the more people interacting with the contract, the better it is for everyone. To help with this, the Ubiq community will have regular “fungibility weeks,” weeks where everyone floods the contract with deposits to increase privacy for everyone.

Conclusion

For help/updates on Ubiq’s tornado implementation, the fungibility weeks, or if you’d like to learn more and chat with core devs or other members of the community, drop by the Ubiq Discord server. We’re looking forward to meeting you.

Thanks for checking in and be sure to follow the blog, Twitter, Github and join Ubiq Discord to help collaborate with the best community on the internet.

Ubiq Discord: https://discord.gg/XaqzJB4
Medium blog: https://blog.ubiqsmart.com
Twitter: https://twitter.com/ubiqsmart
Twitter: https://twitter.com/CryptoUbiq (Ubiq Community)
GitHub: https://github.com/ubiq
Website: http://ubiqsmart.com

--

--