$$ \newcommand \App {\mathrm{App}} \newcommand \MaxAppProgramCost {\App_{c,\max}} \newcommand \MaxTxGroupSize {GT_{\max}} \newcommand \MaxInnerTransactions {\App_\mathrm{itxn}} \newcommand \MaxAppTotalProgramLen {\App_{\mathrm{prog},t,\max}} \newcommand \MaxExtraAppProgramPages {\App_{\mathrm{page},\max}} $$
Execution Environment for Applications (Smart Contracts)
Applications (Smart Contracts) are executed in Application Call transactions.
Like Logic Signatures, Applications indicate success by leaving a single non-zero
uint64
value on the Stack.
A failed Application Call to an Approval Program is not a valid transaction, thus not written to the blockchain.
An Application Call with On Complete
set to ClearStateOC
invokes the Clear State Program, rather than the usual Approval
Program. If the Clear State Program fails, application state changes are rolled back,
but the transaction still succeeds, and the sender’s Local State for the called application
is removed.
Applications have access to everything a Logic Signature may access (see section), as well as the ability to examine blockchain state, such as balances and application state (their own state and the state of other applications).
Applications also have access to some Global Fields that are not visible to Logic Signatures because their values change over time.
Since Applications access changing state, nodes have to rerun their code to determine if the Application Call transactions in their Transaction Pool would still succeed each time a block is added to the blockchain.
Bytecode Size
The size of an Application is defined as the length of its approval program bytecode plus its clearstate program bytecode. The sum of these two programs MUST NOT exceed \( \MaxAppTotalProgramLen \times \MaxExtraAppProgramPages \).
Opcode Budget
Applications have limits on their execution cost.
Before Version 4, this was a static limit on the cost of all the instructions in the program.
Starting in Version 4, the cost is tracked dynamically during execution and MUST NOT exceed \( \MaxAppProgramCost \).
Beginning with Version 5, programs costs are pooled and tracked dynamically across Application executions in a group. If \( n \) application invocations appear in a group, then the total execution cost of all such calls MUST NOT exceed \( n \times \MaxAppProgramCost \).
In Version 6, inner Application Calls become possible, and each such call increases
the pooled opcode budget by \( \MaxAppProgramCost \) at the time the inner group
is submitted (with the itxn_submit
opcode), allowing a maximum opcode budget of:
$$ \MaxTxGroupSize \times (1 + \MaxInnerTransactions) \times \MaxAppProgramCost = 190{,}400 $$
Clear Program Execution
Executions of the Clear State Program are more stringent to ensure that Applications may be closed out (by accounts) and have a chance to clean up their internal state.
At the beginning of a Clear State Program execution, the pooled budget available MUST be \( \MaxAppProgramCost \) or higher. If it is not, the containing transaction group fails without clearing the Application’s state.
During the Clear State Program execution, no more than \( \MaxAppProgramCost \) may be drawn. If further execution is attempted, the Clear State Program fails, and the Application’s state is cleared.
Resource Availability
Applications have limits on the amount of blockchain state they may examine.
These limits are enforced by failing any opcode that attempts to access a resource unless the resource is available. These resources are:
-
Accounts, which MUST be available to access their balance, or other Account parameters such as voting details.
-
Assets, which MUST be available to access global asset parameters, such as the asset’s URL, name, or privileged addresses.
-
Holdings, which MUST be available to access a particular Account’s balance or frozen status for a particular asset.
-
Applications, which MUST be available to read an Application’s programs, parameters, or Global State.
-
Locals, which MUST be available to read a particular Account’s Local State for a particular Application.
-
Boxes, which MUST be available to read or write a box, designated by an Application and name for the Box.
Resources are available based on the contents of the executing transaction and, in later versions, the contents of other transactions in the same group.
-
A resource in the foreign array fields of the Application Call transaction (foreign accounts, foreign assets, and foreign applications) is available.
-
The transaction sender (
snd
) is available. -
The Global Fields
CurrentApplicationID
, andCurrentApplicationAddress
are available. -
In pre-Version 4 programs, all Holdings are available to the
asset_holding_get
opcode, and all Locals are available to theapp_local_get_ex
opcode if the Account of the resource is available. -
In Version 6 (and later) programs, any Asset or Application created earlier in the same transaction group (whether by a top-level or inner transaction) is available. In addition, any Account that is the associated Account of an Application that was created earlier in the group is available.
-
In Version 7 (and later) programs, the Account associated with any Application present in the foreign applications field is available.
-
In Version 4 (and later) programs, Holdings and Locals are available if both components of the resource are available according to the above rules.
-
In Version 9 (and later) programs, there is group resource sharing. Any resource that is available in some top-level transaction in a group is available in all Version 9 or later Application calls in the group, whether those Application calls are top-level or inner.
-
Version 9 (and later) programs MAY use the transaction access list instead of the foreign arrays. When using the transaction access list, each resource MUST be listed explicitly, since the automatic availability of the foreign arrays is no longer provided, in particular:
-
Holdings and Locals are no longer automatically available because their components are.
-
Application Accounts are no longer automatically available because of the availability of their corresponding Applications.
-
However, the transaction access list allows for the listing of more resources than the foreign arrays. Listed resources become available to other (post-Version 8 programs) Applications through group resource sharing.
- When considering whether a Holding or Local is available by group resource sharing, the Holding or Local MUST be available in a top-level transaction based on pre-Version 9 rules.
📎 EXAMPLE
If account
A
is made available in one transaction, and assetX
is made available in another, group resource sharing does not makeA
’sX
Holding available.
-
Top-level transactions that are not Application Calls also make resources available to group-level resource sharing. The following resources are made available by other transaction types:
-
pay
: sender (snd
), receiver (rcv
), and close-to (close
) (if set). -
keyreg
: sender (snd
). -
acfg
: sender (snd
), configured asset (caid
), and the configured asset holding of the sender. -
axfer
: sender (snd
), asset receiver (arcv
), asset sender (asnd
) (if set), asset close-to (aclose
) (if set), transferred asset (xaid
), and the transferred asset holding of each of those accounts. -
afrz
: sender (snd
), freeze account (fadd
), freeze asset (faid
), and the freeze asset holding of the freeze account. The freeze asset holding of the sender is not made available.
-
-
A Box is available to an Approval Program if any transaction in the same group contains a box reference (in transaction’s box references
apbx
or access listal
) that denotes the Box. A box reference contains an indexi
, and namen
. The index refers to thei
-th Application in the transaction’s foreign applications or access list array (only one of which can be used), with the usual convention that0
indicates the Application ID of the Application called by that transaction. No Box is ever available to a Clear State Program.
Regardless of availability, any attempt to access an Asset or Application with an ID less than \( 256 \) from within an Application will fail immediately. This avoids any ambiguity in opcodes that interpret their integer arguments as resource IDs or indexes into the foreign assets or foreign applications arrays.
It is RECOMMENDED that Application authors avoid supplying array indexes to these opcodes, and always use explicit resource IDs. By using explicit IDs, contracts will better take advantage of group resource sharing.
The array indexing interpretation MAY be deprecated in a future program version.