Contract Architecture & Build System
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
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.Compilation with Hardhat
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
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.