$$ \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 anApplicationCalltransaction referring to this application ID is to be allowed. This program executes for allApplicationCalltransactions referring to this application ID except for those whoseOnCompletion == ClearState, in which case theClearStateProgramis executed instead. This program may modify the local or global state associated with this application. This field is encoded with msgpack fieldapprov.-
For AVM Version 3 or lower, the program’s cost as determined by the Stateful
Checkfunction 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 anApplicationCalltransaction referring to this application ID is executed withOnCompletion == 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 fieldclearp.-
For AVM Version 3 or lower, the program’s cost as determined by the Stateful
Checkfunction 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 fieldgsch. 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 fieldlsch. 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 ofApprovalProgramandClearStateProgrammay not exceed \( \MaxAppTotalProgramLen \times (1+\ExtraProgramPages) \) bytes. This field is encoded with msgpack fieldeppand 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 fieldv. -
The “global state” (
GlobalState) associated with this application, stored as a Key/Value Store. This field is encoded with msgpack fieldgs. -
A “size sponsor” (
SizeSponsor) account. When non-zero, it identifies the account responsible for the minimum balance contributions of this application’sExtraProgramPagesandGlobalStateSchema. When zero, the application’s creator bears those contributions. This field is encoded with msgpack fieldss, and is exposed to the AVM as theAppSizeSponsorfield ofapp_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 fieldfbr. -
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 fieldfba.
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:
NumUintrepresents the maximum number of integer values that may appear in some KV.NumByteSlicerepresents 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
ExtraProgramPagesandGlobalStateSchemaare removed from the current size sponsor (the account named bySizeSponsor, or the creator whenSizeSponsoris zero). -
The contributions for the new
ExtraProgramPagesandGlobalStateSchemaare added to the account that submitted the update (the transaction’s sender), which becomes the new size sponsor.SizeSponsoris set to that account, except that when the sender is the creator,SizeSponsoris 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.