Cycle

The Scriptorium

Smart Assembly code templates and tools for on-chain development in Eve Frontier.

Building Your First Gate
IntermediateChapter 1 of 415 min read

Gate Architecture

Smart Gates are the most common Smart Assembly in Eve Frontier. They control access between solar systems and are a perfect first real-world project.

How Gates Work

A Smart Gate is a pair of linked assemblies — one in each solar system. When a player interacts with a gate, the system checks:

  • Is the player allowed? — Access control rules
  • Can the player afford the toll? — Fee collection
  • Is the gate active? — Operational status
  • solidity
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.24;
    
    import { System } from "@latticexyz/world/src/System.sol";
    import { GateConfig } from "../codegen/tables/GateConfig.sol";
    import { GateAccess } from "../codegen/tables/GateAccess.sol";
    
    contract GateSystem is System {
      error GateNotActive(uint256 gateId);
      error AccessDenied(uint256 gateId, address player);
      error InsufficientToll(uint256 gateId, uint256 required, uint256 provided);
    
      function useGate(uint256 gateId) public payable {
        // Check gate is active
        if (!GateConfig.getIsActive(gateId)) {
          revert GateNotActive(gateId);
        }
    
        // Check access
        address player = _msgSender();
        if (!_hasAccess(gateId, player)) {
          revert AccessDenied(gateId, player);
        }
    
        // Check toll
        uint256 toll = GateConfig.getToll(gateId);
        if (msg.value < toll) {
          revert InsufficientToll(gateId, toll, msg.value);
        }
    
        // Record usage
        GateAccess.set(gateId, player, block.timestamp);
      }
    }

    Table Design

    We need two tables for our gate:

    typescript
    // mud.config.ts
    export default mudConfig({
      tables: {
        GateConfig: {
          keySchema: { gateId: "uint256" },
          valueSchema: {
            owner: "address",
            linkedGateId: "uint256",
            toll: "uint256",
            isActive: "bool",
            accessMode: "uint8", // 0=public, 1=whitelist, 2=tribe-only
          },
        },
        GateAccess: {
          keySchema: {
            gateId: "uint256",
            player: "address",
          },
          valueSchema: {
            lastUsed: "uint256",
          },
        },
      },
    });

    Access Modes

    We'll support three access modes:

    ModeValueDescription
    Public0Anyone can use the gate
    Whitelist1Only approved addresses
    Tribe Only2Only members of the owner's tribe

    In the next chapter, we'll implement the access control logic.

    Sign in to track your progress.