Appendix A - System Calls

This chapter is based on the Starknet documentation available at Starknet Docs.

Writing smart contracts requires various associated operations, such as calling another contract or accessing the contract’s storage, that standalone programs do not require.

The Starknet contract language supports these operations by using system calls. System calls enable a contract to require services from the Starknet OS. You can use system calls in a function to get information that depends on the broader state of Starknet, which would otherwise be inaccessible, rather than local variables that appear in the function’s scope.

Here is a list of the system calls available in Cairo 1.0:

get_block_hash

Syntax

pub extern fn get_block_hash_syscall(
    block_number: u64,
) -> SyscallResult<felt252> implicits(GasBuiltin, System) nopanic;

Description

Gets the hash of a specific Starknet block within the range of [first_v0_12_0_block, current_block - 10].

Return Values

Returns the hash of the given block.

Error Messages

  • Block number out of range: block_number is greater than current_block- 10.
  • 0: block_number is less than the first block number of v0.12.0.

Common Library

get_execution_info

Syntax

pub extern fn get_execution_info_syscall() -> SyscallResult<
    Box<starknet::info::ExecutionInfo>,
> implicits(GasBuiltin, System) nopanic;

Description

Gets information about the original transaction.

In Cairo 1.0, all block/transaction/execution context getters are batched into this single system call.

Arguments

None.

Return Values

Returns a struct containing the execution info.

Common Library

call_contract

Syntax

pub extern fn call_contract_syscall(
    address: ContractAddress, entry_point_selector: felt252, calldata: Span<felt252>,
) -> SyscallResult<Span<felt252>> implicits(GasBuiltin, System) nopanic;

Description

Calls a given contract. This system call expects the address of the called contract, a selector for a function within that contract, and call arguments.

Note:

An internal call can’t return Err(_) as this is not handled by the sequencer and the Starknet OS.

If call_contract_syscall fails, this can’t be caught and will therefore result in the entire transaction being reverted.

Arguments

  • address: The address of the contract you want to call.
  • entry_point_selector: A selector for a function within that contract, can be computed with the selector! macro.
  • calldata: The calldata array.

Return Values

The call response, of type SyscallResult<Span<felt252>>.

Common Library

Note: This is considered a lower-level syntax for calling contracts. If the interface of the called contract is available, then you can use a more straightforward syntax.

deploy

Syntax

pub extern fn deploy_syscall(
    class_hash: ClassHash,
    contract_address_salt: felt252,
    calldata: Span<felt252>,
    deploy_from_zero: bool,
) -> SyscallResult<(ContractAddress, Span<felt252>)> implicits(GasBuiltin, System) nopanic;

Description

Deploys a new instance of a previously declared class.

Arguments

  • class_hash: The class hash of the contract to be deployed.
  • contract_address_salt: The salt, an arbitrary value provided by the sender. It is used in the computation of the contract’s address.
  • calldata: The constructor’s calldata. An array of felts.
  • deploy_from_zero: A flag used for the contract address computation. If not set, the caller address will be used as the new contract’s deployer address, otherwise 0 is used.

Return Values

A tuple wrapped with SyscallResult where:

  • The first element is the address of the deployed contract, of type ContractAddress.

  • The second element is the response array from the contract’s constructor, of type Span::<felt252>.

Common Library

emit_event

Syntax

pub extern fn emit_event_syscall(
    keys: Span<felt252>, data: Span<felt252>,
) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic;

Description

Emits an event with a given set of keys and data.

For more information and a higher-level syntax for emitting events, see Starknet events.

Arguments

  • keys: The event’s keys. These are analogous to Ethereum’s event topics, you can use the starknet_getEvents method to filter by these keys.

  • data: The event’s data.

Return Values

None.

Example

The following example emits an event with two keys, the strings status and deposit and three data elements: 1, 2, and 3.

let keys = ArrayTrait::new();
keys.append('key');
keys.append('deposit');
let values = ArrayTrait::new();
values.append(1);
values.append(2);
values.append(3);
emit_event_syscall(keys, values).unwrap_syscall();

Common Library

library_call

Syntax

pub extern fn library_call_syscall(
    class_hash: ClassHash, function_selector: felt252, calldata: Span<felt252>,
) -> SyscallResult<Span<felt252>> implicits(GasBuiltin, System) nopanic;

Description

Calls the requested function in any previously declared class. The class is only used for its logic.

This system call replaces the known delegate call functionality from Ethereum, with the important difference that there is only one contract involved.

Arguments

  • class_hash: The hash of the class you want to use.

  • function_selector: A selector for a function within that class, can be computed with the selector! macro.

  • calldata: The calldata.

Return Values

