LayerZero V2

repository·main·Indexed 21 days ago

https://github.com/layerzero-labs/layerzero-v2

An omnichain interoperability protocol for censorship-resistant messaging and asset transfers across 60+ blockchains. It features standardized contract interfaces (OApp, OFT) and a modular security stack. The documentation covers the IOTA Move implementation, including the Call Module's hot-potato pattern for dynamic cross-contract coordination, hierarchical workflow management, and the PTB (Programmable Transaction Block) Move Call specification for dynamic construction and execution.

Tokens
24K
Snippets
58
Records
89
Agent score
73%

What's inside layerzero-v2

  1. Coordinate hierarchical workflows with child calls

    main

    The Call Module supports structured, multi-level coordination through parent-child relationships. This allows for complex workflows where a single root call can trigger multiple batches of child calls.

    Coordination Rules

    • Sequential Batches: A new batch (Batch N+1) cannot begin until the previous batch (Batch N) is complete.
    • Parallel Children: All calls within a single batch can execute concurrently.
    • FIFO Destruction: Child calls must be destroyed in the exact order they were created (First-In, First-Out).
    • Completion Propagation: A parent call cannot reach the Completed state until all of its children have been destroyed.

    Workflow Example Structure

    Root Call (A→B)
    ├── Batch 1 (nonce=1)
    │   ├── Child Call 1 (B→C)    [parallel execution]
    │   └── Child Call 2 (B→D)    [parallel execution]
    ├── Batch 2 (nonce=2)         [sequential after Batch 1]
    │   └── Child Call 3 (B→E)
  2. Understand the `Call<Param, Result>` core data structure

    main

    The Call<Param, Result> struct is the primary 'hot-potato' resource used for cross-contract communication in the IOTA Call module. It encapsulates the state of a call, including its identity, participants, and lifecycle status.

    Key fields include:

    • id: Globally unique identifier derived from the object ID.
    • caller & callee: The originating and target contract addresses.
    • one_way: Determines if the callee or the caller is responsible for destroying the resource.
    • param: Type-safe input parameters of type Param.
    • mutable_param: A boolean flag indicating if the callee is authorized to modify parameters.
    • result: An Option<Result> containing the output after complete() is called.
    • status: A CallStatus enum tracking the lifecycle (Active, Creating, Waiting, Completed).
    public struct Call<Param, Result> {
        id: address,                    // Globally unique call identifier
        caller: address,                // Originating contract address
        callee: address,                // Target contract address for processing
        one_way: bool,                  // Destruction authorization mode
        param: Param,                   // Type-safe input parameters
        mutable_param: bool,           // Whether callee can modify parameters (default: false)
        result: Option<Result>,         // Optional result (Some after completion)
        parent_id: address,             // Parent call ID (ROOT_CALL_PARENT_ID for roots)
        batch_nonce: u64,               // Monotonic batch sequence number
        child_batch: vector<address>,   // FIFO-ordered child call identifiers
        status: CallStatus,             // Automatically managed lifecycle state
    }
  3. Understand LayerZero V2 core components

    main

    The LayerZero V2 architecture is composed of several key layers:

    • Protocol Contracts: The core, immutable interfaces (such as the LayerZero Endpoint) are located in the /protocol directory.
    • MessageLib: Located in /messagelib, these contracts manage the append-only, on-chain Message Libraries. They define how Decentralized Verifier Networks (DVNs) and Executors interact with Ultra Light Nodes on each chain.
    • DVN (Decentralized Verifier Network): Responsible for verifying cross-chain messages. Developers can deploy custom DVN contracts on supported chains to create bespoke security setups.
    • Executor: Responsible for delivering messages on the destination chain. Developers can deploy custom Executors to ensure seamless message execution.
  4. How the Call Module enables dynamic cross-contract coordination in IOTA Move

    main

    The Call Module provides a way to perform dynamic dispatch in the IOTA Move VM, which otherwise requires all function calls to be statically resolved at compile time. It uses a hot-potato pattern to simulate runtime contract selection and method invocation without requiring the caller to have compile-time dependencies on all possible callees.

    Key Capabilities

    • Runtime Library Selection: Select message libraries based on runtime configuration.
    • Extensible Architecture: Integrate new libraries without modifying existing contracts.
    • Type-Safe Generics: Uses Move's type system via <Param, Result> parameters to ensure safety.
    • Hierarchical Coordination: Supports complex, multi-level workflows (parent-child call relationships) with structured batching.
    // Runtime target determination with compile-time safety
    let call = call::create<SendParams, Receipt>(
        &caller_cap,
        resolve_library_address(config),  // Runtime resolution
        false,                            // Bidirectional communication
        send_params,
        ctx
    );
    
    // Type-safe parameter passing and result collection
    // ... call flows to selected library ...
    call.complete(&library_cap, receipt);
    
    // Guaranteed result extraction
    let (callee_addr, params, receipt) = call.destroy(&caller_cap);
  5. Understand the Call Module lifecycle and hot-potato pattern

    main

    The Call<Param, Result> object implements a hot-potato pattern, meaning it is a non-droppable resource that must be handled through a specific lifecycle to ensure safety and completion.

    Lifecycle Stages

    1. Creation: The caller instantiates the call with typed parameters.
    2. Processing: The callee receives and processes the call.
    3. Delegation (Optional): The callee can create child calls for complex workflows.
    4. Completion: The callee provides a typed result via complete().
    5. Destruction: The authorized party extracts the result and consumes the call via destroy().

    State Transitions

    StateDescriptionValid Operations
    ActiveCan create new child batches or be completednew_child_batch(), complete()
    CreatingIn the process of creating child calls in current batchcreate_child()
    WaitingBatch finalized, waiting for children to be destroyeddestroy_child()
    CompletedHas result, ready for destructiondestroy()
  6. Use `CallCap` for authorization

    main

    The CallCap object provides authorization for state-modifying call operations. It supports two identity resolution modes via the CapType enum:

    1. Individual Capability (CapType::Individual): Uses the specific CallCap.id.to_address() as the identifier. This is used for single capability instance operations.
    2. Package Capability (CapType::Package(address)): Uses the provided package address as the identifier. This allows protocol-level operations across all instances from the same package and requires a one-time witness for creation.

    All state-modifying operations require a CallCap to be passed as an argument.

    public struct CallCap has key, store {
        id: UID,                        // Sui object identifier
        cap_type: CapType,              // Determines identity resolution mechanism
    }
    
    public enum CapType has copy, drop, store {
        Individual,                     // Uses UID address as identifier
        Package(address),               // Uses package address as identifier
    }
  7. Understand the PTB Move Call system in LayerZero V2

    main

    LayerZero V2 uses a dynamic Programmable Transaction Block (PTB) construction system for Sui. This system allows for runtime selection of protocol components (like message libraries and workers) that cannot be determined statically due to Move language limitations.

    It relies on two primary mechanisms:

    1. Dynamic PTB Generation: Builder modules expand high-level 'Builder Calls' into sequences of low-level 'Direct Calls' during an off-chain simulation phase.
    2. Global ID System: A mechanism to pass arguments between different PTB fragments (e.g., from a parent PTB to a child PTB produced by a builder) using unique identifiers.
  8. How Dynamic PTB Generation works

    main

    The PTB generation process follows a recursive expansion flow to resolve modular components into a single atomic transaction:

    1. Root PTB Construction: The developer creates an initial PTB containing direct calls and/or builder calls.
    2. Off-chain Simulation: Builder calls are routed to their respective component builders.
    3. PTB Expansion: Each builder produces a sequence of calls (which may include further builder calls).
    4. PTB Assembly: The calls produced by builders are combined into the root PTB.
    5. Recursive Expansion: This process repeats until all builder calls are resolved into direct calls.
    6. Blockchain Submission: The final assembled PTB, containing only direct calls, is executed atomically on-chain.
  9. Understand the Call Module hot-potato pattern and lifecycle

    main

    The Call<Param, Result> object implements a hot-potato pattern to ensure mandatory resource handling. Because the object is non-droppable and follows linear typing, every call must reach a terminal state (destruction) to prevent resources from being lost or ignored.

    Lifecycle States and Transitions

    StateDescriptionValid OperationsEntry Condition
    ActiveCan create new child batches or be completednew_child_batch(), complete()Call creation or all children destroyed
    CreatingIn the process of creating child calls in current batchcreate_child()After new_child_batch() called
    WaitingBatch finalized, waiting for children to be destroyeddestroy_child()After create_child() with is_last=true
    CompletedHas result, ready for destructiondestroy()After complete() called with result

    Coordination Rules

    • FIFO Child Destruction: Child calls must be destroyed in the order they were created (First-In, First-Out).
    • Batch Completion: All children in a batch must be destroyed before the parent call can return to the Active state.
    • Sequential Batches: A new batch can only be initiated when the call is in the Active status.
    • Authorization: Every operation (creation, completion, destruction) requires the appropriate CallCap object for access control.
  10. How the Call Module enables dynamic cross-contract coordination in Sui Move

    main

    The Call Module provides a way to perform dynamic dispatch in the Sui Move VM, which otherwise requires all function calls to be statically resolved at compile time. It uses a hot-potato pattern to allow a contract to select a target module at runtime and invoke it without having a compile-time dependency on that module.

    Key Capabilities

    • Runtime Library Selection: Choose which module to interact with based on runtime configuration (e.g., selecting a specific Message Library).
    • Extensible Architecture: Integrate new modules without upgrading or modifying existing dependent contracts.
    • Type-Safe Generics: Uses Move's type system with <Param, Result> parameters to ensure that parameters passed to the callee and results returned to the caller are type-safe.
    • Hierarchical Workflows: Supports complex, multi-level coordination where a call can trigger child calls in batches (parallel or sequential).
    // Runtime target determination with compile-time safety
    let call = call::create<SendParams, Receipt>(
        &caller_cap,
        resolve_library_address(config),  // Runtime resolution
        false,                            // Bidirectional communication
        send_params,
        ctx
    );
    
    // ... call flows to selected library ...
    
    // Type-safe parameter passing and result collection
    call.complete(&library_cap, receipt);
    
    // Guaranteed result extraction
    let (callee_addr, params, receipt) = call.destroy(&caller_cap);
  11. Understand the PTB Move Call Specification for IOTA

    main

    The PTB (Programmable Transaction Block) Move Call system is a dynamic construction mechanism for LayerZero V2 on IOTA. It solves the problem of runtime component selection (like choosing specific message libraries or workers) and cross-PTB argument passing in a language (Move) that typically requires static dispatch.

    It uses two primary mechanisms:

    1. Dynamic PTB Generation: Builder modules expand high-level "Builder Calls" into sequences of low-level "Direct Calls". This expansion can be recursive (nested).
    2. Global ID System: A system of unique identifiers that allows arguments to flow between different PTB fragments during the construction process before they are assembled into a single, atomic transaction.

    Execution Flow:

    1. Root PTB Construction: Developer defines a root PTB with direct or builder calls.
    2. Off-chain Simulation: Builder calls are routed to component builders.
    3. PTB Expansion: Builders produce call sequences (which may include more builder calls).
    4. PTB Assembly: All produced calls are combined into the root PTB.
    5. Recursive Expansion: The process repeats until only direct calls remain.
    6. Blockchain Submission: The final, fully expanded PTB is executed atomically on-chain.
  12. Build an Omnichain Application (OApp)

    main

    LayerZero V2 provides two primary contract standards for building omnichain applications located in the /oapp directory:

    • OApp (Omnichain Application): A generic message-passing interface used to send and receive arbitrary data between contracts on different blockchain networks. Use this for custom cross-chain logic.
    • OFT (Omnichain Fungible Token): A standard for transferring fungible tokens across multiple blockchains without the need for asset wrapping or middlechains.

    For implementation details, refer to the official OApp Quickstart and OFT Quickstart.