Decentralized Ethereum Mixer
How it works
When someone sends 1 ether to the
deposit function in miximus.sol they append single leaf
to the merkle tree.
Afterwards someone who has the secret key (sk) and
nullifier of the leaf of the merkle tree is allowed to
withdraw 1 ether. But instead of revealing the information to prove that they control it. They (using a zksnark)
produce a proof that they know this information without revealing it. They also create a proof that their leaf
is in the merkle tree.
When they verify this proof they reveal the nullifier, but not the sk. So no one is able to tell which nullifier maps to which leaf.
To prevent double spends the smart contract tracks the nullifiers and only allows a single withdrawal per nullifiers.
build libsnark gadget and getting the proving key
git submodule update --init --recursive
cmake .. && make
Finally you will need to download the ~400MB proving key from here, unzip it and save it in the
Running the tests
Start your prefered ethereum node,
cd tests and run
python3 test.py This will
- Generate verification keys, proving keys, This step takes a lot of ram and its likely your OS will kill it if you have a bunch of windows open.
- deploy the contract
- Deposit 32 ether in 1 ether chunks.
- Withdraw the 32 eth so that an observer cannot tell which deposit it was based upon.
The examples are interactive and ask you for the addresses you want to send from and to. The contract is deployed on the Rinkeby test net. These
scripts deposit and withdraw from that contract.
python3 deposit.py ether this will create a transaction from an account of your chosing to send 1 ether to the smart contract. It will create
a files of the forum
%d is the merkel tree index of your commitment.
python3 withdraw.py will ask you for a file
%d.json it will call libsnark and generate a proof with proving key
python3 withdraw.py takes a long time to run so make sure that your
eth.accounts is unlocked by the time the transaction gets broadcast. otherwise
it will drop to pdb debugger.
Layer 2 transaction abstraction
A major problem in the current system is who pays for the gas for the withdrawal. While the perfect solution to this is to allow the smart contract to pay for gas. This is not possible at the moment. There for we provide layer two transaction abstraction where a depositor can define a fee that gets paid to whoever pays the gas of a transaction. Future work should formalize a communication channel where people can advertise these transactions so that others can pay the gas for them and recive a reward.