Docs Técnicas
Source Layout
A TREA source file contains one contract and may start with static imports.
A TREA source file contains one contract and may start with static imports.
import std.token.BasicToken
contract WalletLoan:
storage:
active: bool = False
@view
def is_active() -> bool:
return self.active
@tx
def activate():
self.active = TrueContract Declaration
contract Name:The name is part of artifact identity. Use stable, domain-specific names.
Imports
Static imports must appear before the contract declaration:
import std.token.BasicToken
import std.access.Roles as TokenRolesDynamic and wildcard imports are rejected.
Imports become active when the contract uses impl (see below). Each import path is recorded in the artifact for deterministic dependency identity — the imports_hash changes if the order or content of imports changes.
Composition
A contract can inherit storage and functions from one or more base modules:
import std.token.BasicToken
import std.access.Ownable
contract InstitutionToken impl BasicToken, Ownable:
storage:
balances: Map[Address, u128, 4096]
@tx
override def mint(amount: u128):
require(ctx.caller == self.owner, "only_owner")
self.balances[ctx.caller] = self.balances[ctx.caller] + amount
self.total = self.total + amountThe compiler flattens the module at compile time: base storage fields and functions are merged into the child in declaration order. See Composition for the full rules.
Storage Block
The storage: block declares persistent fields.
storage:
active: bool = False
owner: Address
balances: Map[Address, u128, 64]Storage appears before functions.
Functions
Functions are entrypoints and must be decorated:
@view
def read() -> u64:
return self.value
@tx
def write(value: u64):
self.value = valueSupported decorators:
@view: read-only entrypoint;@tx: transactional entrypoint.@construct: one-shot constructor that gates other entrypoints until it
succeeds.
@init is accepted as a compatibility alias for @construct, but new source should use @construct.
Statements
Supported statements:
return expr;let name[: Type] = expr;require(condition, "label");assert(condition, "label");fail("label");fail("label", "message");emit EventName(...);- assignment to
self.field; - assignment to
self.field[index]; if condition:with optionalelse:;- bounded
for.
Conditionals use the same indentation rules as loops. Conditions must be boolean values.
Indentation
TREA follows a Python-like indentation model. Keep four spaces per indentation level.
Comments
TREA supports # comments.
Use comments for:
PurposeGuardsStateLedger effectEventInvariantNotes
Recommended shape:
@tx
def approve():
# Purpose:
# Activate the pending loan request.
# Guards:
require(ctx.caller == self.lender, "only_lender")
# State:
self.active = True
# Ledger effect:
post(loan.origination_lines(ctx.asset, self.lender, self.borrower, self.requested_principal))
# Event:
emit LoanApproved(self.lender, self.borrower, self.requested_principal, self.rate_ppm)Prefer comments that explain intent, accounting meaning, or invariants. Do not narrate obvious assignments line by line.