Endpoints and Functions
Endpoints are externally callable entry points of a Coco logic. Functions are local helpers called from endpoints.
Endpoint Syntax
endpoint [qualifier] Name(inputs) -> (outputs):
body
Example:
endpoint dynamic PurchaseTicket(quantity U64) -> (receipt_id String):
// implementation
Qualifiers
Lifecycle Qualifiers
| Qualifier | Purpose |
|---|---|
deploy | Runs once when logic is deployed (logic constructor) |
enlist | Runs once per user on first interaction (actor constructor) |
| (none) | Standard endpoint, callable anytime |
State Qualifiers
| Qualifier | Access | Required when |
|---|---|---|
pure | No state access | Default — no state operations |
static | Read-only | Using observe |
dynamic | Read & write | Using mutate |
endpoint pure Calculate(x U64) -> (result U64):
result = x * 2
endpoint static GetBalance() -> (balance U64):
observe balance <- Token.Sender.balance
endpoint dynamic Transfer(to Identifier, amount U64):
mutate bal <- Token.Sender.balance:
bal -= amount
Inputs and Outputs
All parameters must be named for clarity:
// Named inputs and outputs
endpoint Transfer(
recipient Identifier,
amount U64
) -> (
success Bool,
new_balance U64
):
// ...
Why Named Parameters?
Looking at Transfer(recipient, amount) is clearer than Transfer(id, u64). You know what each value represents.
Functions
Functions are local helpers that can only be called from within the same logic.
function Double(num U64) -> (result U64):
result = num * 2
| Feature | endpoint | function |
|---|---|---|
| Called from | Blockchain (external) | Endpoints (internal) |
| Purpose | Public interface | Reusable helper |
Can use deploy/enlist | Yes | No |
| Can call other endpoints | No | N/A |
Calling Functions
endpoint Calculate():
// Full syntax: capture return value
memory x = (result) <- Double(num: 10)
// Shortcut: same variable name as parameter
memory num = 20
memory result = Double(num)
// Multiple return values
memory a, b = (x, y) <- GetPair()
function Double(num U64) -> (result U64):
result = num * 2
function GetPair() -> (x U64, y U64):
x, y = 3, 4
Parameter Rules
- Arguments are read-only — cannot modify input parameters
- Return values are write-only — cannot read before assigning
function Invalid(a U64) -> (out U64):
a += 1 // ERROR: arguments are read-only
out = a
out += 1 // ERROR: return values are write-only
External Package Calls
Use :: to call functions from other packages:
memory result = math::Sqrt(val: 16)
Deploy and Enlist
deploy — Logic Initialization
Runs once when the logic is first deployed. Required if you have state logic.
state logic:
total_supply U64
endpoint deploy Init(supply U64):
mutate supply -> Token.Logic.total_supply
enlist — Actor Initialization
Runs once per user on their first interaction. Used with state actor.
state actor:
balance U64
endpoint enlist Register():
mutate 100 -> Token.Sender.balance // Starting balance
Complete Example
coco Token
state logic:
supply U64
state actor:
balance U64
// Called once at deployment
endpoint deploy SeedSupply():
mutate 1000 -> Token.Logic.supply
// Called once per new user
endpoint enlist Alms():
mutate 10 -> Token.Sender.balance
// Called anytime
endpoint dynamic Claim():
mutate sup <- Token.Logic.supply:
sup -= 1
mutate bal <- Token.Sender.balance:
bal += 1
note
deploycan only be called once (at deployment)enlistcan be called once per actor- If you have both
state logicandstate actor, onlydeployis mandatory