- Table of Contents
- π About
- π Getting Started
- π Usage
- π Benchmarks
- π Changelog
- π Contributing
- π Related Projects
- π Documentation
- βοΈ License
Cairo VM is the virtual machine for the Cairo language.
Previously, there was a version of Cairo VM written in Python, which was used in production.
This repository contains the newer version, written in Rust. It's faster and has safer and more expressive typing. Now in production, it has replaced the older Python version to become the primary Cairo VM.
Cairo is the first production-grade platform for generating STARK proofs for general computation.
It's Turing-complete and it was created by Starkware as part of the Starknet ecosystem.
These are needed in order to compile and use the project.
- Rust 1.81.0 or newer
- Cargo
These dependencies are only necessary in order to run the original VM, compile Cairo programs, and run tests.
- make
- PyEnv
You can install all of the required and optional dependencies by running the script install.sh
while in the repository root.
In order to compile programs you need to install the cairo-lang package.
Running the make deps
(or the make deps-macos
if you are runnning in MacOS) command will create a virtual environment with all the required dependencies.
You can then activate this environment by running
. cairo-vm-env/bin/activate
You can add the following to your rust project's Cargo.toml
:
cairo-vm = { version = '1.0.1'}
To run programs from the command line, first compile the repository from the cairo-vm-cli folder:
cd cairo-vm-cli; cargo build --release; cd ..
Once the binary is built, it can be found in target/release/
under the name cairo-vm-cli
.
In order to compile Cairo programs you need to activate the environment created while installing dependencies. To start it, run:
. cairo-vm-env/bin/activate
To compile a program, use cairo-compile [path_to_the_.cairo_file] --output [desired_path_of_the_compiled_.json_file]
. For example:
cairo-compile cairo_programs/abs_value_array.cairo --output cairo_programs/abs_value_array_compiled.json
To run a compiled .json program through the VM, call the executable giving it the path and name of the file to be executed. For example:
target/release/cairo-vm-cli cairo_programs/abs_value_array_compiled.json --layout all_cairo
The flag --layout
determines which builtins can be used. More info about layouts here.
To sum up, the following code will get you from zero to running a Cairo program:
git clone https://github.com/lambdaclass/cairo-vm.git
cd cairo-vm
cargo build --release
. cairo-vm-env/bin/activate
cairo-compile cairo_programs/abs_value_array.cairo --output cairo_programs/abs_value_array_compiled.json
target/release/cairo-vm-cli cairo_programs/abs_value_array_compiled.json --layout all_cairo
The cairo-vm-cli supports the following optional arguments:
-
--trace_file <TRACE_FILE>
: Receives the name of a file and outputs the relocated trace into it -
--memory_file <MEMORY_FILE>
: Receives the name of a file and outputs the relocated memory into it -
--print_output
: Prints the program output -
--proof_mode
: Runs the program in proof_mode -
--secure_run
: Runs security checks after execution. Enabled by default when not in proof_mode. -
--air_public_input <AIR_PUBLIC_INPUT>
: Receives the name of a file and outputs the AIR public inputs into it. Can only be used if proof_mode is also enabled. -
--air_private_input <AIR_PRIVATE_INPUT>
: Receives the name of a file and outputs the AIR private inputs into it. Can only be used if proof_mode, trace_file & memory_file are also enabled. -
--cairo_pie_output <CAIRO_PIE_OUTPUT>
: Receives the name of a file and outputs the Cairo PIE into it. Can only be used if proof_mode is not enabled. -
--allow_missing_builtins
: Disables the check that all builtins used by the program need to be included in the selected layout. Enabled by default when in proof_mode. -
run_from_cairo_pie
: Runs a Cairo PIE instead of a compiled json file. The name of the file will be the first argument received by the CLI (as if it were to run a normal compiled program). Can only be used if proof_mode is not enabled. -
cairo_layout_params_file
: Only used with dynamic layout. Receives the name of a json file with the dynamic layout parameters.
For example, to obtain the air public inputs from a fibonacci program run, we can run :
target/release/cairo-vm-cli cairo_programs/proof_programs/fibonacci.json --layout all_cairo --proof_mode --air_public_input fibonacci_public_input.json
Currently, as this VM is under construction, it's missing some of the features of the original VM. Notably, this VM only implements a limited number of Python hints at the moment, while the Python Cairo VM allows users to run any Python code.
There are two ways to use non-standard hints in this VM:
- Extend the cairo-vm code and build your own binary using the interface HintProcessor.
- Use cairo-vm-py which supports running any hint in a Python interpreter.
When running a Cairo program directly using the Cairo-vm repository you would first need to prepare a couple of things.
- Specify the Cairo program you want to run
let program =
Program::from_file(Path::new(&file_path), None);
- Instantiate the VM, the cairo_runner, the hint processor, and the entrypoint
let mut cairo_runner = CairoRunner::new(&program, LayoutName::all_cairo, false, false);
let mut hint_processor = BuiltinHintProcessor::new_empty();
let entrypoint = program
.identifiers
.get(&format!("__main__.{}", &func_name))?
.pc;
- Lastly, initialize the builtins and segments.
cairo_runner.initialize_builtins(false)?;
cairo_runner.initialize_segments(None);
When using cairo-vm with the Starknet devnet there are additional parameters that are part of the OS context passed on to the run_from_entrypoint
method that we do not have here when using it directly. These parameters are, for example, initial stacks of the builtins, which are the base of each of them and are needed as they are the implicit arguments of the function.
let _var = cairo_runner.run_from_entrypoint(
entrypoint,
vec![
&MaybeRelocatable::from(2).into(), //this is the entry point selector
&MaybeRelocatable::from((2,0)).into() //this would be the output_ptr for example if our cairo function uses it
],
false,
&mut hint_processor,
);
To run a cairo 1 program enter in the folder cd cairo1-run
and follow the cairo1-run documentation
A demo on how to use cairo-vm
with WebAssembly can be found in examples/wasm-demo
To run the test suite you'll need cargo-llvm-cov
dependency so make sure to run this command beforehand:
make deps
Now that you have the dependencies necessary to run the test suite you can run:
make test
A dynamic layout must be specified with a dynamic params file. You can find an example in: vm/src/tests/cairo_layout_params_file.json
.
To run cairo 0 or 1 programs with a dynamic layout, you must use --layout dynamic
and the --cairo_layout_params_file
flag pointing a dynamic params file. For example, run:
cargo run --bin cairo-vm-cli cairo_programs/fibonacci.json --layout dynamic --cairo_layout_params_file vm/src/tests/cairo_layout_params_file.json
Cairo-vm offers a tracer which gives you a visualization of how your memory and registers change line after line as the VM executes the code. You can read more about it here
Running a Cairo program that gets the 1.5 millionth Fibonacci number we got the following benchmarks:
- Execution time with Criterion
- Flamegraph
- Github action results
Note before running the benchmark suite: the benchmark named iai_benchmark depends on Valgrind. Please make sure it is installed prior to running the iai_benchmark
benchmark.
Run the complete benchmark suite with cargo:
cargo bench
Run only the criterion_benchmark
benchmark suite with cargo:
cargo bench --bench criterion_benchmark
Run only the iai_benchmark
benchmark suite with cargo:
cargo bench --bench iai_benchmark
Benchmark the cairo-vm
in a hyper-threaded environment with the examples/hyper_threading/ crate
make hyper-threading-benchmarks
Keeps track of the latest changes here.
The open-source community is a fantastic place for learning, inspiration, and creation, and this is all thanks to contributions from people like you. Your contributions are greatly appreciated.
If you have any suggestions for how to improve the project, please feel free to fork the repo and create a pull request, or open an issue with the tag 'enhancement'.
- Fork the Project
- Create your Feature Branch (
git checkout -b feat/AmazingFeature
) - Commit your Changes (
git commit -m 'feat: add some AmazingFeature'
) - Push to the Branch (
git push origin feat/AmazingFeature
) - Open a Pull Request
And don't forget to give the project a star! β Thank you again for your support.
You can find more detailed instructions in the CONTRIBUTING.md document.
- starknet_in_rust: implementation of Starknet in Rust, powered by the cairo-vm.
- cairo-vm-py: Bindings for using cairo-vm from Python code.
- From Cairo Documentation: How Cairo Works
- Cairo β a Turing-complete STARK-friendly CPU architecture
- A Verified Algebraic Representation of Cairo Program Execution
- Cairo Verifier in Rust
We wrote a document explaining how the Cairo VM works. It can be found here.
This is a list of recommended books to learn how to implement a compiler or an interpreter.
- How I wrote my own "proper" programming language - Mukul Rathi
- Introduction to Compilers and Language Design - Douglas Thain
- Beautiful Racket - Matthew Flatt
- Crafting interpreters - Robert Nystrom
- Engineering a Compiler - Keith D. Cooper, Linda Torczon
- Intro to zero-knowledge proofs
- Security and Privacy for Crypto with Zero-Knowledge Proofs
- A Hands-On Tutorial for Zero-Knowledge Proofs Series
- What are zk-SNARKs?
- Vitalik's introduction to how zk-SNARKs are possible
- Vitalik's post on quadratic arithmetic programs
- Why and How zk-SNARK Works - Maksym Petkus
- Comparing General Purpose zk-SNARKs
- Dark forest's intro + circuits PART 1
- Dark forest's intro + circuits PART 2
Introduction:
- Cryptography Stack Exchange Answer
- Hasu gets STARK-pilled - with Eli Ben-Sasson
- Cairo for Blockchain Developers
- Why STARKs are the key to unlocking blockchain scalability
- STARKs whitepaper: Scalable, transparent, and post-quantum secure computational integrity
- STARKs vs. SNARKs: A Cambrian Explosion of Crypto Proofs
Vitalik Buterin's blog series on zk-STARKs:
- STARKs, part 1: Proofs with Polynomials
- STARKs, part 2: Thank Goodness it's FRI-day
- STARKs, part 3: Into the Weeds
Alan Szepieniec's STARK tutorial:
StarkWare's STARK Math blog series:
- STARK Math: The Journey Begins
- Arithmetization I
- Arithmetization II
- Low Degree Testing
- A Framework for Efficient STARKs
This project is licensed under the Apache 2.0 license.
See LICENSE for more information.