Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

$$ \newcommand \App {\mathrm{App}} \newcommand \MaxAppProgramCost {\App_{c,\max}} \newcommand \ExtraProgramPages {\mathrm{ExtraProgramPages}} \newcommand \MaxGlobalSchemaEntries {\App_{\mathrm{GS},\max}} \newcommand \MaxLocalSchemaEntries {\App_{\mathrm{LS},\max}} \newcommand \MaxAppTotalProgramLen {\App_{\mathrm{prog},t,\max}} \newcommand \MaxExtraAppProgramPages {\App_{\mathrm{page},\max}} \newcommand \MinBalance {b_{\min}} \newcommand \AppFlatOptInMinBalance {\App_{\mathrm{optin},\MinBalance}} \newcommand \AppFlatParamsMinBalance {\App_{\mathrm{create},\MinBalance}} \newcommand \MaxAppKeyLen {\App_{\mathrm{k},\max}} \newcommand \SchemaBytesMinBalance {\App_{\mathrm{b},\MinBalance}} \newcommand \SchemaMinBalancePerEntry {\App_{\mathrm{s},\MinBalance}} \newcommand \SchemaUintMinBalance {\App_{\mathrm{u},\MinBalance}} \newcommand \Box {\mathrm{Box}} \newcommand \MaxBoxSize {\Box_{\max}} \newcommand \BoxByteMinBalance {\Box_{\mathrm{byte},\MinBalance}} \newcommand \BoxFlatMinBalance {\Box_{\mathrm{flat},\MinBalance}} $$

Applications

Each account can create applications, each named by a globally-unique 64-bit unsigned integer (the application ID).

Applications are associated with a set of application parameters, which can be encoded as a msgpack struct:

  • A mutable stateful “Approval” program (ApprovalProgram), whose result determines whether an ApplicationCall transaction referring to this application ID is to be allowed. This program executes for all ApplicationCall transactions referring to this application ID except for those whose OnCompletion == ClearState, in which case the ClearStateProgram is executed instead. This program may modify the local or global state associated with this application. This field is encoded with msgpack field approv.

    • For AVM Version 3 or lower, the program’s cost as determined by the Stateful Check function MUST NOT exceed \( \MaxAppProgramCost \).

    • For AVM Version 4 or higher programs, the program’s cost during execution MUST NOT exceed \( \MaxAppProgramCost \).

  • A mutable stateful “Clear State” program (ClearStateProgram), executed when an opted-in user forcibly removes the local application state associated with this application from their account data. This happens when an ApplicationCall transaction referring to this application ID is executed with OnCompletion == ClearState. This program, when executed, is not permitted to cause the transaction to fail. This program may modify the local or global state associated with this application. This field is encoded with msgpack field clearp.

    • For AVM Version 3 or lower, the program’s cost as determined by the Stateful Check function MUST NOT exceed \( \MaxAppProgramCost \).

    • For AVM Version 4 or higher programs, the program’s cost during execution MUST NOT exceed \( \MaxAppProgramCost \).

  • A “global state schema” (GlobalStateSchema), which sets a limit on the size of the global Key/Value Store that may be associated with this application (see State Schemas). This field is encoded with msgpack field gsch. It is set at creation and MAY be changed by an application update. It MUST NOT be reduced below the application’s current global state usage.

    • The maximum number of values that this schema may permit is \( \MaxGlobalSchemaEntries \).
  • An immutable “local state schema” (LocalStateSchema), which sets a limit on the size of a Key/Value Store that this application will allocate in the account data of an account that has opted in (see “State Schemas”). This field is encoded with msgpack field lsch. Unlike the global state schema, it MUST NOT be changed after creation, because each opted-in account caches a copy of it in order to compute its own minimum balance requirement.

    • The maximum number of values that this schema may permit is \( \MaxLocalSchemaEntries \).
  • An “extra pages” value (ExtraProgramPages), which limits the total size of the application programs. The sum of the lengths of ApprovalProgram and ClearStateProgram may not exceed \( \MaxAppTotalProgramLen \times (1+\ExtraProgramPages) \) bytes. This field is encoded with msgpack field epp and may not exceed \( \MaxExtraAppProgramPages \). It is set at creation and MAY be changed by an application update, provided the (possibly new) programs still fit within the (possibly new) page allowance.

  • An “application version” (Version) value that begins at \( 0 \) when an Application is created or when the protocol version including this field goes into effect whichever is later. This field is encoded with msgpack field v.

  • The “global state” (GlobalState) associated with this application, stored as a Key/Value Store. This field is encoded with msgpack field gs.

  • A “size sponsor” (SizeSponsor) account. When non-zero, it identifies the account responsible for the minimum balance contributions of this application’s ExtraProgramPages and GlobalStateSchema. When zero, the application’s creator bears those contributions. This field is encoded with msgpack field ss, and is exposed to the AVM as the AppSizeSponsor field of app_params_get (see Size Sponsor).

  • A mutable “foreign box reads” flag (ForeignBoxReads). When true, another application may read this application’s boxes, provided the boxes are available to the transaction group. It does not permit another application to modify the boxes. This field is encoded with msgpack field fbr.

  • A mutable “family box access” flag (FamilyBoxAccess). When true, applications with the same creator may read and modify this application’s boxes, provided the boxes are available to the transaction group. This field is encoded with msgpack field fba.

