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
amount | compiles to uint256 but the compiler rejects arithmetic that mixes amounts with bare integers. |
time / duration | prevent 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
- Semantic types (
amount,time,duration) prevent an entire class of unit bugs at compile time. - Maps and arrays have familiar syntax but compile to efficient EVM layouts.
- Field initialization to zero is implicit — no constructor boilerplate needed.