Awesome
zkay: A Language for Private Smart Contracts on Ethereum
Zkay (pronounced as [zi: keɪ]
) is a programming language which enables automatic compilation of intuitive data privacy specifications to Ethereum smart contracts leveraging (homomorphic) encryption and non-interactive zero-knowledge (NIZK) proofs. This repository provides a toolchain for compiling, deploying and using zkay contracts.
In addition to the instructions below, we refer to the following resources:
- The original research paper (zkay), which introduces the core concepts of zkay.
- The follow-up research paper (ZeeStar), which discusses how homomorphic encryption is introduced in zkay v0.3.
- The online documentation, which provides a tutorial, language reference and API documentation.
Further, the following documents describe the implementation details of zkay:
- The implementation of zkay v0.2 is discussed in a technical report.
- The implementation of zkay v0.3 is described in these notes.
Warning / Security Disclaimer
Zkay is a research project and its implementation should not be considered secure (e.g., it may contain bugs and has not undergone any security review)! Do not use zkay in a productive system or to process sensitive confidential data.
Prerequisites
Zkay requires python version 3.8 or later (we recommend using a separate conda environment). In addition, install the following dependencies using your system's package manager:
Debian/Ubuntu
sudo apt-get install default-jdk-headless git build-essential cmake libgmp-dev pkg-config libssl-dev libboost-dev libboost-program-options-dev
Arch Linux
sudo pacman -S --needed jdk-openjdk cmake pkgconf openssl gmp boost
Installation
Install zkay in editable mode as follows.
git clone https://github.com/eth-sri/zkay.git
# first, install the babygiant library (see zkay/babygiant-lib/README.md for troubleshooting)
cd zkay/babygiant-lib
bash ./install.sh
cd ..
# then, install zkay
pip install -e .
Using Docker
Alternatively, you can run zkay in a docker container using the provided Dockerfile in the install
subdirectory:
make -C ./install run
Unit Tests
To run all unit tests, use:
python -m unittest discover --verbose zkay
Building the Docs
The documentation is hosted here. To build it locally, use the following commands (requires sphinx, sphinx-rtd-theme, and sphinx-autoapi):
cd docs
make html
The above commands create a tree of HTML files in _build/html
. Developers with sufficient access rights can publish the documentation on GitHub Pages using the script publish_gh_pages.sh
.
Usage
See the online documentation for a tutorial on how to use zkay. Below, we only show a summary of available commands.
Note: zkay supports tab completion in Bash shells via the argcomplete package. To enable this feature, argcomplete must be installed and activated on your system (see instructions).
Type-check Contracts
To type-check a zkay file test.zkay
without compiling it, run:
zkay check test.zkay
Strip zkay Features from Contract
To strip zkay-specific features from test.zkay
and output the resulting (location preserving) Solidity code, run:
zkay solify test.zkay
The transformed code is printed to stdout.
Deploy Library Contracts
Zkay requires a backend-dependent external public key infrastructure (PKI) contract and, depending on the proving scheme, additional library contracts to be deployed. These contracts can be compiled and deployed using the commands:
zkay deploy-pki <account>
zkay deploy-crypto-libs <account>
The account
parameter specifies the wallet address from which the deployment transaction should be issued.
Note: The groth16
proving scheme (enabled by default) does not require additional libraries, in which case zkay deploy-crypto-libs
is not required.
Note: The default eth-tester
blockchain backend does not require manually deploying the PKI or library contracts.
Compile Contracts
To compile a zkay file test.zkay
, run:
zkay compile [-o "<output_dir>"] test.zkay
This performs the following steps:
- Type checking (equivalent to
zkay check
) - Compilation to Solidity
- NIZK proof circuit compilation and key generation
- Generation of the contract interface
contract.py
, which can be used to transparently interact with a deployed zkay contract
Exporting a Contract Package
To package a zkay contract that was previously compiled with output directory <compilation_output>
, run:
zkay export [-o "<output_filename>"] "<compilation_output>"
This creates an archive containing the zkay code, the NIZK prover and verifier keys, and manifest file. The recommended file extension for the archive is *.zkp
. This archive can be distributed to users of the contract.
Importing a Contract Package
To unpack and compile a contract package contract.zkp
:
zkay import [-o "<unpack_directory>"] contract.zkp
Interacting with a Contract
Assume you have compiled a file test.zkay
using zkay compile -o "output_dir"
(or imported an archive contract.zkp
using zkay import -o "output_dir" contract.zkp
), you can open an interactive shell for deploying and interacting with the contract as follows:
zkay run output_dir
>>> ...
The python shell provides the following commands:
help()
: Get a list of all contract functions and their argumentsuser1, user2, ..., userN = create_dummy_accounts(N)
: Get addresses of pre-funded test accounts for experimentation (only supported ineth-tester
andganache
backends)handle = deploy(*constructor_args, user: str)
: Issue a deployment transaction for the contract from the accountuser
(address literal).handle = connect(contract_addr: str, user: str)
: Create a handle to interact with the deployed contract at addresscontract_addr
from accountuser
. Fails if remote contract does not match local files.handle.address
: Get the address of the deployed contract corresponding to this handlehandle.some_func(*args[, value: int])
: The account which created handle issues a zkay transaction which calls the zkay contract functionsome_func
with the given arguments. Encryption, transaction transformation and proof generation happen automatically. If the function is payable, the additional argumentwei_amount
can be used to set the wei amount to be transferred.handle.state.get_raw('varname', *indices)
: Retrieve the current raw value of state variablename[indices[0]][indices[1]][...]
.handle.state.get_plain('varname', *indices)
: Retrieve the current plaintext value (decrypted with @me key if necessary) of state variablename[indices[0]][indices[1]][...]
.
Update Solc to Latest Compatible Version
To download and install the latest compatible version of solc (requires internet connection):
zkay update-solc
Third-party Libraries
Zkay is based on various third-party source code and libraries:
- zkay-libsnark (fork of libsnark): Downloaded and built during setup of zkay.
- zkay-jsnark (fork of jsnark): Bundled in
zkay/jsnark_interface/JsnarkCircuitBuilder.jar
. - pygments-lexer-solidity: See
docs/custom_highlighting/zkay_lexer.py
. - solidity-BN256G2: See
zkay/compiler/privacy/bn256g2.sol
. - solidity alt_bn128 pairing library: See
zkay/compiler/privacy/library_contracts.py
. - solidity-antlr4: See
zkay/solidity_parser/Solidity.g4
. - Bouncy Castle Crypto APIs for Java: Bundled in
zkay/jsnark_interface/bcprov-jdk15on-1.64.jar
. - sapling_jubjub: See
zkay/transaction/crypto/babyjubjub.py
. - arkworks rust libraries: Dependencies of
babygiant-lib
.
See LICENSE-3RD-PARTIES for license information on third-party source code and libraries.
CCS 2019 Evaluation
The contracts evaluated in the CCS 2019 paper can be found in the folder eval-ccs2019
. The scenarios have been adapted to use zkay's new frontend. The original artifact (zkay version 0.1) evaluated in the CCS 2019 paper can be found under the tag ccs2019.
S&P 2022 Evaluation
The artifact evaluated in the S&P 2022 paper (ZeeStar) can be found under the tag sp2022. The example contracts and instructions on how to reproduce the results can be found in the folder eval-sp2022
.
Citing this Work
You are encouraged to cite the following research paper if you use zkay for academic research.
@inproceedings{steffen2019zkay,
author = {Steffen, Samuel and Bichsel, Benjamin and Gersbach, Mario and Melchior, Noa and Tsankov, Petar and Vechev, Martin},
title = {Zkay: Specifying and Enforcing Data Privacy in Smart Contracts},
year = {2019},
isbn = {9781450367479},
publisher = {Association for Computing Machinery},
address = {New York, NY, USA},
url = {https://doi.org/10.1145/3319535.3363222},
doi = {10.1145/3319535.3363222},
booktitle = {Proceedings of the 2019 ACM SIGSAC Conference on Computer and Communications Security},
pages = {1759–1776},
numpages = {18},
location = {London, United Kingdom},
series = {CCS ’19}
}
The following research paper presents how zkay is extended by homomorphic encryption (implemented in version 0.3 of zkay).
@inproceedings{steffen2022zeestar
author = {Steffen, Samuel and Bichsel, Benjamin and Baumgartner, Roger and Vechev, Martin},
title = {ZeeStar: Private Smart Contracts by Homomorphic Encryption and Zero-knowledge Proofs},
year = {2022},
booktitle={2022 IEEE Symposium on Security and Privacy (SP)},
}
The following technical report describes version 0.2 of zkay, which introduces many vital features such as real encryption.
@techreport{baumann2020zkay,
title={zkay v0.2: Practical Data Privacy for Smart Contracts},
author={Nick Baumann and Samuel Steffen and Benjamin Bichsel and Petar Tsankov and Martin Vechev},
year={2020},
eprint={2009.01020},
url={https://arxiv.org/abs/2009.01020}
}