Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Module Architecture

The Evolve module system uses an account-centric model where every piece of application logic is an account.

Core Components

┌─────────────────────────────────────────────────────────────┐
│                      State Transition Function (STF)         │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │                      ExecutionState                      │ │
│  │  - Overlay (write cache)                                 │ │
│  │  - Undo log (for rollback)                              │ │
│  │  - Events                                                │ │
│  └─────────────────────────────────────────────────────────┘ │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │                        Invoker                           │ │
│  │  - Implements Environment/EnvironmentQuery               │ │
│  │  - Manages call stack (max depth: 64)                   │ │
│  │  - Handles fund transfers                                │ │
│  └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘

Lifecycle Hooks

Modules can implement lifecycle traits:

pub trait BeginBlocker<B> {
    fn begin_block(&self, block: &B, env: &mut dyn Environment);
}
 
pub trait EndBlocker {
    fn end_block(&self, env: &mut dyn Environment);
}
 
pub trait TxValidator<Tx> {
    fn validate_tx(&self, tx: &Tx, env: &mut dyn Environment) -> SdkResult<()>;
}
 
pub trait PostTxExecution<Tx> {
    fn after_tx_executed(
        tx: &Tx,
        gas_consumed: u64,
        tx_result: Result<...>,
        env: &mut dyn Environment,
    ) -> SdkResult<()>;
}

Resource Limits

LimitValuePurpose
Max call depth64Prevent stack overflow
Max overlay entries100,000Memory bound
Max events10,000Memory bound
Max key size254 bytesStorage efficiency
Max value size1 MBStorage efficiency

State Management

Checkpoint/Restore

Every do_exec call creates a checkpoint:

let checkpoint = state.checkpoint();
 
match execute_call() {
    Ok(result) => result,
    Err(e) => {
        state.restore(checkpoint)?;  // Rollback all changes
        return Err(e);
    }
}

Storage Isolation

Each account's storage is prefixed by its AccountId:

[AccountId][FieldPrefix][Key] => Value