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

Accounts

Everything in Evolve is an account. This account-centric model is the foundation of the entire system.

What is an Account?

An account has three components:

ComponentDescription
IdentityUnique AccountId (u128)
CodeImplementation of the AccountCode trait
StateIsolated storage namespace

The AccountCode Trait

Every account implements the AccountCode trait:

pub trait AccountCode: Send + Sync {
    fn execute(
        &self,
        env: &mut dyn Environment,
        request: InvokeRequest,
    ) -> SdkResult<Vec<u8>>;
 
    fn query(
        &self,
        env: &dyn EnvironmentQuery,
        request: InvokeRequest,
    ) -> SdkResult<Vec<u8>>;
}

The #[account_impl] macro generates this implementation for you.

System Accounts

Reserved AccountId values with special behavior:

IDNamePurpose
0RUNTIME_ACCOUNT_IDAccount creation, migrations
1STORAGE_ACCOUNT_IDStorage read/write operations
2EVENT_HANDLER_ACCOUNT_IDEvent emission
5UNIQUE_HANDLER_ACCOUNT_IDUnique ID generation

System accounts have hardcoded handlers in the invoker.

Inter-Account Calls

Accounts communicate through message passing:

// Account A calls Account B
env.do_exec(account_b_id, &message, funds)?;
 
// Internally:
// 1. Invoker creates checkpoint
// 2. Funds are transferred (if any)
// 3. Account B's code executes
// 4. On error: checkpoint restored
// 5. On success: changes committed

Message Dispatch

The #[account_impl] macro generates:

  1. Message structs for each function
  2. Function IDs from SHA-256 of function name
  3. Dispatch logic in AccountCode::execute/query

Storage Isolation

Each account's storage is prefixed by its AccountId:

[AccountId][FieldPrefix][Key] => Value
 
Example:
[0x0A][0x01][alice] => 1000  // Account 10, field 1, key "alice"

This prevents accounts from accidentally (or maliciously) accessing each other's state.