03 — Actions, Events & Errors

Actions

Actions are the public interface of a contract — analogous to Solidity functions with visibility external.

contract Counter {
  field n: u256 = 0

  action increment() {
    self.n += 1;
    emit Incremented(self.n);
  }

  action increment_by(amount: u256) {
    require(amount > 0, InvalidAmount);
    self.n += amount;
    emit Incremented(self.n);
  }

  action value() -> u256 {
    return self.n;
  }
}

Read vs write: actions that only read state should be annotated @view:

@view
action value() -> u256 { return self.n; }

The compiler enforces that @view actions contain no state mutations.

Events

event Incremented(new_value: u256)
event Transfer(from: indexed Address, to: indexed Address, amount: u256)

indexed fields become Bloom-filter topics (up to 3 per event, same as Solidity). The ABI encoder emits them as event Transfer(address indexed from, address indexed to, uint256 amount).

Emit syntax:

emit Transfer(from: sender, to: recipient, amount: value);

Errors

Typed errors revert with ABI-encoded data:

error InvalidAmount(provided: u256)
error Unauthorised(caller: Address)
error InsufficientBalance(available: u256, requested: u256)

Revert with an error:

require(amount > 0, InvalidAmount(amount));
// or imperatively:
if self.balances[caller] < amount {
  revert InsufficientBalance(self.balances[caller], amount);
}

require vs revert

KeywordBehaviour
require(cond, Err)Reverts with Err if cond is false
revert Err(..args)Unconditionally reverts
assert(cond)Reverts with Panic(0x01) — use for invariants only