Skip to content
Pre-Release: Fe is under active development. This documentation covers the upcoming release. Follow progress on GitHub

Standard Library Effects

Fe’s standard library provides effect traits for common EVM operations. These are available via the prelude — no imports needed.

The Ctx trait provides read-only access to the EVM execution environment:

fn get_caller() -> Address uses (ctx: Ctx) {
ctx.caller()
}
fn get_block() -> u256 uses (ctx: Ctx) {
ctx.block_number()
}

Available methods on Ctx:

MethodReturnsDescription
caller()AddressMessage sender
address()AddressContract’s own address
value()u256Ether sent with the call
timestamp()u256Current block timestamp
block_number()u256Current block number

The Log trait allows emitting EVM log events. It requires mut because emitting is a side effect:

#[event]
struct Transfer {
#[indexed]
from: Address,
#[indexed]
to: Address,
value: u256,
}
fn emit_transfer(from: Address, to: Address, value: u256) uses (log: mut Log) {
log.emit(Transfer { from, to, value })
}

The emit() method works with any struct marked #[event].

Under the hood, Ctx and Log are traits. The struct that implements them all is Evm. When you write uses (ctx: Ctx), the contract’s Evm instance satisfies that requirement.

Evm implements: Ctx, Log, RawMem, RawStorage, RawOps, Create, Call.

In tests, you interact with Evm directly:

#[test]
fn test_with_evm() uses (evm: mut Evm) {
let addr = evm.create2<Example>(value: 0, args: (), salt: 0)
assert(addr.inner != 0)
}

Any type — struct, trait, or enum — can serve as an effect. The standard library effects are not special; they follow the same rules as user-defined effects. See Storage as Effects for the most common pattern: using your own structs as effects in contracts.

Here is a non-storage example — injecting validation logic as an effect:

pub struct RangeValidator {
pub min: u256,
pub max: u256,
}
impl RangeValidator {
pub fn is_valid(self, value: u256) -> bool {
value >= self.min && value <= self.max
}
}
fn validate(value: u256) -> bool uses (v: RangeValidator) {
v.is_valid(value)
}
#[test]
fn test_custom_effect() {
let validator = RangeValidator { min: 10, max: 100 }
let result = with (validator) {
validate(50)
}
assert(result == true)
let result2 = with (validator) {
validate(5)
}
assert(result2 == false)
}
EffectTypePurpose
CtxTrait (std)Execution environment (caller, block info)
LogTrait (std)Event emission
EvmStruct (std)Root effect implementing all EVM traits
CustomAny typeWhatever capability your code needs