Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Counter

The smallest useful Cambrian entity: one member, three routes. Source of truth: contracts/counter.cam in the cambrian-lang repo.

Entity

entity Counter {

    routes {
        increment(amount: u64) => []
        reset() => []
        getCount() -> u64 => [
            return(m_count)
        ]
    }

    m_count: u64 {
        in increment(amount) => m_count + amount
        in reset() => 0
    }
}
  • increment / reset mutate state only — empty action lists.
  • getCount returns the current value; it has no member transform, so m_count is unchanged.
  • Transforms live next to the member they update, not inside the route body.

Companion fixtures

Same directory ships ready-made harnesses (Foundry / Lean pick them up when listed in a project or passed beside the entity):

FileRole
contracts/counter.test.camUnit tests: increment, reset, expect return, multi-step
contracts/counter.fuzz.camProperties + fuzz { amount in … } ranges; forall m_count: *
contracts/counter.invariant.camInvariants over increment / reset, incl. ctx { … } forall

Excerpt from the unit suite:

test "increment adds to count" for Counter with { m_count: 5 } {
    call increment(3)
    expect state { m_count: 8 }
}

test "getCount returns current" for Counter with { m_count: 99 } {
    call getCount()
    expect return 99
}

Property / fuzz:

property "increment from zero" (amount: u64) for Counter with { m_count: 0 } {
    call increment(amount)
    expect state { m_count: amount }

    fuzz { amount in 0..1000 }
}

Try it

cambrian-transpiler contracts/counter.cam -o /tmp/counter --target evm
# or Lean:
cambrian-transpiler contracts/counter.cam -o /tmp/counter-lean --target lean

See Unit Tests, Properties and Fuzz, and Invariants for the testing surface these companions exercise.