testnet
GitHub

Contract Architecture & Build System

developer external-dapp

A unified system for compiling and managing Solidity contracts scattered across the Maroo monorepo.

Maroo utilizes a monorepo structure where smart contracts, particularly interfaces for precompiles, are co-located with their corresponding Go modules. The Contract Build System provides the necessary tooling to manage this distributed layout. It uses a centralized Hardhat project as a compilation engine, orchestrated by a Python script that gathers source files, compiles them, and distributes the build artifacts back to their original locations, ensuring that Go modules always have access to the latest contract ABIs.

Key Features

Centralized Compilation

Uses a single Hardhat project to manage dependencies and compiler versions, ensuring consistency across all contracts.

Artifact Co-location

Automatically places compiled JSON artifacts (ABI, bytecode) next to their source Solidity files, making them easily accessible to Go modules.

Automated Workflow

A single Python script handles discovery, aggregation, compilation, and distribution, simplifying the developer workflow.

Selective Compilation

Supports full recompiles, cleaning of artifacts, and recompiling a single contract to speed up development cycles.

Architecture

graph TD
    subgraph Maroo Monorepo
        A[precompiles/okrw/IOkrw.sol] --> C{compile_smart_contracts.py};
        B[precompiles/pcl/IPcl.sol] --> C;
        D[other/module/Contract.sol] --> C;
    end

    subgraph Compilation Process
        C -- 1. Copy sources --> E[contracts/solidity/];
        E -- 2. Invoke --> F[Hardhat Compiler];
        F -- 3. Generate --> G[contracts/artifacts/];
    end

    subgraph Artifact Distribution
        G -- 4. Copy back --> H[precompiles/okrw/abi.json];
        G -- 5. Copy back --> I[precompiles/pcl/abi.json];
        G -- 6. Copy back --> J[other/module/Contract.json];
    end

    subgraph Go Modules
      K[x/okrw module] -- reads --> H;
      L[x/pcl module] -- reads --> I;
    end

Overview of the Maroo contract compilation and artifact distribution flow.

Contract Discovery and Aggregation

The build process begins with the compile_smart_contracts.py script scanning the entire repository for Solidity (.sol) files. It specifically targets contracts located within module directories, with a primary focus on those under the precompiles/ path. The script intelligently ignores irrelevant files, such as third-party libraries in node_modules, Foundry tests (*.t.sol), and other non-essential contracts.

Once discovered, all relevant Solidity files are copied into a centralized directory: contracts/solidity/. This aggregation step is crucial because it allows Hardhat to treat all scattered contracts as part of a single, coherent project. This simplifies dependency management and ensures that a consistent version of the Solidity compiler and its settings are applied to every contract.
Note: The script maintains the original directory structure of the copied files within `contracts/solidity/` to prevent naming conflicts and preserve logical separation.

Compilation with Hardhat

After aggregating the source files, the script invokes the Hardhat compilation task (npx hardhat compile) on the contracts/ directory. Hardhat resolves all imports, downloads any necessary dependencies (e.g., OpenZeppelin contracts) via npm or yarn, and compiles the Solidity code into EVM bytecode and Application Binary Interfaces (ABIs).

The output of this process is stored in the contracts/artifacts/ directory. Each compiled contract generates a corresponding JSON file containing its ABI, bytecode, deployment information, and other metadata. This artifact is the canonical, machine-readable representation of the smart contract.

Artifact Distribution and Usage

The final and most critical step is the distribution of these compiled artifacts. The script iterates through the generated JSON files in contracts/artifacts/ and copies each one back to the original source directory of its corresponding .sol file. For example, the artifact for precompiles/okrw/IOkrw.sol is copied back to precompiles/okrw/.

This co-location of the source code and its ABI is a key design pattern in Maroo. It allows the Go modules that implement the precompiles (e.g., the x/okrw module) to directly read the abi.json file. This ABI is then used to pack and unpack function arguments and return values, ensuring seamless communication between the Go-based Cosmos SDK logic and the EVM. This tight integration removes the need for manual ABI updates and reduces the risk of mismatches between the Solidity interface and the Go implementation.

Next Steps

Source: maroo
ESC
Type to search