Compose Smart-Contract Oriented Programming (SCOP)

website·Indexed 32 days ago

https://compose.diamonds

A framework for building composable smart contract systems using Smart-Contract Oriented Programming (SCOP). Compose utilizes diamond contracts (ERC-2535) to replace source-code inheritance with on-chain composition, employing a library of reusable facets and Solidity modules to create modular, readable, and interoperable on-chain infrastructure.

Tokens
17.1K
Snippets
46
Records
140
Agent score
60%

What's inside Compose

  1. Overview of Compose and Smart Contract Oriented Programming (SCOP)

    Compose is a smart contract library designed for ERC-2535 Diamonds, implementing a paradigm called Smart Contract Oriented Programming (SCOP). It emphasizes code clarity, reusability, and on-chain composability by favoring composition over inheritance—combining deployed facets rather than inheriting contracts. The project is currently in an early stage and is not yet production-ready.
  2. Overview of Smart-Contract Oriented Programming (SCOP)

    Smart-Contract Oriented Programming (SCOP) is a paradigm that treats smart contracts as a system of composable, stateless logic components rather than isolated monolithic programs. Key principles include:

    • Readability as Design: Code is written for long-term auditability and trust, ensuring developers and auditors can understand component roles and system integration.
    • Native On-Chain Composition: Deployed contracts are treated as infrastructure that can be referenced and executed on-chain without relying on off-chain coordinators.
    • Architectural Reuse: Reuse is achieved by designing components with clear interfaces and predictable boundaries, allowing them to serve as shared on-chain infrastructure.
    • Independent Evolution: Clear boundaries allow individual parts of a system to be added, replaced, or removed without redeploying the entire application.
    • Flexible Immutability: Systems can be designed to be upgradeable during development and transitioned to an immutable state once stability is reached.
  3. Overview of Smart Contract Oriented Programming (SCOP)

    Smart Contract Oriented Programming (SCOP) is a development paradigm for building modular on-chain applications as composed systems rather than isolated deployments. It treats reusable logic, application identity, shared state, and lifecycle management as explicit parts of the system design.

    SCOP is implemented via a composition layer using diamond-native architecture:

    • Diamonds: Act as the application container.
    • Facets: Provide reusable deployed functionality.
    • Modules: Support storage access, initialization, and internal extension helpers.
  4. Best practices for managing ownership in OwnerDataMod

    To maintain security and accurate event logging in the diamond architecture:

    1. Initialization: Call setContractOwner only from trusted initialization paths.
    2. Transfers: For transferring ownership, use OwnerTransferMod.transferOwnership or an equivalent facet to ensure events correctly record the previous owner.
    3. Access Control: Guard all external entrypoints that perform restricted state changes with requireOwner().
  5. Compose CLI project structure

    The CLI follows a modular architecture. Key directories include src/modules for feature logic (init, info, validation), src/pipelines for execution flow, and src/adapters for dependency management. The entry point is src/index.ts and argument parsing is handled in src/comander.ts.
    cli/
    ├── src/
    │   ├── adapters/        # Dependency adapters
    │   ├── context/         # Shared context
    │   ├── modules/         # Feature modules (init, info, validation, etc.)
    │   ├── pipelines/       # Execution pipelines
    │   ├── resolver/        # Dependency resolution
    │   ├── templates/       # Local template files
    │   ├── utils/           
    │   ├── comander.ts      # CLI argument parsing
    │   └── index.ts         # Entrypoint
    ├── bases/               # Base preset configurations
    ├── bin/                 # CLI executable
  6. Understand Diamond Contract architecture (ERC-2535)

    A diamond contract is a modular smart contract architecture defined by ERC-2535. Unlike traditional contracts, a diamond exists at a single address and holds all state storage, but delegates its logic to multiple separate contracts called 'facets'.

    Key characteristics include:

    • Single Address: Users interact with one address regardless of how many facets are attached.
    • Modular Logic: Functionality is split into small, focused facets.
    • Upgradability: Facets can be added, replaced, or removed after deployment without changing the diamond's address or redeploying the entire system.
    • Storage: The diamond itself maintains the data storage, while facets provide the logic to manipulate that data.
  7. Understand the Compose Testing Philosophy (BTT)

    Compose uses a behavior-first testing approach called Behavior Tree Testing (BTT). The source of truth for expected behavior is defined in specification files located in test/trees/*.tree. Key principles include:

    • Maintaining parity between facet surfaces and modifier/module behavior.
    • Ensuring no test-only code (getters or hooks) is added to production contracts in src/.
    • Using behavior-oriented naming for tests that mirror the structure of the behavior trees.
  8. Understand and use Solidity Modules for code reuse

    Solidity modules are files containing reusable logic (functions, constants, structs, events, enums, errors, and interfaces) where the top-level code lives outside of contracts and libraries. Unlike contracts or libraries, modules produce no standalone bytecode and are never deployed on-chain; instead, their code is included into the bytecode of any contract that imports them at compile time.

    Key benefits include:

    • Clean Code Reuse: Avoids duplication and complex inheritance chains.
    • Gas Efficiency: Since module functions are internal, the compiler can inline them or use cheap JUMP calls, avoiding the overhead of external calls or library deployments.
  9. Manage diamond facets with DiamondUpgradeMod

    DiamondUpgradeMod provides a suite of functions to mutate a diamond's selector routing and facet list. It interacts with the diamond's shared storage located at DIAMOND_STORAGE_POSITION (defined as keccak256("erc8153.diamond")). Changes made via these functions are immediately visible to the diamond and all facets accessing shared storage.
  10. Compose CLI Modular Architecture Overview

    The Compose CLI uses a pipeline-oriented modular architecture to ensure components are replaceable and extensible. The architecture consists of four primary concepts:

    • Context (ctx): A shared object that carries command parameters, configuration, module state, and execution status through the workflow.
    • Pipelines: Orchestrators that define workflows, coordinate module execution, resolve adapters, and manage control flow.
    • Modules: Implementations of focused CLI business logic.
    • Adapters: Isolation layers for external tools, frameworks, libraries, APIs, and runtime-specific behavior.

    Component Relationships:

    • Pipelines decide which modules run.
    • Modules handle feature logic and use adapters for external tooling.
    • Shared context allows each step to understand the output of previous steps. Module changes must preserve existing ctx.state fields to avoid breaking subsequent steps.
  11. Inspect diamond facet mappings with DiamondInspectFacet

    The DiamondInspectFacet allows external tools and indexers to analyze the structure of a Diamond contract. It provides methods to resolve which facet handles a specific function selector and to list all registered facets and their exported functions.
  12. Understand Diamond Proxy architecture

    In a Diamond architecture, the Diamond.sol proxy serves as the application entry point. It holds the storage state but contains no business logic. All calls are delegated to stateless 'facets' via a fallback function. Specifically, DiamondMod.diamondFallback() identifies the contract owning the function selector and forwards the call to that facet.