Docs Técnicas
Contract Events
TREA contracts emit events via emit EventName(arg1, arg2, ...). After a ContractCall transaction is committed, the emitted events are available through the events endpoint.
TREA contracts emit events via emit EventName(arg1, arg2, ...). After a ContractCall transaction is committed, the emitted events are available through the events endpoint.
POST /api/transaction (ContractCall with emit Transfer(...))
→ ledger commits effects
→ event log updated
GET /api/contracts/:id/events → events list with topics and decoded argsEvents are an audit annotation on the execution output — they do not affect storage, postings, or accounting state.
Endpoint
`GET /api/contracts/:contract_id/events`
Returns events emitted by a deployed contract instance.
Query parameters:
| Param | Type | Description | | ----- | ---- | ----------- | | name | string | Filter by event name (Transfer, Approval, …) | | address | string | Filter events where any Address argument matches | | from_block | u64 | Inclusive lower bound on block height | | to_block | u64 | Inclusive upper bound on block height | | limit | u64 | Max events to return (default 100, max 1000) |
Response:
{
"contract_id": "my-token-001",
"total": 2,
"events": [
{
"contract_id": "my-token-001",
"tx_id": "tx-abc123",
"block_height": 42,
"block_timestamp": 1700000000,
"name": "Transfer",
"topic": "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"args": ["wallet:alice", "wallet:bob", "1000"]
}
]
}The topic field is the full 32-byte keccak256 hash of the canonical Ethereum event signature (e.g. Transfer(address,address,uint256)). It matches the topic0 that Ethereum indexers expect. Unknown event shapes return an empty topic string.
Supported topics
| Event | Signature | Topic (keccak256) | | ----- | --------- | ----------------- | | Transfer | Transfer(address,address,uint256) | ddf252ad…b3ef | | Approval | Approval(address,address,uint256) | 8c5be1e5…1173 | | LoanApproved | LoanApproved(address,address,uint256,uint256) | derived |
Any other event is returned with "topic": "" — the args are still available for custom indexers.
Declaring events in TREA
Events must be declared with @event before they can be emitted:
contract MyToken:
@event
def Transfer(from: Address, to: Address, amount: u128):
pass
@event
def Approval(owner: Address, spender: Address, amount: u128):
pass
@tx
def transfer(to: Address, amount: u128) -> bool:
require(amount != 0, "invalid_amount")
self.balances[ctx.caller] = self.balances[ctx.caller] - amount
self.balances[to] = self.balances[to] + amount
emit Transfer(ctx.caller, to, amount)
return TrueDesign notes
- In-memory log. The event log lives in the ledger's in-memory
State. It resets
on node restart. Indexers should treat it as a cache — authoritative history lives in the transaction receipts and AEC segments, which are persisted to disk.
- Not a substitute for receipts. Events are audit annotations. For balance
reconstruction, use the accounting ledger or GET /api/aec/:account — not events.
- Cross-contract. Events emitted by sub-contracts during a cross-contract call are
attributed to the top-level contract_id of the originating ContractCall transaction.
- Filtering. The
addressfilter matches anyAddress-typed argument in the event.
For Transfer, this catches both from and to in a single query.
Using with an indexer
// Poll for new Transfer events since last known block
const res = await fetch(
`/api/contracts/${contractId}/events?name=Transfer&from_block=${lastBlock + 1}`
);
const { events } = await res.json();
for (const ev of events) {
const [from, to, amount] = ev.args;
console.log(`Transfer: ${from} → ${to} (${amount})`);
// topic matches Ethereum topic0 for Ethereum-compatible indexers
console.log(`topic0: 0x${ev.topic}`);
}For wallets that need all events touching a specific address:
const res = await fetch(
`/api/contracts/${contractId}/events?address=${walletAddress}`
);