Skip to main content
This page introduces the Starknet-specific concepts you need to understand before building LayerZero applications. If you’re coming from EVM chains, this guide explains how Starknet differs and why LayerZero’s implementation works the way it does. What you’ll learn:
  • Cairo’s felt252 type system and u256 representation
  • Starknet storage model and component-based composition
  • Transaction types, versions, and typed dispatcher calls
  • Multi-call patterns for atomic configuration
  • Resource bounds, fee estimation, and common gas pitfalls
  • Reentrancy protections and clear-then-execute behavior
  • Bytes32 address encoding for crosschain peers
For complete protocol workflows with detailed code, see Protocol Overview. For hands-on implementation, see OApp or OFT guides.

VM Architecture

Starknet uses the Cairo programming language and a field-element-based type system. These fundamentals shape how LayerZero contracts represent addresses, amounts, and payloads.

The felt252 Type

Starknet’s native type is felt252 (field element), a ~251-bit unsigned integer:
Key Properties:
  • Native to the STARK proof system (efficient proving)
  • Wraps around on overflow (unlike Solidity’s revert behavior)
  • Can represent addresses, integers, and short strings

Common Types

u256 Representation

Unlike EVM’s native 256-bit integers, Starknet represents u256 as two felt252 values:
Implications for LayerZero:
  • Crosschain amount encoding must handle this difference
  • OFT uses u64 for shared decimals to ensure compatibility

Message Flow Overview

LayerZero messages on Starknet flow through the Endpoint and verification system before reaching the destination OApp:
  • Send: OApp -> Endpoint -> message library -> workers (DVNs/Executor)
  • Verify: DVNs verify and submit to the receive library
  • Receive: Executor calls lz_receive on the destination OApp
Complete Protocol DetailsFor detailed send/verify/receive workflows with contract code and event flows, see Protocol Overview.

Transaction Execution Model

Starknet uses distinct transaction types and typed dispatchers. These patterns determine how LayerZero contracts are deployed, called, and configured.

Transaction Types

Starknet has distinct transaction types for different operations:

DECLARE

Publishes contract code to the network:
Result: class_hash - unique identifier for the contract code When to use: First time deploying a new contract version

DEPLOY_ACCOUNT

Deploys an account contract:
Prerequisite: The computed account address must be pre-funded When to use: Setting up a new wallet/signer

INVOKE

Executes contract functions:
When to use: All regular contract interactions

Transaction Versions

  • v0/v1/v2: Deprecated and unsupported on current Starknet networks
  • v3: Current transaction format with resource bounds (recommended)

Dispatcher Pattern

Starknet doesn’t support dynamic dispatch (no delegatecall equivalent). Instead, cross-contract calls use typed dispatchers. For more details, see the Cairo Book: Dispatcher Pattern.

Interface Definition

Generated Dispatcher

The compiler generates a dispatcher for each interface:

Using Dispatchers

Benefits:
  • Compile-time type checking
  • Automatic serialization/deserialization
  • Clear error messages
vs EVM:

Multi-Call Transactions

Multicall is implemented at the account-contract level: a single INVOKE can execute multiple calls atomically when the account supports it. Most major account implementations (Ready Wallet, formerly Argent; Braavos; OpenZeppelin Account) expose multicall by default. If an account contract does not implement multicall, batching is not available for that account.

Batching with Account.execute

Benefits

  • Atomicity: All calls succeed or all fail
  • Gas efficiency: Single transaction overhead
  • Configuration safety: Set all config before enabling pathway

LayerZero Configuration Pattern

State Management Model

Starknet contracts use a key-value storage model and component-based composition rather than inheritance. These patterns shape how LayerZero contracts store configuration and expose functionality.

Contract Storage Model

Storage Structure

Starknet contracts use a key-value storage model with felt252 keys:

Storage Access

Storage Layout

Storage keys are computed deterministically:
  • Simple variables: sn_keccak(variable_name)
  • Mappings: h(h(variable_name), key1, key2, ...)
This is abstracted by the compiler, but understanding it helps with:
  • Debugging storage reads/writes
  • Computing storage proofs for crosschain verification

Component System

Cairo uses a component system instead of inheritance:

Defining a Component

Using Components in a Contract

vs Solidity Inheritance:

Security & Permission Model

Starknet’s execution model affects how reentrancy is handled in LayerZero contracts.

Reentrancy Model

Unlike EVM, Starknet’s execution model provides some inherent reentrancy protections:

Sequential Execution

Transactions are executed sequentially within a block, not concurrently. However, within a single transaction, reentrancy is still possible.

ReentrancyGuard Component

LayerZero contracts use OpenZeppelin’s ReentrancyGuard:

Clear-Then-Execute Pattern

The Endpoint uses this pattern for lz_receive:

Gas Model

Starknet’s fee model differs from EVM and uses explicit resource bounds.

Gas Model

Setting Resource Bounds

Estimating Fees

Common Issues

Key Starknet Concepts for LayerZero

Address encoding is critical for crosschain peer verification.

Address Encoding for Crosschain

Bytes32 for Cross-VM Compatibility

LayerZero uses Bytes32 for addresses to support different address sizes:

Setting Peers

Key Takeaways

  • felt252 and u256 encoding affect how LayerZero represents amounts and addresses.
  • Storage and components replace inheritance; configuration lives in structured storage.
  • Typed dispatchers provide safe cross-contract calls without dynamic dispatch.
  • Multicall enables atomic configuration before opening pathways.
  • Resource bounds and fee estimation require explicit handling on Starknet.
  • Clear-then-execute prevents reentrancy during lz_receive.
  • Bytes32 encoding standardizes peer addresses across chains.

Next Steps