Cairo1/Cairo0 Interoperability

Cairo1 and Cairo0 Interoperability

A CASM program consists of two main components: bytecode (vec<bigint>) and Python hints (vec<string>). The bytecode includes all Cairo VM instructions and all deterministic inputs to the program, while the Python hints are pieces of Python code that run at specified program counter values during execution.


Cairo0

Cairo0 is a general-purpose language with features like memory manipulation, segment creation, and Cairo assembly code injection. These capabilities allow the creation of programs that can:

  • Dynamically load other programs' bytecode into a designated memory segment.

  • Load the corresponding hints into the parent Python hints list, relocating the program counters of the hints so they execute at the correct program counter values.

During the execution of a Cairo0 program, a jmp abs command can jump to the entry point of the externally loaded bytecode, making the Cairo VM execute those instructions normally. The jmp command inherits the frame pointer (fp) of the parent function frame and the return program counter (ret_pc), so when the function calls the ret opcode, it returns to the parent function in the call stack. Once the externally loaded program finishes, execution proceeds with the bytecode of the original Cairo0 program.


Cairo1

In contrast, Cairo1 is a more user-friendly language, similar to Rust in terms of syntax. It is more abstract and less versatile, which simplifies the development of large projects with more readable code. Cairo1 offers structures like structs, traits, and implementations, and it is modular. However, it lacks the memory manipulation capabilities and CASM code injections of Cairo0, making it less flexible. Despite these limitations, Cairo1 provides advantages in terms of memory integrity and call stack validity, making it an easier and safer language for developers.


Combining Cairo0 and Cairo1

Imagine you have a Cairo0 program that heavily utilizes Cairo0's flexibility to efficiently manipulate, check, and interpret external data, as is the case with Data Processor. However, you want to load external program modules that use the data prepared and validated by the Cairo0 host (Data Processor). These external modules should not be able to modify the Cairo0 host runtime memory in an unauthorized way, either by mistake or on purpose. Therefore, these modules need to be written in a safer, less versatile language. The perfect match for this requirement is Cairo1. Additionally, Cairo1 offers the familiar Rust syntax and all its development conveniences.


Interoperability

The natural need for creating interoperability between Cairo0 and Cairo1 arises. This is achieved by:

  • Using a Cairo0 bootloader: A program that dynamically loads external programs into itself and runs them.

  • Utilizing a Cairo1 compiler: Required to compile Cairo1 projects into CASM.

  • Employing Python utilities: To load Cairo1 programs into Cairo0 memory dynamically.

This approach combines the best of both worlds, leveraging Cairo0's flexibility and Cairo1's safety and ease of use.

Last updated