EY’s Nightfall Hands On — Our Initial Installation and Testing Experience

Private transactions over the public Ethereum blockchain — this is the promise of the EY Nightfall project.

I recently installed the Nightfall demo and took it for a test drive, so I’ll share my initial experience in this article. I won’t get into the technical details regarding how Nightfall actually works, but if you are interested you can read the whitepaper here.


First, why is Nightfall needed?

For enterprises, EY’s Paul Brody explains the enormous value proposition Nightfall unlocks in his article here. I’ll go over some of the key points.

Public blockchains are currently unusable by enterprises. They are completely transparent by their very nature. If a company wants to exchange currency for a product on a public blockchain, the whole world would know what the company bought and the amount spent. Enterprise pricing is competitive and extremely sensitive information, making public blockchains not a viable option for many enterprise use cases.

Private blockchains, on the other hand, give enterprises the privacy they desire, but are only marginally better than using a web portal and database. Someone still has to operate and manage it (ex. one of the companies/entities in a strategic partnership), giving the operator an advantageous market position. In other words, private blockchains are centralized. In many cases, a database is a better solution.

Nightfall gives enterprises the ability to conduct completely private transactions over a public blockchain (Ethereum), which suddenly opens the door for massive enterprise blockchain adoption.

Installing the Nightfall Demo

Now I’ll get into the nitty gritty. I have a Mac, so I’ll give the install experience from the perspective of a Mac user. The only part of the installation where your OS should really matter is during the prerequisite steps, since Nightfall applications/services run in docker containers.

First, you’ll need a fairly powerful machine to run Nightfall. I’m at the very low end of what you’d ideally want to have. Here are my specs for reference:

  • MacBook Pro, 2.2 GHz Intel Core i7 (MacOS Mojave 10.14.4)

  • 16 GB Memory

  • 60 GB hard drive space

Regarding hard drive space above, I went ahead and freed up more than necessary, and it’s a good thing I did. You’ll want at least 20 GB free since the Zero Knowledge Proofs (ZKPs) take up at least 7GB on their own. And in my case, since memory is at a premium with all of the other applications running on my MacBook, I currently have 6–8GB of my HD taken up for swap memory! Not a good situation (and I could probably try Docker Desktop with a lower memory amount).

In any case, you can see the direct storage requirements for Nightfall below (somewhere ~12 GB):

nightfall reqs.png

Overall, the install was a smooth experience and the Nightfall documentation is very good. You’ll want to set aside a few hours, since the generation of the Zero Knowledge Proof keys and constraint files takes a very long time depending on your hardware. In my case, I had to go through the install twice, but I’ll discuss that later (it was my fault… be sure you don’t miss any steps!).

You can find all of the installation steps here.

The first snag I ran into was during the prerequisite steps. I had an older version of Node than required, so I followed the documentation to update it. However, I could not get the following link step to work due to permission issues on my setup:

brew link — overwrite node@10 — force

Not sure if others will run into this, but I’m listing the solution that worked for me since it wasn’t easy to solve (the commands here are specifically for Mac Sierra and higher):

