state
Pebble 0.3.1 · all symbols on this page are stable.
The state keyword introduces a typed datum inside a contract declaration. Each state block defines one variant of an on-chain sum type whose underlying CBOR encoding is what the contract's UTxOs carry as their datum. Inside a spend method declared on a state, context.state is destructured to a strongly-typed record of that state's fields — you never write unConstrData or fromData by hand.
A contract may declare zero or more state blocks. If at least one state exists, the contract's UTxOs carry a datum of the corresponding sum type. If none exists, the contract is "stateless" and UTxOs carry no datum (or an opaque data you handle yourself via context.optionalDatum).
Grammar
contract Name [( params… )] {
state Variant {
field_1: Type
field_2: Type
...
spend method_1( args… ) { body }
spend method_2( args… ) { body }
...
}
// more states allowed
spend fallback( args… ) { body } // optional bare spend
}
Rules:
- Fields precede
spendmethods. Within astateblock, everyfield: Typedeclaration must come before anyspendmethod. - Only
spendis allowed insidestate.mint,certify,withdraw,propose,votego on the contract level, not inside a state. Their datum-shape is determined by the script purpose, not by the state. - No field initialisers.
statefields are inputs from the datum — they aren't initialised at declaration time. The off-chain transaction that creates the UTxO supplies their values. - Names must be unique across states. Two
state Fooblocks in the same contract is an error. spendmethod names are scoped to their state. Two different states can both declarespend fill(...)without collision.