Both box-access flags are initially false and may be changed by the application using app_params_set.

Creating an application, sponsoring its size, opting in to one, and storing data in boxes all contribute to the minimum balance requirement of an account. The amounts are given in App Minimum Balance Contributions and Boxes.

Key/Value Stores

A Key/Value Store, or KV, is an associative array mapping keys of type byte-array to values of type byte-array or 64-bit unsigned integer.

The values in a KV are either:

  • Bytes, representing a byte-array,
  • Uint, representing an unsigned 64-bit integer value.

The maximum length of a key in a KV is \( \MaxAppKeyLen \) bytes.

State Schemas

A state schema represents limits on the number of each value type that may appear in a Key/Value Store.

State schemas control the maximum size of global and local state KVs.

A state schema is composed of two fields:

  • NumUint represents the maximum number of integer values that may appear in some KV.
  • NumByteSlice represents the maximum number of byte-array values that may appear in some KV.

App Minimum Balance Contributions

An application contributes to the minimum balance requirement of the accounts that are responsible for its state, in μALGO, as follows:

  • Its creator contributes \( \AppFlatParamsMinBalance \) for the application itself. This contribution always remains with the creator.

  • Its size sponsor, which is its creator until an update moves that responsibility, contributes \( \AppFlatParamsMinBalance \times \ExtraProgramPages \) for the application’s extra program pages, plus the schema contribution below for its GlobalStateSchema.

  • Each account opted in contributes \( \AppFlatOptInMinBalance \), plus the schema contribution below for the application’s LocalStateSchema.

The contribution for a state schema is:

$$ (\SchemaMinBalancePerEntry + \SchemaUintMinBalance) \times \mathrm{NumUint} + (\SchemaMinBalancePerEntry + \SchemaBytesMinBalance) \times \mathrm{NumByteSlice} $$

Each contribution is released when the state it accounts for is released: deleting the application releases the creator’s and the size sponsor’s contributions, and closing out or clearing local state releases the contributions of the account that was opted in.

Size Sponsor

The minimum balance contributions for an application’s ExtraProgramPages and GlobalStateSchema are borne by a single account, its size sponsor. At creation, that account is the creator, and the application’s SizeSponsor field is left zero to signify this.

An application update MAY change ExtraProgramPages and GlobalStateSchema. Because the account submitting the update need not be the creator, the responsibility for these contributions follows the account that most recently set the sizes:

  • The contributions for the former ExtraProgramPages and GlobalStateSchema are removed from the current size sponsor (the account named by SizeSponsor, or the creator when SizeSponsor is zero).

  • The contributions for the new ExtraProgramPages and GlobalStateSchema are added to the account that submitted the update (the transaction’s sender), which becomes the new size sponsor. SizeSponsor is set to that account, except that when the sender is the creator, SizeSponsor is reset to zero.

When the application is deleted, the contributions for its ExtraProgramPages and GlobalStateSchema are released from the current size sponsor.

Boxes

The Box store is an associative array mapping keys of type: (uint64 x []byte) to values of type []byte.

  • The key is a pair in which the first value corresponds to an Application ID, and the second is a box name, \( 1 \) to \( \MaxAppKeyLen \) bytes in length. Unlike Global/Local State keys, an empty array is not a valid Box name. However, empty Box names may appear in transactions to increase the I/O budget or allow creation of Boxes whose Application ID is not known at transaction group construction time (see below).

  • The value is a byte-array of length not greater than \( \MaxBoxSize \).

Boxes are held by the application’s account, whose address is the hash of the application ID. A box with name \( n \) and size \( s \) contributes \( \BoxFlatMinBalance + \BoxByteMinBalance \times (\mathrm{len}(n) + s) \) μALGO to that account’s minimum balance requirement for as long as the box exists. An opcode that creates, resizes, or destroys a box changes the contribution immediately.

Family Reentrancy

The boxes of an application whose FamilyBoxAccess is true are mutable state shared across every application with the same creator, so they are subject to a family-scoped analogue of the reentrancy restriction on applications. Two applications are in the same family when their creator addresses are equal.

An application touches family-shared state when it reads or modifies a box of an application whose FamilyBoxAccess is true — including its own. A touch by \( c \) is also a touch by each application in the unbroken chain of callers of \( c \) that are in \( c \)’s family, and remains so after \( c \) returns.

Modifying such a box FAILS if the chain of callers of the modifying application \( c \) contains an application in \( c \)’s family that has already touched family-shared state and is separated from \( c \) by at least one application outside the family. Reads never trigger this rule.