Safe CASM{:md}
.
Sierra ensures that programs are always provable by preventing the compilation of programs with infinite loops or invalid constraints.
From Cairo 1 to Sierra
Before Starknet Alpha v0.11.0, developers wrote contracts in Cairo 0, which compiled directly to Cairo Assembly (CASM), and contract classes were submitted to the sequencer viaDECLARE
transactions.
This approach had risks, as the sequencer could not determine whether a given transaction would fail without executing it, and therefore could not charge fees for failed transactions.
Cairo 1 introduced contract class compilation to this new Sierra intermediate representation instead of directly compiling to CASM. The Sierra code is then submitted to the sequencer, compiled down to CASM, and finally executed by the Starknet OS.
Using Sierra ensures that all transactions (including failed ones) are provable, and allows sequencers to charge fees for all submitted transactions, making DoS attacks significantly more expensive.
Compilation Pipeline
If you’re interested in really understanding how the compilation works under the hood, check out the cairo-compiler-workshop.
Anatomy of a Sierra Program
Type Declarations
Sierra, as a Cairo representation, also uses a linear type system, where each value must be used exactly once. During the compilation, a unique identifier is assigned to each type. When types can safely be used multiple times, they need to be duplicated using thedup
instruction, which will assign two new identifiers to preserve linearity.
Type declaration is done with the following syntax:
In addition, each type has a set of attributes that describe how it can be used:
- storable
- droppable
- duplicatable
- zero_sized
Library Function Declarations
Sierra comes with a set of built-in functions (libfuncs
) that represent the call to low-level units of code known to be safe. After type declarations, a Sierra program must define all the libfuncs used in the program along with their expected input types.
Libfunc declaration is done with the following syntax:
While this section is generic, Starknet uses an allowed list of libfuncs.
Statements
This section shows the sequence of operations that occur during execution, describing the actual logic of the program. A statement either invokes a libfunc or returns a value. Statements are declared with the following syntax:return(variable_id)
statement.
User Defined Functions Declarations
At the end of a Sierra program, each user-defined function is declared with a unique identifier and the statement index where the function starts. This provides information about the function, such as its signature, while the implementation is defined in the statements section. An user defined function is declared with the following syntax:Simple Sierra Program Breakdown
Let’s go through the following Cairo program:felt252
: Represents the field element type
felt252_add
: Performs addition on field elementsstore_temp<felt252>
: Temporarily stores the result
- Statement 0: calls the
felt252_add
libfunc to add the values from memory cells 0 and 1, storing the result in memory cell 2 - Statement 1: calls the
store_temp<felt252>
libfunc to prepare the result for the return statement - Statement 2: returns the value from memory cell 2
add_numbers
: Takes twofelt252
types in memory cells 0 and 1 and returns afelt252
value by starting at statement 0
To enable Sierra code generation in a human-readable format, add the
sierra-text
flag to the library target in your Scarb.toml{:md}
file: