On-chain Modules (Web3)
Relevant source files
The following files were used as context for generating this wiki page:
On-chain modules in Sploosh provide a dedicated surface for authoring smart contracts that target blockchain environments such as the Ethereum Virtual Machine (EVM) and Solana SBF (SVM). These modules allow developers to write on-chain logic using the same safety-first syntax as native Sploosh code, while the compiler enforces strict prohibitions against non-deterministic operations, float mathematics, and host IO (file systems, network, or actors).
The system is designed for "dual-target" compilation, enabling a single source tree to target native, WASM, EVM, and SVM backends. On-chain modules feature Solidity-compatible storage layouts, built-in reentrancy guards, and specific Web3 primitives for cross-contract calls and event emission.
Sources: README.md:6-10, VISION.md:8-13, VISION.md:86-90
Architecture and Core Components
On-chain modules are defined using the onchain mod keyword. Unlike standard modules, these are subject to specialized compile-time checks and runtime behaviors tailored for decentralized ledgers.
On-chain Module Structure
An on-chain module typically contains a storage block, public functions, and event definitions. The storage layout is intentionally compatible with Solidity to facilitate migration and interoperability.
The diagram above illustrates the internal structure of an on-chain module and its compilation targets.
Sources: README.md:68-83, VISION.md:86-95, crates/sploosh-parser/src/lib.rs:388-409
Key Language Primitives (Web3)
| Component | Description |
|---|---|
onchain mod | A module compiled for blockchain targets (EVM/SVM). Rejects floats, actors, and host IO. |
storage | A specialized block for defining persistent state; currently consumed but discarded by the bootstrap parser. |
u256 | A 256-bit unsigned integer type frequently used for balances and cryptographic operations. |
Address | A primitive type representing a blockchain account address. |
chain::call | The standard API for cross-contract calls, lowering to EVM CALL or Solana CPI. |
ctx::caller() | A context primitive returning the Address of the current transaction sender. |
Sources: VISION.md:86-98, README.md:73-81, crates/sploosh-parser/src/lib.rs:1049-1065
Safety and Security Models
Sploosh implements specific security protocols for the Web3 surface to prevent common vulnerabilities like reentrancy and integer overflows.
Reentrancy Protection
By default, all public functions in an onchain mod are protected by a global reentrancy guard. This is a runtime per-contract boolean flag set upon entry to any non-@reentrant function. Developers must explicitly opt-out of this protection using the @reentrant attribute.
This sequence diagram shows the default reentrancy guard mechanism applied to public on-chain functions.
Sources: VISION.md:99-104, SECURITY.md:65-70
Compile-time Prohibitions
The Sploosh compiler enforces "on-chain prohibitions" to ensure determinism and security. The following are strictly forbidden within an onchain mod:
- Float Math: No
f32orf64operations are allowed. - Concurrency: Actors,
spawn, andHandle<T>are prohibited. - Host IO: No access to
fs(file system),net(network), or environment variables. - Non-deterministic operations: Any operation that could produce different results on different nodes.
Sources: VISION.md:86-89, AGENTS.md:154-155, SECURITY.md:65-72
Data Handling and Storage
On-chain modules interact with state through a dedicated storage mechanism and communicate via events.
Storage Layout and Access
Storage is handled through storage::get and storage::set operations. The design philosophy emphasizes compatibility with existing standards like ERC-20 to allow migration from Solidity.
onchain mod token {
storage {
balances: Map<Address, u256>,
total_supply: u256,
}
pub fn transfer(to: Address, amount: u256) -> Result<(), TokenError> {
let sender = ctx::caller();
let bal = storage::get(&self.balances, sender)?;
// ... logic ...
storage::set(&mut self.balances, sender, bal - amount);
emit Transfer { from: sender, to, amount };
Ok(())
}
}
Sources: README.md:68-83, VISION.md:80-84
Attributes and Directives
Attributes are the primary way to provide metadata to the compiler for on-chain artifacts.
| Attribute | Scope | Purpose |
|---|---|---|
@payable | Function | Opts a function into receiving native blockchain value (e.g., ETH/SOL). |
@reentrant | Function | Opts a function out of the default per-contract reentrancy guard. |
#[target(evm)] | Module/Item | Directs the compiler to generate EVM-specific bytecode. |
#[indexed] | Event Field | Marks an event field for indexing in blockchain logs. |
Sources: VISION.md:99-104, AGENTS.md:151-153
Integration and Externals
Sploosh facilitates interaction with external contracts and native C libraries through extern blocks.
Cross-Contract Interaction
The extern onchain mod structure replaces manual ABI scaffolding. Developers define the interface of an external contract, and Sploosh generates the necessary call logic.
Extern Blocks
Functions defined within extern blocks are linked at compile time. In a Web3 context, these often represent system-level host functions provided by the blockchain environment.
extern "C" {
pub fn puts(s: &str);
}
extern onchain mod token {
pub fn balance_of(owner: Address) -> u256;
}
Sources: crates/sploosh-parser/src/lib.rs:411-428, crates/sploosh-parser/src/lib.rs:1143-1150
Conclusion
The on-chain module system in Sploosh provides a specialized, safe environment for Web3 development. By combining Rust-grade safety with built-in smart contract protections and a Solidity-compatible storage model, it aims to reduce the "footguns" typically associated with smart contract programming while maintaining high performance across both EVM and SVM targets.