Skip to main content

Endpoints and Functions

Endpoints are the externally callable entry points of a Coco logic, while functions are local helpers you call from endpoints. Endpoints define named inputs and named return values, and may be marked dynamic when they mutate state (any block that uses mutate must be in a dynamic endpoint). Special qualifiers deploy and enlist handle one-time logic initialization and per-actor initialization, respectively. Aside from visibility and these qualifiers, endpoint and function syntax is the same; Coco favors explicit, named arguments and returns for clarity and auditability.

coco Functions

endpoint Combine(x,y String) -> (z String):
memory w = join(y, (output) <- DoSomething())
yield z join(x, w)

function DoSomething() -> (output String):
yield output "done!"

Endpoint Syntax

An endpoint in Coco is a callable element that can be invoked ("called") on the blockchain. A single endpoint is expected to perform simple and singular operations.

An endpoint can accept zero or more arguments and return some outputs. All arguments and return variables for an endpoint must be named. All return variables of the endpoint are automatically initialized at the beginning of its execution. See Functions.DoSomething()

Some endpoint names have a dynamic keyword. This is intended to emphasize that the endpoint modifies the state of the module. It is mandatory for any endpoint that uses the mutate keyword in its block. See TokenLedger.SeedSupply()

If multiple consecutive endpoint parameters are of the same data type, the type can be omitted from all but the last parameter.

Functions

function keyword is used for callables that can only be called from endpoints locally. They can't be invoked on the blockchain. On the other hand, endpoint can't invoke another endpoint, so function is a conventional reusable encapsulation of some functionality. So the difference between endpoint and function is just their visibility (endpoints can be called from blockchain and function from endpoints), everything else in the syntax is the same.

Arguments and return values

While passing arguments to and returning the return values from endpoints or functions in Coco is done in the same way as in most other programming languages, Coco requires a more verbose syntax for calling functions - namely, function call needs to include all argument and return value names. These names can only be omitted in case the argument has exactly the same name as the variable, so we can omit the name to avoid stuttering.

coco FCall

endpoint A():
memory x = (out) <- Double(num: 10)
memory num = 20
memory out = Double(num) // compared to the first line, we can omit names when variable names match
memory a, b = (x, y) <- Pair()

function Double(num U64) -> (out U64):
out = num * 2

function Pair() -> (x, y U64):
x, y = 3, 4

There's another strict rule regarding arguments and return values: arguments are read-only and return values are write-only. E.g., these things are not allowed:

function X(a, b U64) -> (out U64):
a += 1 // can't assign to an argument
out = a + b
out += 1 // this is "out = out + 1" and we can't read `out` at the right hand side

Deploy and Enlist

Every endpoint can get invoked, but two special qualifiers are available for deploying and enlisting. deploy endpoint is used when the logic is first deployed on the blockchain and it initializes the logic's state. If there's no state logic in the logic, deploy endpoints are not needed.

When we have state actor we can have enlist endpoints that initialize actor's state.

deploy endpoint can be called only once at deployment of the logic, while there's no limit for other endpoints (including enlist).