Fundamentals

Chapter 2 / 15

Fields and Storage

Every primitive type, plus arrays and maps.


Covenant's type system maps cleanly to EVM storage slots while adding semantic types that prevent common mistakes — for example, using amount instead of u256 for ether values makes units explicit.

storage_types.cov
record Catalog {
    // Semantic primitives
    owner:      address;
    balance:    amount;       // wei — prevents unit confusion
    created:    time;         // unix timestamp
    lock_for:   duration;     // seconds
    checksum:   hash;         // bytes32

    // Text
    name:       text;

    // Integer widths
    small:      u8;
    counter:    u64;
    big:        u256;
    signed_val: i256;

    // Boolean
    active:     bool;

    // Fixed-size array (max 32 entries)
    tags:       [text; 32];

    // Dynamic map
    deposits:   map(address => amount);

    // Nested map
    allowances: map(address => map(address => amount));
}
Reading and writing fields
record Counter {
    count: u64;
    owner: address;

    action increment() only(self.owner) {
        self.count += 1;
    }

    action reset() only(self.owner) {
        self.count = 0;
    }

    view get() -> u64 {
        return self.count;
    }
}

Annotations

amountcompiles to uint256 but the compiler rejects arithmetic that mixes amounts with bare integers.
time / durationprevent accidental subtraction of timestamps and durations — the compiler enforces dimensional compatibility.
map(K => V)compiles to a Solidity mapping; nested maps compile to nested mappings.
[T; N]is a fixed-size array stored packed into adjacent slots when possible.

Key takeaways