Skip to main content

Environment & Invocation

Access runtime information about the current call and execution environment.

Invocation

Get information about the current endpoint call:

MethodReturnsDescription
Invocation.ID()IdentifierUnique ID of this invocation
Invocation.Caller()IdentifierImmediate caller (differs from Sender in cross-logic calls)

Sender vs Caller

  • Sender — The actor who initiated the interaction (stays the same through cross-logic calls)
  • Invocation.Caller() — The immediate caller (changes in cross-logic calls)
endpoint CheckCaller() -> (sender Identifier, caller Identifier):
sender = Sender // Original actor
caller = Invocation.Caller() // Immediate caller (could be another logic)

Environment

Access runtime environment data:

MethodReturnsPISA targetDescription
Environment.Timestamp()U64allCurrent interaction timestamp
Environment.EffortCapacity()U640.4.0 and laterTotal fuel available
Environment.EffortAvailable()U640.4.0 and laterRemaining fuel
Environment.VolumeCapacity()U640.4.0 – 0.7.1Total storage space
Environment.VolumeAvailable()U640.4.0 – 0.7.1Remaining storage space
Environment.StorageResult(account, payer)(U64, U64)0.8.0 onlyStorage bytes added and removed in this interaction
endpoint GetEnvInfo() -> (
timestamp U64,
fuel_remaining U64,
invocation_id Identifier
):
timestamp = Environment.Timestamp()
fuel_remaining = Environment.EffortAvailable()
invocation_id = Invocation.ID()
Storage metering changed in PISA v0.8.0

VolumeCapacity() and VolumeAvailable() are not supported on 0.8.0 targets — v0.8.0 meters storage per account and payer instead of globally, and StorageResult() replaces them. StorageResult() in turn is not available on earlier targets.

StorageResult()

Returns two values: how many storage bytes the current interaction has added and removed so far, for one storage account charged to one payer.

added, removed = Environment.StorageResult(account, payer)
ArgumentTypeMeaning
accountIdentifierWhose storage is being measured
payerIdentifierWho is being charged — matches the payer clause on the write
coco Token

state logic:
name String

endpoint deploy Init(name String) -> (added, removed U64):
mutate name -> Token.Logic.name payer Logic
added, removed = Environment.StorageResult(Identifier(Token), Identifier(Token))
// "noname" polorizes to 7 bytes -> added = 7, removed = 0

endpoint dynamic Clear() -> (added, removed U64):
mutate "" -> Token.Logic.name // payer Sender is the default
added, removed = Environment.StorageResult(Identifier(Token), Sender)
// added = 1, removed = 7

Because both values are returned together, assign them to two outputs in a single statement.

Example: Time-based Logic

coco TimeLock

state actor:
locked_until U64

endpoint dynamic Lock(duration U64):
memory unlock_time = Environment.Timestamp() + duration
mutate unlock_time -> TimeLock.Sender.locked_until

endpoint dynamic Withdraw():
observe locked <- TimeLock.Sender.locked_until:
if Environment.Timestamp() < locked:
throw "Still locked"
// proceed with withdrawal