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 \Genesis {\mathrm{Genesis}} \newcommand \GenesisID {\Genesis\mathrm{ID}} \newcommand \pk {\mathrm{pk}} \newcommand \spk {\mathrm{spk}} \newcommand \Tx {\mathrm{Tx}} \newcommand \TxType {\mathrm{TxType}} \newcommand \TxTail {\Tx\mathrm{Tail}} \newcommand \Hash {\mathrm{Hash}} \newcommand \FirstValidRound {r_\mathrm{fv}} \newcommand \LastValidRound {r_\mathrm{lv}} \newcommand \sppk {\mathrm{sppk}} \newcommand \nonpart {\mathrm{nonpart}} \newcommand \MaxTxTail {\mathrm{TxTail}_{\max}} \newcommand \abs[1] {\lvert #1 \rvert} \newcommand \floor[1] {\left \lfloor #1 \right \rfloor } $$

$$ \newcommand \MaxTxnNoteBytes {T_{m,\max}} \newcommand \Stake {\mathrm{Stake}} \newcommand \Fee {\mathrm{fee}} \newcommand \MinTxnFee {T_{\Fee,\min}} \newcommand \PayoutsGoOnlineFee {B_{p,\Fee}} \newcommand \Eligibility {\mathrm{A_e}} \newcommand \Units {\mathrm{Units}} \newcommand \MBR {\mathrm{MBR}} \newcommand \MaximumMinimumBalance {\mathrm{MBR}_{\max}} $$

Validity and State Changes

The new Ledger’s state that results from applying a valid block is the account state that results from applying each transaction in that block, in sequence.

For a block to be valid, each transaction in its transaction sequence MUST be valid at the block’s round \( r \) and for the block’s genesis identifier \( \GenesisID_B \).

For a transaction

$$ \Tx = (\GenesisID, \TxType, \FirstValidRound, \LastValidRound, I, I^\prime, I_0, f, a, x, N, \pk, \sppk, \nonpart, \ldots) $$

(where \( \ldots \) represents fields specific to transaction types besides payand keyreg) to be valid at the intermediate state \( \rho \) in round \( r \) for the genesis identifier \( \GenesisID_B \), the following conditions MUST all hold:

  • It MUST represent a transition between two valid account states.

  • Either \( \GenesisID = \GenesisID_B \) or \( \GenesisID \) is the empty string.

  • \( \TxType \) is either pay, keyreg, acfg, axfer, afrz, appl, stpf, or hb.

  • There are no extra fields that do not correspond to \( \TxType \).

  • \( 0 \leq \LastValidRound - \FirstValidRound \leq \MaxTxTail \).

  • \( \FirstValidRound \leq r \leq \LastValidRound \).

  • \( \abs{N} \leq \MaxTxnNoteBytes \).

  • \( I \neq I_\mathrm{pool} \), \( I \neq I_f \), and \( I \neq 0 \).

  • \( \Stake(r+1, I) \geq f \geq \MinTxnFee \).

  • The transaction is properly authorized as described in the Authorization and Signatures section.

  • \( \Hash(\Tx) \notin \TxTail_r \).

  • If \( x \neq 0 \), there exists no \( \Tx^\prime \in \TxTail \) with sender \( I^\prime \), lease value \( x^\prime \), and last valid round \( \LastValidRound^\prime \) such that \( I^\prime = I \), \( x^\prime = x \), and \( \LastValidRound^\prime \geq r \).

  • If \( \TxType \) is pay,

    • \( I \neq I_k \) or both \( I^\prime \neq I_\mathrm{pool} \) and \( I_0 \neq 0 \).

    • \( \Stake(r+1, I) - f > a \) if \( I^\prime \neq I \) and \( I^\prime \neq 0 \).

    • If \( I_0 \neq 0 \), then \( I_0 \neq I \).

    • If \( I_0 \neq 0 \), \( I \) cannot hold any assets.

  • If \( \TxType \) is keyreg,

    • \( p_{\rho, I} \ne 2 \) (i.e., nonparticipatory accounts may not issue keyreg transactions)

    • If \( \nonpart \) is True then \( \spk = 0 \), \( \pk = 0 \) and \( \sppk = 0 \)

Given that a transaction is valid, it produces the following updated account state for intermediate state \( \rho+1 \):

  • For \( I \):

    • If \( I_0 \neq 0 \) then \( a_{\rho+1, I} = a^\prime_{\rho+1, I} = a^\ast_{\rho+1, I} = p_{\rho+1, I} = \pk_{\rho+1, I} = 0 \);

    • otherwise,

      • \( a_{\rho+1, I} = \Stake(\rho+1, I) - a - f \) if \( I^\prime \neq I \) and \( a_{\rho+1, I} = \Stake(\rho+1, I) - f \) otherwise.
      • \( a^\prime_{\rho+1, I} = T_{r+1} \).
      • \( a^\ast_{\rho+1, I} = a^\ast_{\rho, I} + (T_{r+1} - a^\prime_{\rho, I}) \floor{\frac{a_{\rho, I}}{A}} \).
      • If \( \TxType \) is pay, then \( \pk_{\rho+1, I} = \pk_{\rho, I} \) and \( p_{\rho+1, I} = p_{\rho, I} \)
      • Otherwise (i.e., if \( \TxType \) is keyreg),
        • \( \pk_{\rho+1, I} = \pk \)
        • \( p_{\rho+1, I} = 0 \) if \( \pk = 0 \) and \( \nonpart = \texttt{False} \)
        • \( p_{\rho+1, I} = 2 \) if \( \pk = 0 \) and \( \nonpart = \texttt{True} \)
        • \( p_{\rho+1, I} = 1 \) if \( \pk \ne 0 \)
        • If \( f > \PayoutsGoOnlineFee \), then \( \Eligibility{\rho+1, I} = \texttt{True} \)
  • For \( I^\prime \) if \( I \neq I^\prime \) and either \( I^\prime \neq 0 \) or \( a \neq 0 \):

    • \( a_{\rho+1, I^\prime} = \Stake(\rho+1, I^\prime) + a \).

    • \( a^\prime_{\rho+1, I^\prime} = T_{r+1} \).

    • \( a^\ast_{\rho+1, I^\prime} = a^\ast_{\rho, I^\prime} + (T_{r+1} - a^\prime_{\rho, I^\prime}) \floor{\frac{a_{\rho, I^\prime}}{A}} \).

  • For \( I_0 \) if \( I_0 \neq 0 \):

    • \( a_{\rho+1, I_0} = \Stake(\rho+1, I_0) + \Stake(\rho+1, I) - a - f \).

    • \( a^\prime_{\rho+1, I_0} = T_{r+1} \).

    • \( a^\ast_{\rho+1, I_0} = a^\ast_{\rho, I_0} + (T_{r+1} - a^\prime_{\rho, I_0}) \floor{\frac{a_{\rho, I_0}}{A}} \).

  • For all other \( I^\ast \neq I \), the account state is identical to that in view \( \rho \).

For transaction types other than pay and keyreg, account state is updated based on the reference logic described in the Transaction section.

Additionally, for all types of transactions, if the rekey to address of the transaction is nonzero and does not match the transaction sender address, then the transaction sender account’s spending key is set to the rekey to address. If the rekey to address of the transaction does match the transaction sender address, then the transaction sender account’s spending key is set to zero.

Note

The rest of this section describes the legacy Distribution Rewards system. If the \( R_r \) rewards rate parameter is \( 0 \), all computations keep values constant and no legacy reward distribution is carried out.

The final intermediate account \( \rho_k \) state changes the balance of the incentive pool as follows:

$$ a_{\rho_k, I_\mathrm{pool}} = a_{\rho_{k-1}, I_\mathrm{pool}} - R_r(\Units(r)) $$

An account state in the intermediate state \( \rho+1 \) and at round \( r \) is valid if all following conditions hold, where \( I_\mathrm{sp} \) is the special State Proof sender address:

  • For all addresses \( I \notin \{I_\mathrm{pool}, I_f, I_\mathrm{sp}\} \), either the account’s balance record at \( \rho+1 \) is empty - it holds no μALGO, every other field is zero, and it is responsible for no resource - or \( \Stake(\rho+1, I) \geq \MBR(\rho+1, I) \), where \( \MBR(\rho+1, I) \) is the account’s minimum balance requirement. An account responsible for any resource - for example an application account that holds a box - is therefore never exempt, and a zero balance leaves it in an invalid account state.

  • For all addresses \( I \notin \{I_\mathrm{pool}, I_f, I_\mathrm{sp}\} \), if \( \MaximumMinimumBalance \neq 0 \), then \( \MBR(\rho+1, I) \leq \MaximumMinimumBalance \).

  • \( \sum_I \Stake(\rho+1, I) = \sum_I \Stake(\rho, I) \).

The incentive pool, the fee sink, and the State Proof sender are the only accounts exempt unconditionally from the two minimum balance conditions.

These two minimum balance conditions are the only requirements the Ledger places on an account’s balance relative to its minimum balance requirement, and they apply to every transaction type. A transaction whose effects would leave any account in an invalid account state FAILS, and its effects are discarded.

Because the conditions hold over all addresses, they constrain every account a transaction affects, not only its sender: for example, the receiver of a payment, an application account that creates a box, and the account that becomes an application’s size sponsor by taking on the contributions for that application’s size.

Because the conditions constrain the intermediate state produced by each transaction, contributions incurred and released while a single transaction is evaluated — including by its inner transactions and by AVM box operations — are netted before the conditions are checked. Conversely, an account MUST satisfy its requirement at every intermediate state, so a group may not leave an account below its requirement after one transaction even if a later transaction in the same group would restore it.