Skip to main content
A Stellarium struct names a shape of object: the fields it has and the type of each. Contracts, event types and resource functions use structs as types, so a value is checked against its fields wherever it is passed, returned, assigned or emitted, instead of being an unchecked object. Structs need RequestScript 1.7.0. See Structs in the RequestScript docs for the language rules.
  • Your organization owns its structs. You declare a struct on one of your nodes, in RequestScript or in TypeScript, and its path belongs to your organization.
  • Anyone uses them. Any script on a node that knows a struct may use it as a type. Nodes learn structs from their peers.
  • Versions never change. Every declaration and every reference names a version, and a version is never changed or deleted, so a reference always means the same fields on every node.

Declaring a struct

A struct declares its fields and its version, and has no body:
Address.req
Customer.req
Send it to POST /v1/structs on a node of your organization, with the node’s API_KEY or a run token from one of your organization’s API clients for that node:
Response
  • The node’s organization owns it. A run token from another organization is refused with 403.
  • The first organization keeps the path. Once your organization declares com.example.Address, only your nodes may declare versions of it. Another organization is refused with 409.
  • Versions are immutable. Declaring the same version again with the same fields succeeds with 200 and changes nothing. With different fields it is refused with 409. To change a shape, declare a new version.
  • Versions are never deleted. Contracts and event types on other nodes may name any version, so there is no route to delete one.
  • Everything it names must be known. A struct that names a struct the node doesn’t know, contains itself, or nests more than 8 structs deep is refused with 400.
  • Peers learn about it right away. The node announces its structs to its peers whenever it declares a new one.

Using structs

A struct type is the struct’s name and version. Use it wherever a type goes:
Ship.req
  • Contracts and requests: parameters, return types, var annotations and state variables.
  • Event types: event com.example.OrderShipped(to: com.example.Address@1).
  • Resource functions: parameter and return types, declared in TypeScript.
A value is checked structurally and leniently. Each declared field is converted to its type, a missing field is null, and fields the struct doesn’t declare are kept. Any object with fitting fields fits, whatever struct it was built as. A value that doesn’t fit fails the script, and POST /v1/run answers 422 with "error": "Script failed" and the field in details. A reference always names its version, and never moves to a later one. To use a new shape, deploy a new version of the contract or event type that names it.

Declaring structs in TypeScript

A resource function names structs in its types. Define them with defineStruct, and register them with the node:
server.ts
  • Field types are RequestScript type strings. A field that is another struct names its version, by its .type or as "com.example.Address@1". You can also pass structs to start as structs: [Forecast].
  • The node needs an operator. A node with structs needs OPERATOR_URL, and waits for its session before it serves, as a node with paid functions does: the session tells it its organization. It then declares each struct as its organization’s, in any order.
  • Conflicts stop the node. A path another organization owns, a version declared before with different fields, or a field naming a struct the node doesn’t know stops the node from starting. So does a function type that names a struct without a version.
  • Parameters are checked before the call. When a peer calls the function, the node checks its struct-typed parameters before anything is paid or run, and answers 400 if one doesn’t fit. Parameters of other types reach exec as they come.
  • Return values are checked by the caller. A return value that doesn’t fit its struct fails the caller’s script.

How structs reach your peers

  1. Nodes announce their structs. Each node tells its peers which structs its organization owns, signed with its key and carrying its membership token. It announces again whenever it declares one. A node joining the network asks each peer for its structs, before their event types and resources, which may name them.
  2. Peers check the owner. A peer learns a struct only if the membership token says the announcing node belongs to the struct’s owner. It refuses a path another organization owns, and a version it already knows with other fields.
  3. Learned structs stay. A struct a node learned stays known after the peer stops announcing it, since a version never goes away.
A node knows only the structs of its peers’ organizations. A struct may name another organization’s struct, and a node can use it once it has learned both from their owners.

Unknown structs

  • Deploys: a contract, event type or struct that names a struct the node doesn’t know is refused with 400.
  • Runs: a script that names an unknown struct fails before it runs anything.
  • Peers’ resources: a node still learns a peer’s resource when one of its functions names a struct it doesn’t know. A script calling that function fails before any payment or network call. The resource’s other functions still work.
  • Peers’ event types: a node doesn’t learn an event type whose fields name a struct it doesn’t know. It learns it from the peer’s next event announcement, once it knows the struct.

Limits

  • A struct has at most 64 fields.
  • Structs nest at most 8 deep, counting lists of structs.
  • A struct’s source is at most 16 KiB.