The call response, of type SyscallResult<Span<felt252>>.

Common Library

send_message_to_L1

Syntax

pub extern fn send_message_to_l1_syscall(
    to_address: felt252, payload: Span<felt252>,
) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic;

Description

Sends a message to L1.

This system call includes the message parameters as part of the proof’s output and exposes these parameters to the StarknetCore contract on L1 once the state update, including the transaction, is received.

For more information, see Starknet’s messaging mechanism.

Arguments

  • to_address: The recipient’s L1 address.

  • payload: The array containing the message payload.

Return Values

None.

Example

The following example sends a message whose content is (1,2) to the L1 contract whose address is 3423542542364363.

let payload = ArrayTrait::new();
payload.append(1);
payload.append(2);
send_message_to_l1_syscall(payload).unwrap_syscall();

Common Library

get_class_hash_at

Syntax

pub extern fn get_class_hash_at_syscall(
    contract_address: ContractAddress,
) -> SyscallResult<ClassHash> implicits(GasBuiltin, System) nopanic;

Description

Gets the class hash of the contract at the given address.

Arguments

  • contract_address: The address of the deployed contract.

Return Values

The class hash of the contract's originating code.

Common Library

replace_class

Syntax

pub extern fn replace_class_syscall(
    class_hash: ClassHash,
) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic;

Description

Once replace_class is called, the class of the calling contract (i.e. the contract whose address is returned by get_contract_address at the time the syscall is called) will be replaced by the class whose hash is given by the class_hash argument.

Note:

After calling replace_class, the code currently executing from the old class will finish running.

The new class will be used from the next transaction onwards or if the contract is called via the call_contract syscall in the same transaction (after the replacement).

Arguments

  • class_hash: The hash of the class you want to use as a replacement.

Return Values

None.

Common Library

storage_read

Syntax

pub extern fn storage_read_syscall(
    address_domain: u32, address: StorageAddress,
) -> SyscallResult<felt252> implicits(GasBuiltin, System) nopanic;

Description

Gets the value of a key in the storage of the calling contract.

This system call provides direct access to any possible key in storage, in contrast with var.read(), which enables you to read storage variables that are defined explicitly in the contract.

For information on accessing storage by using the storage variables, see storage variables.

Arguments

  • address_domain: The domain of the key, used to separate between different data availability modes. This separation is used in Starknet to offer different data availability modes. Currently, only the onchain mode (where all updates go to L1), indicated by domain 0, is supported. Other address domains which will be introduced in the future will behave differently in terms of publication (in particular, they will not be posted on L1, creating a tradeoff between cost and security).

  • address: The requested storage address.

Return Values

The value of the key, of type SyscallResult<felt252>.

Example

use starknet::storage_access::storage_base_address_from_felt252;

...

let storage_address = storage_base_address_from_felt252(3534535754756246375475423547453)
storage_read_syscall(0, storage_address).unwrap_syscall()

Common Library

storage_write

Syntax

pub extern fn storage_write_syscall(
    address_domain: u32, address: StorageAddress, value: felt252,
) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic;

Description

Sets the value of a key in the storage of the calling contract.

This system call provides direct access to any possible key in storage, in contrast with var.write(), which enables you to write to storage variables that are defined explicitly in the contract.

For information on accessing storage by using the storage variables, see storage variables.

Arguments

  • address_domain: The domain of the key, used to separate between different data availability modes. This separation is used in Starknet to offer different data availability modes. Currently, only the onchain mode (where all updates go to L1), indicated by domain 0, is supported. Other address domains which will be introduced in the future will behave differently in terms of publication (in particular, they will not be posted on L1, creating a tradeoff between cost and security).

  • address: The requested storage address.

  • value: The value to write to the key.

Return Values

None.

Common Library

keccak

Syntax

pub extern fn keccak_syscall(
    input: Span<u64>,
) -> SyscallResult<u256> implicits(GasBuiltin, System) nopanic;

Description

Computes the Keccak-256 hash of a given input.

Arguments

  • input: A Span<u64> Keccak-256 input.

Return Values

Returns the hash result as a u256.

Common Library

sha256_process_block

Syntax

pub extern fn sha256_process_block_syscall(
    state: core::sha256::Sha256StateHandle, input: Box<[u32; 16]>
) -> SyscallResult<core::sha256::Sha256StateHandle> implicits(GasBuiltin, System) nopanic;

Description

Computes the next SHA-256 state of the input with the given state.

This syscall computes the next SHA-256 state by combining the current state with a 512-bit block of input data.

Arguments

  • state: The current SHA-256 state.
  • input: The value to be processed into SHA-256.

Return Values

Returns a new SHA-256 state of the input data.

Common Library