Stephane Gosselin


LibSubmarine: Temporarily hide transactions on ethereum (cheaply!)

The State of Privacy

Privacy is a major challenge for blockchains, Ethereum in particular. There are myriads of use cases which require the ability to transact privately in order to avoid signalling other parties who could take action against the information revealed.

One notable example is on-chain voting. If votes can be publicly tallied before the voting period has ended, new voters are able to use this information in a way which influences their votes.

An elegant solution to this problem called weighted commit-reveal voting solves this problem by allowing a participant to hide their vote until the voting period has ended. This is great, because it means a user can credibly commit to secret data on-chain, which is only revealed at a later date. However, the participating address and weight of the vote are publicly known before the end of the voting period.

So, what if the participant wishes to completely hide their participation in the vote until the voting period is over?

This is where submarine sends come into play.

Hidden Transactions = Submarine Sends

Regular commit-reveal schemes are limited to hiding the data included in the Ethereum transaction. Submarine Sends permit the user to hide the entire transaction until it is revealed in a later block. That is, it is possible to hide the sender, receiver, value and data. Here are a few use cases.

Sealed bid auctions

In a sealed bid auction, it must be possible to credibly commit to a price without revealing it publicly. If the bid is in ETH, it’s impossible to hide the price with normal commit/reveal.

Frontrunning protection

Any DEX is susceptible to frontrunning as a miner can observe transactions in the mempool and place an order ahead of the transaction in a block.

On-chain voting

As mentioned previously, regular commit/reveal cannot hide participation or value of votes.

How Submarine Sends Work

A major challenge with implementing Submarine Sends is gas consumption and UX. @ethlorenz proposed an elegant solution which is both gas efficient and minimizes the number of user generated transactions. The solution requires the interaction of 4 accounts: A user (Alice), a hidden address (Submarine), a dApp, and a Challenger. Alice performs 3 or 4 transactions depending on the implementation.


  1. Alice commits value and data to a hidden submarine address.
  2. Alice reveals the value and data to the dApp after at least one block.
  3. Alice broadcasts raw signed unlock transaction where Submarine address sends the value to the dApp.
  4. dApp finalizes the process by retrieving the value and data.


In this system, Alice has the opportunity to act maliciously by revealing different value and data than what she previously committed. This behaviour can be prevented by requiring Alice to submit a deposit with the reveal and requiring a challenge period between the unlock and finalize transaction where a challenger can prove Alice is cheating and claim her deposit.


The sum of gas used for user generated transactions amounts to roughly 207k gas whereas the challenge amounts to roughly 270k gas.

LibSubmarine Internals

We built LibSubmarine as a modular and reusable implementation of the Submarine Sends scheme. The architecture consists of a library for generating and executing the commit-reveal scheme and a separate library called ProvEth for the generation and verification of the Merkle-Patricia Proofs used by the challenger.

LibSubmarine and Proveth libraries


First, the off-chain procedure consists of generating a pseudo-signature which can be used to ‘trick’ the Ethereum chain to accept a one-off transaction from an address for which we do not have the private key.

This is possible because the address sending a transaction is not actually defined in a raw broadcasted Ethereum transaction. Instead, ‘From’ addresses are computed on the fly by Ethereum clients based on the ECDSA Secp256k1 signature attached to a transaction.

Because of the way ECDSA works, it is possible to pass arbitrary data as a transaction signature and call ecrecover(Txdata)to obtain an ECDSA public key which corresponds to the Ethereum `From` address of the transaction.

This constructed transaction becomes the unlock transaction which can be executed once the user has completed the reveal step.

Once the off-chain procedure is complete, the user proceeds to the four steps outlined in the previous section. Commit, Reveal, Unlock, and Finalize. More details can be found in our Github repo.


This library creates merkle-patricia proofs off-chain using the transaction trie of an Ethereum block and verifies the proof on-chain using smart contracts.

This proof is what a challenger submits to credibly claim that Alice is acting maliciously and slash her deposit.

This library was re-packaged from the Peace Relay and can be used as a tool to perform merkle-patricia proof verification on chain.

Wrapping it up.

Check out our Github. We would love some help with improving the library. Otherwise you can encourage us with a tweet to get the word out! 👌

If your technical curiosity is still tingling - keep your eyes peeled! We will be posting additional articles covering the code in detail.

This is a tool by the community, for the community using the MIT License. 💯

All credit for discovering this scheme goes to the IC3 team with their submarines sends article and to @ethlorenz for finding a cost effective implementation.

Thank you to @relyt29, @sbetamc, and @ethlorenz for being bad-ass devs and helping review this article!

Topics of interest

More Related Stories