Skip to main content
This page provides development guidance for building LayerZero applications on IOTA, covering toolchain setup, operational practices, and technical constraints.

Toolchain Setup

IOTA CLI

Tested Version: iota@v1.54.1 Install the IOTA CLI:
Verify installation:

Project Structure

Typical IOTA Move project structure:

Move.toml Configuration

For package structure details:

Development Environment

Building Contracts

Running Tests

Local Development

Start a local IOTA network:

Deployment

Deploying to Testnet

Deploying to Mainnet

Deployment Script Example

Operational Practices

Package Upgrades

IOTA packages are immutable by default but can be made upgradeable. UpgradeCap: Owned object granting upgrade authority
Transfer Upgrade Authority:
Upgrade a Package:
Key Point: Upgraded packages maintain compatibility with objects created by previous versions, provided you follow IOTA’s upgrade policies.

Capability Management

LayerZero uses multiple capability objects: For OApp/OFT Packages:
  • CallCap: Authorizes creating Call objects (usually stored in package module)
  • AdminCap: Authorizes admin operations (transfer to new admin as needed)
  • MigrationCap: Authorizes migrating OApp/OFT to new implementations (store securely)
  • TreasuryCap<T>: Authorizes minting/burning coins (for OFT mint/burn type)
  • UpgradeCap: Authorizes package upgrades (transfer with caution)
Transfer Pattern:
No Safe Transfer: IOTA doesn’t have EVM’s safeTransfer callback. Transfers are direct:

Multisig Patterns

For multi-party control, use:
  1. IOTA Multisig Addresses: Native 1-of-n or k-of-n multisig
  2. Shared Control Objects: Create a shared configuration object requiring multiple approvals
  3. Third-Party Solutions: IOTA Wallet multisig, protocol-specific multisig
Example using address derivation:

Resource & Fee Models

See IOTA Gas Model for complete details.

Storage Gas

Charged for storing data onchain:

Computation Gas

Charged for execution:

Rebate Mechanism

When storage is freed, gas is refunded:
Important: This can result in negative gas utilization for net storage reduction.

Base Budget

Every transaction requires a minimum of 1000 gas units, even if net cost is negative due to rebates.

Technical Constraints

Package Size Limit

Maximum size per package: 250 KiB If your package exceeds this:
  • Split into multiple packages
  • Reduce unused code
  • Optimize data structures

Transaction Size Constraints

See IOTA Transaction Limits:
  • Max objects per transaction: 256
  • Max events per transaction: 1024
  • Max argument size: 128 KB

Compute Limits

Gas limits vary by network:
  • Testnet: Lower limits
  • Mainnet: Higher limits
For LayerZero operations, budget at least:
  • Simple send: 5,000,000 gas
  • Complex send: 20,000,000 gas
  • Receive: 10,000,000 gas

Network Resource Limits

Monitor these limits:
  • Object count per address: Unlimited, but impacts query performance
  • Storage per address: Unlimited, but costs scale linearly
  • Transaction throughput: ~5,000 TPS (network-wide)

Network Considerations

Finality

IOTA uses a checkpoint-based finality system:
  • Soft finality: Certificate of transaction (milliseconds)
  • Hard finality: Checkpoint inclusion (~2-3 seconds)
For LayerZero verification, DVNs wait for checkpoint finality.

RPC Infrastructure

Public RPCs:
  • Mainnet: https://fullnode.mainnet.iota.io:443
  • Testnet: https://fullnode.testnet.iota.io:443
  • Devnet: https://fullnode.devnet.iota.io:443
Private RPC Providers:
  • Ankr
  • QuickNode
  • Blast API
For production, use private RPCs for better reliability and rate limits.

Channel Management

Recovery Methods

LayerZero provides recovery methods for stuck messages:
Authorization: All recovery methods require the AdminCap object.

Querying State with TypeScript SDKs

The IOTA CLI has limitations for querying state. Use TypeScript SDKs instead:

IOTA CLI Limitations

The IOTA CLI cannot easily:
  • Parse complex return values from view functions
  • Handle nested data structures
  • Decode bytes arrays
Workaround: Use the TypeScript SDK for all state queries.

Best Practices

1. Test Thoroughly

2. Monitor Gas Usage

3. Handle Rebates Correctly

4. Version Your Packages

5. Secure Your Keys

Common Gotchas

1. Negative Gas Utilization

When storage is freed, transactions can have negative net gas cost. Budget at least 1000 base units.

2. Package Size Exceeded

Error: Package size exceeds maximum Solution: Split into multiple packages or optimize code.

3. Object Ownership Errors

Error: Invalid object ownership Solution: Verify object is owned by signer or is shared.

4. Insufficient Gas

Error: Insufficient gas Solution: Increase --gas-budget parameter.

Additional Resources

Next Steps