sudo rm -rf /usr/local/include/node/* && sudo rm -rf /usr/local/include/node/* && sudo rm -rf /usr/local/lib/dtrace
sudo chown -R $(whoami) $(brew --prefix)/*

After doing this, the brew link command worked successfully.

The Docker Desktop config I used was as follows. As mentioned above, I’ll probably try lowering the RAM amount since I’ve pushed my MacBook to the limit:

  • 4 CPUs

  • 16MB RAM

  • 512 MiB swap

  • Default subnet (

After starting up Docker Desktop, make sure to start docker-proxy as the first thing you do. This bit me, as I somehow missed this step during the first install. I believe it was the reason I had to start the installation over a second time, as I couldn’t create user accounts even after starting it up later.

docker-proxy start

Next you’ll start the generation of keys and files for ZKPs, which is the longest part of the process (it takes over an hour). The good news is it’s all automated, and the verbose console text is clear and detailed (mostly calcs). If you want to know read more about how ZKPs (and specifically zkSNARKs) work, you’ll find a good technical introduction here. The specific toolbox for zkSNARKs on Ethereum is ZoKrates.

Once this part is done, you are ready to run the demo!

Launching the Nightfall Demo

You can launch the demo from the command line, which launches all containers necessary for Nightfall. The Nightfall smart contracts are launched as part of this step inside a Ganache CLI docker container. NOTE: Nightfall only runs on Ganache CLI at the moment as the project is still in the early stages of identifying and fixing security issues and bugs — the EY team stresses that the project is not production ready and to use at your own risk. The demo script does a nice job of cleaning up any previously running containers that you may have forgotten to stop and remove.

Here’s a snapshot of the running Nightfall containers that start when you launch the demo:

Nightfall Containers

Nightfall Containers

With the demo running, you can go to any web browser and type http://nightfall.docker to start using Nightfall.

You will start with an initial account creation screen, which creates actual accounts on the blockchain and registers the names so that users can easily look each other up later for transfers. In my case, I created two users, Alice and Bob. NOTE: To test two separate users, you must use two completely separate browsers like Chrome and Firefox, or two Chrome browsers with one it incognito mode.

This is Alice’s initial dashboard:

Nightfall Web Dashboard

Nightfall Web Dashboard

The four columns from left to right are: conventional ERC‑721 transactions; hidden ERC‑721 transactions; conventional ERC-20 transactions and hidden ERC‑20 transactions.

The out-of-the-box token contracts used in the demo (specifically FToken.sol and NFTokenMetada.sol) give you EYT and OPS tokens to play with, but you can modify to use your own token contracts. I haven’t tried this yet.

There is good documentation on the nightfall UI here. It summarizes the main functionality as follows:

You cannot use hidden (ZKP) transactions without firstly creating conventional tokens. Note that the terms ‘mint’ and ‘burn’ when applied to hidden transactions have a slightly different meaning: minting a hidden token actually creates a hiding for an existing conventional token and burning it recovers the original token from the hiding.

Given this, I’ll take you through some private transaction test cases I ran on both ERC-20 and ERC-721 tokens.

Testing Nightfall — Private ERC-20 Transactions

Here are the steps I ran to test private transfer of ERC-20 tokens between two users: Alice and Bob:

  1. Alice — Minted 100 ERC-20 tokens using the MINT EY OPSCOIN button in the UI (there is no limit to the amount of tokens you can mint in the demo). These tokens were automatically assigned to Alice’s account. The minting happened instantly, since the Ethereum contracts are running locally on Ganache CLI.

  2. Alice — Minted two OpsCoin commitments (these create the hidden tokens in the shield contract) using the MINT EY OPSCOIN COMMITMENT button. I input values of 10 tokens and 20 tokens for the two OpsCoin commitments. NOTE: The two OpsCoin commitments must total a value equal to or less than token amount minted in step 1. Each commitment took about 20 seconds each to mint. The result was the following:

Two OpsCoin token Commitments (hidden tokens)

Two OpsCoin token Commitments (hidden tokens)

Alice’s dashboard now shows that she has 70 OpsCoin tokens and 30 OpsCoin commitments:

Alice’s dashboard after minting 30 OpsCoin Commitments

Alice’s dashboard after minting 30 OpsCoin Commitments

3. Alice — Performed a private transfer of 12 OpsCoin commitments to Bob using the TRANSFER EY OPSCOIN COMMITMENT button. NOTE: The amount Alice can transfer does not have to be equal to 10 or 20 commitment values. It can be any amount 0 to 30. If the amount is less than 30, then Alice will be given the difference back as change. Also, the current Nightfall implementation requires two commitments in order to perform a transfer. There is no real reason for this, but just how it was implemented, so worst case you can create a second token with a value of 0 for the second commitment.

The transfer of a commitment took about 7 mins on my Mac and is resource intensive. This is because “it has to calculate a proof that it knows a path through the Merkle tree of commitments (actually two paths — one for each coin).” You can watch the actual calculations happening in the console you ran the demo from. You can see the cpu and memory usage of the newly spawned container on the last row below:

“docker stats” command during transfer of commitment

“docker stats” command during transfer of commitment

4. Bob — Received the commitment and Alice got her change back as a commitment. Here’s what Bob’s dashboard looked like after the transfer:

Bob’s Dashboard after receiving 12 OpsCoin Commitments from Alice

Bob’s Dashboard after receiving 12 OpsCoin Commitments from Alice

Here is what Alice’s dashboard looked like after the transfer (notice the CHANGE transaction):

Alice’s dashboard after transfer of 12 OpsCoin Commitments to Bob

Alice’s dashboard after transfer of 12 OpsCoin Commitments to Bob

5. Bob — Burned the commitment. This is the way Bob can access the actual OpsCoin tokens. It is all or nothing, as Bob must burn all 12 OpsCoins in the commitment, not a partial amount. This took about 2 or 3 mins on my Mac. After this Bob’s dashboard shows the following:

Bob’s dashboard after burning 12 OpsCoin Commitment

Bob’s dashboard after burning 12 OpsCoin Commitment

6. Alice — Burned the change commitment to turn change back into original OpsCoin token (she must burn full change amount which is represented as one commitment).

In the end, Alice ended up with 88 OpsCoin tokens and Bob with 12 OpsCoin tokens that could then be used normally again.

Testing Nightfall — Private ERC-721 Transactions

I tested the private transfer of ERC-721 EYTOKENs in the same manner as the ERC-20s. The big difference is that instead of minting and transferring a certain amount of tokens, the URI is used to identify the specific token you want to mint, transfer, or burn. You can enter any text for the URI for demo purposes.

Unique ERC-721 minted representing a song license shown in URI column

Unique ERC-721 minted representing a song license shown in URI column

Here is what the dashboard looks like after turning the regular ERC-721 token into a Commitment. Notice the MINTED and SHIELDED transactions (also notice the URI still in plain view):

Minting a Commitment for an ERC-721

Minting a Commitment for an ERC-721

I will not go into too much detail here, as the remaining transfer and burning functionality is similar to ERC-20.


The one thing I am trying to wrap my head around is how the ERC-721s would remain private. Since ERC-721s are unique NFTs, it shouldn’t be a tough task for a keen observer to determine who transacted with who simply by monitoring owners of the asset over time. However, I suppose if the owners kept the asset only as a commitment, transferring the commitment around, and only burning the commitment when the actual token asset was needed, then it would probably be deemed much less trackable. I will do more reading on this to see if I’m missing anything.

Also, even for the ERC-20s, the white paper warns:

Minting an ERC-20 commitment initially requires Alice to transfer a certain value of ERC-20 tokens to a ‘Shield’ contract (which thereafter holds this value in escrow). This transfer reveals the Ethereum address of the sender (Alice) as well as the value. Therefore everyone will know the owner and the underlying value being represented by the initial ERC-20 commitment which is created at this ‘minting’ stage.


The initial release of Nightfall does not give Alice full anonymity when she interacts with the Shield contract, unless she mines into her anonymous Ethereum accounts.

Future updates will include the functionality to delegate transactions to others. This is a solved problem, which just needs to be implemented.

The last sentence gives promise that even though the first release of Nightfall cannot guarantee anonymity for the sender, there is a solution coming in a future release.

This may even solve the problem with ERC-721 i.e. if only delegate addresses are used for transactions, then attribution to the actual sender would not be possible.

Final Thoughts

Nightfall is showing huge promise. Yes, the costs to perform private transactions at this time seem fairly high and time consuming (compared to regular, non-private Ethereum transactions). However, when compared to what enterprises must do today to transact with other enterprises, suppliers, etc, these costs will be enormous savings in many cases.

In addition, the EY team has already reduced the costs an order of magnitude from what they released at the end of last year, so I believe these improvements will continue. Couple that with the improved speed and lower transaction costs coming with Ethereum 2.0, and this solution becomes compelling for even the lower-value “every day” transactions.

Nightfall whitepaper: https://github.com/EYBlockchain/nightfall/blob/master/doc/whitepaper/nightfall-v1.pdf

Brian Burns