Two weeks ago we announced Shutter Network. Today we are excited to release the first alpha version, deployed on the Goerli testnet. Shutter Network is an open-source project that aims to prevent frontrunning on Ethereum by using a threshold cryptography-based distributed key generation (DKG) protocol.
In this blog post we will explain the scope of the release, run you through the transaction flow, and explain how to play with the system.
The release consists of a suite of smart contracts and the keyper¹ client, both of which are open-source under the MIT licence. You can check out the repository on Github.
In addition, we are providing an example application — a frontrunning resistant message billboard using Shutter. A network of 21 keyper nodes (for this demo hosted centrally) create keys and decrypt transactions in this demo. Please note that this is still a work-in-progress which means there might be bugs, the user interface may feel clunky, and gas efficiency is not optimized yet.
The Flow of a Shutter Transaction
A Shutter transaction is a transaction protected from frontrunning in the target smart contract system. It therefore passes through a sequence of stages before it is executed.
A Shutter transaction is:
- Created and encrypted in the user's wallet;
- Sent to the batcher contract as a standard Ethereum transaction;
- Picked up and decrypted by the keypers;
- Sent to the executor contract, and
- Forwarded to the target contract.
In more detail, Shutter transactions are grouped in batches. Each batch spans a configurable number of blocks and has a unique encryption/decryption key pair. In order to send a transaction through Shutter, the user first has to decide which batch the transaction should be included in. Afterwards, they use the key corresponding to this batch to encrypt their transaction. Lastly, they send the transaction to the batcher contract where it is pending to be executed. User interfaces can abstract the additional complexity of these steps away and Shutter enabled dapps should not look too different from standard dapps.
The encrypted transaction is then pending in the batcher contract until the batch closes, which happens implicitly at a corresponding block height. At this point, the keyper set will cooperate to generate the decryption key, decrypt all transactions in the batch, and deterministically shuffle² them. They will pass the decrypted transactions to the executor contract which will perform some sanity checks to ensure that no previous batch was skipped and that the keypers provided the correct transaction set, etc. After these checks are done, the executor contract sends the transactions one by one to the target contract (i.e. the contract the user wants to interact with).
How to Use the Example Application
We built a simple example application and provide a web interface to illustrate the user experience of Shutter Network. It allows you to send a message that the contract will emit as an event — a frontrunning protected billboard!
A hypothetical use case for this could be an online pub quiz, which does not rely on a centralised party and where it is important to prove that someone was first to answer the question. With plain text transactions, a miner could censor the submitted answer and pretend they came up with it themselves.
To use the application, you need a browser with Metamask or a similar wallet plugin and some testnet ETH to cover transaction fees. The wallet has to be connected to Goerli. Press the "Connect" button to allow the application to interact with one of your accounts.
Once connected, you are able to enter a message to send. Then press "Send encrypted". The application will add a nonce (preventing message replay) and a signature (using a random private key)³. Then it will acquire the public key corresponding to the target batch, encrypt the message with it, and wrap it in a normal Ethereum transaction which you will have to sign using your wallet.
Once the transaction is included in a block, it is scheduled for later execution. It should appear in the "Recently Submitted Transactions" table. Note that the message data is encrypted and no one will be able to decipher it, so frontrunning it is not possible.
When the batch with your transaction is closed, the keypers will decrypt and send it to the blockchain for execution. You can check the progress in the "Status" table. Eventually, your transaction with the decrypted message should show up under "Recently Executed Transactions". If everything worked fine, your message will be visible to the world — and no one has had a chance to know its content nor mess with its publication before it was notarized.
We are happy with our results so far, but this is still a work-in-progress and there is a lot to be done. We will keep working on the implementation to reach production quality so that applications can be confidently built on top of the Shutter Network. Nevertheless, if you are building a decentralized exchange, a governance system, or any other application that may suffer from frontrunning, it is already the right time to investigate Shutter. Feel free to check out our first blog post to get more details and reach out to us directly.
In the next blog post we are planning to provide an in-depth technical explanation of Shutter. To stay up to date, please follow us on Twitter and join the Telegram group! You are welcome to share your feedback or reach out to us via DM.
¹ Keypers is a group of special nodes that provide the keys for encryption and decryption of transactions.
² The randomness for shuffling is extracted from the decryption key which is not known in advance, so the order is both unpredictable and unbiasable.
³ In a production application, we would expect a key from the user’s wallet to be used for the signing.