Chapter 3 / 15
Actions, Events & Errors
emit, transfer, revert_with — the full action vocabulary.
Actions in Covenant carry four responsibilities: validate inputs, update state,
emit events, and transfer value. Covenant's revert_with attaches
typed error payloads — readable by any ABI-aware client without extra decoding.
bank.cov
record Bank {
balances: map(address => amount);
// Named events
event Deposited(who: address, value: amount);
event Withdrawn(who: address, to: address, value: amount);
// Typed errors
error InsufficientFunds(requested: amount, available: amount);
error ZeroTransfer();
action deposit() {
let val = msg.value;
if val == 0 {
revert_with ZeroTransfer();
}
self.balances[msg.sender] += val;
emit Deposited(msg.sender, val);
}
action withdraw(to: address, value: amount) {
let avail = self.balances[msg.sender];
if value == 0 {
revert_with ZeroTransfer();
}
if value > avail {
revert_with InsufficientFunds(value, avail);
}
// Checks-Effects-Interactions order
self.balances[msg.sender] -= value;
emit Withdrawn(msg.sender, to, value);
transfer(to, value);
}
view balance_of(who: address) -> amount {
return self.balances[who];
}
}Annotations
event | declares a log event with named, typed fields. The ABI selector is derived automatically. |
error | declares a typed revert payload — EIP-838 compatible. Arguments are ABI-encoded into revert data. |
revert_with E(...) | reverts the transaction and encodes the error payload. Equivalent to Solidity's revert E(...). |
msg.value | the ether attached to the call, as an amount. |
transfer(to, value) | sends ether using call{value: v}('') with a forward-gas cap. Reverts on failure. |
Key takeaways
- Events and errors are declared at the record level — they are part of the contract's public ABI.
revert_withalways carries a typed payload; barerevertis not idiomatic Covenant.- Follow Checks-Effects-Interactions order — update state before calling
transfer().