# Resource Usage

Algorand smart contracts do not have default access to the entire blockchain ledger. Therefore, when a smart contract method needs to access resources such as accounts, assets (ASA), other applications (smart contracts), or box references, these must be provided through the reference array during invocation. This page explains what reference arrays are, why they are necessary, the different ways to provide them, and includes a series of code examples.

## Resource Availability

[Section titled “Resource Availability”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#resource-availability)

When smart contracts are executed, they may require data stored within the blockchain ledger for evaluation. For this data (resource) to be accessible to the smart contract, it must be made available. When you say, ‘A resource is available to the smart contract,’ it means that the reference array, referencing the resource, was provided during the invocation and execution of a smart contract method that requires access to that resource.

### What are Reference Arrays?

[Section titled “What are Reference Arrays?”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#what-are-reference-arrays)

There are four reference arrays:

- [Accounts](https://dev.algorand.co/concepts/accounts/overview): Reference to Algorand accounts
- [Assets](https://dev.algorand.co/concepts/assets/overview): Reference to Algorand Standard Assets
- [Applications](https://dev.algorand.co/concepts/smart-contracts/overview): Reference to an external smart contract
- [Boxes](https://dev.algorand.co/concepts/smart-contracts/storage/box): Reference to Boxes created within the smart contract

Including necessary resources in the appropriate arrays enables the smart contract to access the necessary data during execution, such as reading an account’s Algo balance or examining the immutable properties of an ASA.
This page explains how data access is managed by a smart contract in version 9 or later of the Algorand Virtual Machine (AVM). For details on earlier AVM versions, refer to the [TEAL specification](https://github.com/algorandfoundation/specs/blob/master/dev/TEAL.md#resource-availability)

By default, the reference arrays are empty, with the exception of the accounts and applications arrays. The Accounts array contains the transaction sender’s address, and the Applications array contains the called smart contract ID.

### Types of Resources to Make Available

[Section titled “Types of Resources to Make Available”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#types-of-resources-to-make-available)

Using these four reference arrays, you can make the following six unique ledger items available during smart contract execution: account, asset, application, account+asset, account+application, and application+box.
Accounts and Applications can contain sublists with potentially large datasets. For example, an account may opt into an extensive set of assets or applications which store the user’s local state. Additionally, smart contracts can store potentially unlimited boxes of data within the ledger. For instance, a smart contract might create a unique box of arbitrary data for each user.
These combinations, account+asset, account+application, and application+box, represent cases where you need to access data that exists at the intersection of two resources. For example:

- Account+Asset: To read what the balance of an asset is for a specific account, both the asset and the account reference must be included in the respective reference arrays.
- Account+Application: To access an account’s local state of an application, both the account and the application reference must be included in the respective reference arrays.
- Application+Box: To retrieve data from a specific box created by an application, the application and the box reference must be included in the respective reference arrays.

### Inner Transaction Resource Availability

[Section titled “Inner Transaction Resource Availability”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#inner-transaction-resource-availability)

When a smart contract executes an inner transaction to call another smart contract, the inner contract inherits all resource availability from the top-level contract. Here’s an example:

Let’s say contract A sends an inner transaction that calls a method in contract B. If contract B’s method requires access to asset XYZ, you only need to provide the asset reference when calling contract A, while still properly referencing contract B in the Applications array. This makes asset XYZ available to contract B through the resource availability inherited from contract A.

### Reference Array Constraints and Requirements

[Section titled “Reference Array Constraints and Requirements”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#reference-array-constraints-and-requirements)

There are certain limitations and requirements you need to consider when providing references in the reference arrays:

- The four reference arrays are limited to a combined total of eight values per application transaction. This limit excludes the default references to the transaction sender’s address and the called smart contract ID.
- The accounts array can contain no more than four accounts.
- The values passed into the reference arrays can change per application transaction.
- When accessing one of the sublists of items, the application transaction must include both the top-level item and the nested list item within the same call. For example, to read an ASA balance for a specific account, the account and the asset must be present in the respective accounts and asset arrays for the given transaction.

### Reason for limited Access to Resources

[Section titled “Reason for limited Access to Resources”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#reason-for-limited-access-to-resources)

To maintain a high level of performance, the AVM restricts how much of the ledger can be viewed within a single contract execution. This is implemented with reference arrays passed with each application call transaction, defining the specific ledger items available during execution. These arrays are the Account, Asset, Application, and Boxes arrays.

### Resource Sharing

[Section titled “Resource Sharing”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#resource-sharing)

Resources are shared across transactions within the same atomic group. This means that if there are two app calls calling different smart contracts in the same atomic group, the two smart contracts share resource availability.

For example, say you have two smart contract call transactions grouped together, transaction #1 and transaction #2. Transaction #1 has asset 123456 in its assets array, and transaction #2 has asset 555555 in its assets array. Both assets are available to both smart contract calls during evaluation.

When accessing a sublist resource (account+asa, account+application local state, application+box), both resources must be in the same transaction’s arrays. For example, you cannot have account A in transaction #1 and asset Z in transaction #2 and then try to get the balance of asset Z for account A. Asset Z and account A must be in the same application transaction. If asset Z and account A are in transaction #1’s arrays, A’s balance for Z is also available to transaction #2 during evaluation.

Because Algorand supports grouping up to 16 transactions simultaneously, this pushes the available resources up to 8x16 or 128 items if all 16 transactions are application transactions.

If an application transaction is grouped with other types of transactions, other resources will be made available to the smart contract called in the application transaction. For example, if an application transaction is grouped with a payment transaction, the payment transaction’s sender and receiver accounts are available to the smart contract.

If the CloseRemainderTo field is set, that account will also be available to the smart contract. The table below summarizes what each transaction type adds to resource availability.

| Transaction | Transaction Type | Availability Notes |
| --- | --- | --- |
| Payment | `pay` | `txn.Sender`, `txn.Receiver`, and `txn.CloseRemainderTo` (if set) |
| Key Registration | `keyreg` | `txn.Sender` |
| Asset Config/Create | `acfg` | `txn.Sender`, `txn.ConfigAsset`, and the `txn.ConfigAsset` holding of `txn.Sender` |
| Asset Transfer | `axfer` | `txn.Sender`, `txn.AssetReceiver`, `txn.AssetSender` (if set), `txnAssetCloseTo` (if set), `txn.XferAsset`, and the `txn.XferAsset` holding of each of those accounts |
| Asset Freeze | `afrz` | `txn.Sender`, `txn.FreezeAccount`, `txn.FreezeAsset`, and the `txn.FreezeAsset` holding of `txn.FreezeAccount`. The `txn.FreezeAsset` holding of `txn.Sender` is not made available |

## Different Ways to Provide References

[Section titled “Different Ways to Provide References”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#different-ways-to-provide-references)

There are different ways you can provide resource references when calling smart contract methods:

1. **Automatic Resource Population**: Automatically input resource references in the reference(foreign) arrays with automatic resource population using the AlgoKit Utils library ( [TypeScript](https://github.com/algorandfoundation/algokit-utils-ts/blob/40be39f672be19dc244b8e8fb4f5bcbc446d4f50/docs/code/modules/index.md#populateappcallresources) and Python)

2. **Reference Types**: Pass reference types as arguments to contract methods. (You can only do this for Accounts, Assets, and Applications and not Boxes.)

3. **Manually Input**: Manually input resource references in the reference(foreign) arrays

## Account Reference Example

[Section titled “Account Reference Example”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#account-reference-example)

Here is a simple smart contract with two methods that read the balance of an account. This smart contract requires the account
reference to be provided during invocation.

- [Algorand TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-885)
- [Algorand Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-886)

```
import { Contract, Account, readonly } from '@algorandfoundation/algorand-typescript'

import { Address } from '@algorandfoundation/algorand-typescript/arc4'

/**

* A contract that demonstrates how to use resource usage in a contract using an account reference

*/

export default class ReferenceAccount extends Contract {

/**

* Returns the balance of the account

* @returns The balance of the account

*/

@readonly

public getAccountBalance() {

const address = new Address('R3J76MDPEXQEWBV2LQ6FLQ4PYC4QXNHHPIL2BX2KSFU4WUNJJMDBTLRNEM')

const addressBytes = address.bytes

const account = Account(addressBytes)

return account.balance

}

/**

* Returns the balance of the account

* @param account The account to get the balance of

* @returns The balance of the account

*/

@readonly

public getAccountBalanceWithArgument(account: Account) {

return account.balance

}

}
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/contracts/ReferenceAccount/contract.algo.ts#L1)

```
from algopy import Account, ARC4Contract, UInt64

from algopy.arc4 import abimethod

"""

A contract that demonstrates how to use resource usage in a contract using an account reference

"""

class ReferenceAccount(ARC4Contract):

"""

Returns the balance of the account

@returns The balance of the account

"""

@abimethod

def get_account_balance(self) -> UInt64:

return Account(

"WMHF4FLJNKY2BPFK7YPV5ID6OZ7LVDB2B66ZTXEAMLL2NX4WJZRJFVX66M"

).balance  # Replace with your account address

"""

Returns the balance of the account

@param account The account to get the balance of

@returns The balance of the account

"""

@abimethod

def get_account_balance_with_argument(self, account: Account) -> UInt64:

return account.balance
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/smart_contracts/reference_account/contract.py#L1)

Here are three different ways you can provide the account reference when calling a contract method using the AlgoKit Utils library.

### Method \#1: Automatic Resource Population

[Section titled “Method #1: Automatic Resource Population”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-1-automatic-resource-population)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-855)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-856)

```
// Configure automatic resource population per app call

const result1 = await referenceAccountAppClient.send.getAccountBalance({

args: {},

})

console.log('Method #1 Account Balance', result1.return)

// Or set the default value for populateAppCallResources to true globally and apply to all app calls

Config.configure({

populateAppCallResources: true,

})

const result2 = await referenceAccountAppClient.send.getAccountBalance({

args: {},

})

console.log('Method #1 Account Balance', result2.return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/account-reference.ts#L7)

```
# Configure automatic resource population per app call

result1 = reference_account_app_client.send.get_account_balance(

send_params=SendParams(populate_app_call_resources=True)

)

print("Method #1 Account Balance", result1.abi_return)

# Or set the default value for populate_app_call_resources to true globally and apply to all app calls

config.config.configure(populate_app_call_resources=True)

result2 = reference_account_app_client.send.get_account_balance()

print("Method #1 Account Balance", result2.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/account_reference.py#L17)

### Method \#2: Using Reference Types

[Section titled “Method #2: Using Reference Types”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-2-using-reference-types)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-853)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-854)

```
// Include the account reference in the app call argument to be populated automatically

const result = await referenceAccountAppClient.send.getAccountBalanceWithArgument({

args: {

account: referenceAccount.addr.toString(),

},

})

console.log('Method #2 Account Balance', result.return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/account-reference.ts#L33)

```
# Include the account reference in the app call argument to be populated automatically

result = reference_account_app_client.send.get_account_balance_with_argument(

args=GetAccountBalanceWithArgumentArgs(account=reference_account.address)

)

print("Method #2 Account Balance", result.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/account_reference.py#L40)

### Method \#3: Manually Input

[Section titled “Method #3: Manually Input”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-3-manually-input)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-851)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-852)

```
// Include the account reference in the accountReferences array to be populated manually

const result = await referenceAccountAppClient.send.getAccountBalance({

args: {},

accountReferences: [referenceAccount],

})

console.log('Method #3 Account Balance', result.return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/account-reference.ts#L50)

```
# Include the account reference in the account_references array to be populated manually

result = reference_account_app_client.send.get_account_balance(

params=CommonAppCallParams(account_references=[reference_account.address])

)

print("Method #3 Account Balance", result.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/account_reference.py#L56)

## Asset Reference Example

[Section titled “Asset Reference Example”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#asset-reference-example)

Here is a simple smart contract with two methods that read the total supply of an asset(ASA). This smart contract requires the asset
reference to be provided during invocation.

- [Algorand TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-877)
- [Algorand Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-878)

```
import { Contract, Asset, readonly } from '@algorandfoundation/algorand-typescript'

/**

* A contract that demonstrates how to use resource usage in a contract using an asset reference

*/

export default class ReferenceAsset extends Contract {

/**

* Returns the total supply of the asset

* @returns The total supply of the asset

*/

@readonly

public getAssetTotalSupply() {

return Asset(1005).total // Replace with your asset id

}

/**

* Returns the total supply of the asset

* @param asset The asset to get the total supply of

* @returns The total supply of the asset

*/

@readonly

public getAssetTotalSupplyWithArgument(asset: Asset) {

return asset.total

}

}
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/contracts/ReferenceAsset/contract.algo.ts#L1)

```
from algopy import ARC4Contract, Asset, UInt64

from algopy.arc4 import abimethod

"""

A contract that demonstrates how to use resource usage in a contract using an asset reference

"""

class ReferenceAsset(ARC4Contract):

"""

Returns the total supply of the asset

@returns The total supply of the asset

"""

@abimethod

def get_asset_total_supply(self) -> UInt64:

return Asset(1185).total  # Replace with your asset id

"""

Returns the total supply of the asset

@param asset The asset to get the total supply of

@returns The total supply of the asset

"""

@abimethod

def get_asset_total_supply_with_arg(self, asset: Asset) -> UInt64:

return asset.total
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/smart_contracts/reference_asset/contract.py#L1)

Here are three different ways you can provide the asset reference when calling a contract method using the AlgoKit Utils library.

### Method \#1: Automatic Resource Population

[Section titled “Method #1: Automatic Resource Population”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-1-automatic-resource-population-1)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-879)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-880)

```
// Configure automatic resource population per app call

const result1 = await referenceAssetAppClient.send.getAssetTotalSupply({

args: {},

populateAppCallResources: true,

})

console.log('Method #1 Asset Total Supply', result1.return)

// Or set the default value for populateAppCallResources to true globally and apply to all app calls

Config.configure({

populateAppCallResources: true,

})

const result2 = await referenceAssetAppClient.send.getAssetTotalSupply({

args: {},

})

console.log('Method #1 Asset Total Supply', result2.return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/asset-reference.ts#L7)

```
# Configure automatic resource population per app call

result1 = reference_asset_client.send.get_asset_total_supply(

send_params=SendParams(populate_app_call_resources=True),

)

print("Method #1 Asset Total Supply:", result1.abi_return)

# Or set the default value for populate_app_call_resources to true globally and apply to all app calls

config.config.configure(

populate_app_call_resources=True,

)

result2 = reference_asset_client.send.get_asset_total_supply()

print("Method #1 Asset Total Supply:", result2.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/asset_reference.py#L17)

### Method \#2: Using Reference Types

[Section titled “Method #2: Using Reference Types”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-2-using-reference-types-1)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-859)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-860)

```
// Include the account reference in the app call argument to be populated automatically

const result = await referenceAssetAppClient.send.getAssetTotalSupplyWithArgument({

args: {

asset: referenceAssetId,

},

})

console.log('Method #2 Asset Total Supply', result.return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/asset-reference.ts#L34)

```
# Include the account reference in the app call argument to be populated automatically

result = reference_asset_client.send.get_asset_total_supply_with_arg(

args=GetAssetTotalSupplyWithArgArgs(asset=reference_asset_id),

)

print("Method #2 Asset Total Supply:", result.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/asset_reference.py#L42)

### Method \#3: Manually Input

[Section titled “Method #3: Manually Input”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-3-manually-input-1)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-865)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-866)

```
// Include the account reference in the accountReferences array to be populated

const result = await referenceAssetAppClient.send.getAssetTotalSupply({

args: {},

assetReferences: [referenceAssetId],

})

console.log('Method #3 Asset Total Supply', result.return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/asset-reference.ts#L51)

```
# Include the asset reference in the asset_references array to be populated

result = reference_asset_client.send.get_asset_total_supply(

params=CommonAppCallParams(asset_references=[reference_asset_id]),

)

print("Method #3 Asset Total Supply:", result.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/asset_reference.py#L58)

## App Reference Example

[Section titled “App Reference Example”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#app-reference-example)

Here is a simple smart contract named `ApplicationReference` with two methods that call the `increment` method in the `Counter` smart contract via inner transaction.
The `ApplicationReference` smart contract requires the `Counter` application reference to be provided during invocation.

- [Algorand TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-881)
- [Algorand Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-882)

```
import { Contract, Application, GlobalState, Uint64, itxn, arc4 } from '@algorandfoundation/algorand-typescript'

import type { uint64 } from '@algorandfoundation/algorand-typescript'

/**

* A contract that increments a counter

*/

export class Counter extends Contract {

public counter = GlobalState<uint64>({ initialValue: Uint64(0) })

/**

* Increments the counter and returns the new value

* @returns The new counter value

*/

public increment(): uint64 {

this.counter.value = this.counter.value + 1

return this.counter.value

}

}

/**

* A contract that demonstrates how to use resource usage in a contract using an asset reference

*/

export default class ReferenceApp extends Contract {

/**

* Calls the increment method on another Counter app with a hardcoded app ID

* @returns The incremented counter value from the inner call

*/

public incrementViaInner(): uint64 {

const app = Application(1717) // Replace with your application id

// Call the increment method on the Counter application

const appCallTxn = itxn

.applicationCall({

appId: app.id,

// Use methodSelector to get the ABI selector for the increment method

appArgs: [arc4.methodSelector('increment()uint64')],

fee: 0,

})

.submit()

// Decode the ABI return value from the transaction logs

// The ABI return value is in the last log with a prefix for the ABI return format

return arc4.decodeArc4<uint64>(appCallTxn.lastLog, 'log')

}

/**

* Calls the increment method on another Counter app passed as an argument

* @param app The application to call

* @returns The incremented counter value from the inner call

*/

public incrementViaInnerWithArg(app: Application): uint64 {

// Call the increment method on the provided Counter application

const appCallTxn = itxn

.applicationCall({

appId: app.id,

// Use methodSelector to get the ABI selector for the increment method

appArgs: [arc4.methodSelector('increment()uint64')],

fee: 0,

})

.submit()

// Decode the ABI return value from the transaction logs

// The ABI return value is in the last log with a prefix for the ABI return format

return arc4.decodeArc4<uint64>(appCallTxn.lastLog, 'log')

}

}
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/contracts/ReferenceApp/contract.algo.ts#L1)

```
from algopy import Application, ARC4Contract, UInt64, arc4

from algopy.arc4 import abimethod

"""

A contract that increments a counter

"""

class Counter(ARC4Contract):

def __init__(self) -> None:

self.counter = UInt64(0)

"""

Increments the counter and returns the new value

@returns The new counter value

"""

@abimethod

def increment(self) -> UInt64:

self.counter += 1

return self.counter

"""

A contract that demonstrates how to use resource usage in a contract using an asset reference

"""

class ReferenceApp(ARC4Contract):

"""

Calls the increment method on another Counter app with a hardcoded app ID

@returns The incremented counter value from the inner call

"""

@abimethod

def increment_via_inner(self) -> UInt64:

app = Application(1717)  # Replace with your application id

counter_result, call_txn = arc4.abi_call(

Counter.increment,

fee=0,

app_id=app,

)

return counter_result

"""

Calls the increment method on another Counter app passed as an argument

@param app The application to call

@returns The incremented counter value from the inner call

"""

@abimethod

def increment_via_inner_with_arg(self, app: Application) -> UInt64:

# Call the increment method on the provided Counter application

counter_result, call_txn = arc4.abi_call(Counter.increment, fee=0, app_id=app)

return counter_result
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/smart_contracts/reference_app/contract.py#L1)

Here are three different ways you can provide the app reference when calling a contract method using the AlgoKit Utils library.

### Method \#1: Automatic Resource Population

[Section titled “Method #1: Automatic Resource Population”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-1-automatic-resource-population-2)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-863)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-864)

```
// Configure automatic resource population per app call

const result1 = await referenceAppAppClient.send.incrementViaInner({

args: {},

populateAppCallResources: true,

})

console.log('Method #1 Increment via inner', result1.return)

// Or set the default value for populateAppCallResources to true globally and apply to all app calls

Config.configure({

populateAppCallResources: true,

})

const result2 = await referenceAppAppClient.send.incrementViaInner({

args: {},

extraFee: microAlgos(1000), // additional fee to cover the inner app call

})

console.log('Method #1 Increment via inner', result2.return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/app-reference.ts#L7)

```
# Configure automatic resource population per app call

result1 = reference_app_client.send.increment_via_inner(

send_params=SendParams(populate_app_call_resources=True),

)

print("Method #1 Increment via inner:", result1.abi_return)

# Or set the default value for populate_app_call_resources to true globally and apply to all app calls

config.config.configure(

populate_app_call_resources=True,

)

result2 = reference_app_client.send.increment_via_inner(

params=CommonAppCallParams(

extra_fee=AlgoAmount(micro_algo=1000)

),  # additional fee to cover the inner app call

)

print("Method #1 Increment via inner:", result2.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/app_reference.py#L17)

### Method \#2: Using Reference Types

[Section titled “Method #2: Using Reference Types”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-2-using-reference-types-2)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-857)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-858)

```
// Include the app reference in the app call argument to be populated automatically

const result = await referenceAppAppClient.send.incrementViaInnerWithArg({

args: {

app: 1717n,

},

extraFee: microAlgos(1000), // additional fee to cover the inner app call

})

console.log('Method #2 Increment via inner', result.return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/app-reference.ts#L35)

```
# Include the app reference in the app call argument to be populated automatically

result = reference_app_client.send.increment_via_inner_with_arg(

args=IncrementViaInnerWithArgArgs(app=1717),

params=CommonAppCallParams(

extra_fee=AlgoAmount(micro_algo=1000)

),  # additional fee to cover the inner app call

)

print("Method #2 Increment via inner:", result.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/app_reference.py#L45)

### Method \#3: Manually Input

[Section titled “Method #3: Manually Input”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-3-manually-input-2)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-869)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-870)

```
// Include the app reference in the appReferences array to be populated

const result = await referenceAppAppClient.send.incrementViaInner({

args: {},

appReferences: [1717n],

extraFee: microAlgos(1000), // additional fee to cover the inner app call

})

console.log('Method #3 Increment via inner', result.return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/app-reference.ts#L53)

```
# Include the app reference in the app_references array to be populated

result = reference_app_client.send.increment_via_inner(

params=CommonAppCallParams(

app_references=[1717],

extra_fee=AlgoAmount(

micro_algo=1000

),  # additional fee to cover the inner app call

),

)

print("Method #3 Increment via inner:", result.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/app_reference.py#L63)

## Account + Asset Example

[Section titled “Account + Asset Example”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#account--asset-example)

Here is a simple smart contract with two methods that read the balance of an ASA in an account. This smart contract requires both the asset
reference and the account reference to be provided during invocation.

- [Algorand TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-883)
- [Algorand Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-884)

```
import { Contract, readonly, Account, Asset, assert } from '@algorandfoundation/algorand-typescript'

import { Address } from '@algorandfoundation/algorand-typescript/arc4'

/**

* A contract that demonstrates how to reference both accounts and assets in a smart contract

*/

export default class ReferenceAccountAsset extends Contract {

/**

* Returns the balance of a specific asset in a hardcoded account

* @returns The asset balance of the account

*/

@readonly

public getAssetBalance() {

const address = new Address('R3J76MDPEXQEWBV2LQ6FLQ4PYC4QXNHHPIL2BX2KSFU4WUNJJMDBTLRNEM') // Replace with your account address

const addressBytes = address.bytes

const account = Account(addressBytes)

const asset = Asset(1472) // Replace with your asset ID

assert(account.isOptedIn(asset), 'Account is not opted in to the asset')

return asset.balance(account)

}

/**

* Returns the balance of a specific asset in a provided account

* @param account The account to check the asset balance for

* @param asset The asset to check the balance of

* @returns The asset balance of the account

*/

@readonly

public getAssetBalanceWithArg(account: Account, asset: Asset) {

assert(account.isOptedIn(asset), 'Account is not opted in to the asset')

// Get the asset balance

return asset.balance(account)

}

}
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/contracts/ReferenceAccountAsset/contract.algo.ts#L1)

```
from algopy import Account, ARC4Contract, Asset, UInt64

from algopy.arc4 import abimethod

"""

A contract that demonstrates how to reference both accounts and assets in a smart contract

"""

class ReferenceAccountAsset(ARC4Contract):

"""

Returns the balance of a specific asset in a hardcoded account

@returns The asset balance of the account

"""

@abimethod

def get_asset_balance(self) -> UInt64:

acct = Account(

"WMHF4FLJNKY2BPFK7YPV5ID6OZ7LVDB2B66ZTXEAMLL2NX4WJZRJFVX66M"

)  # Replace with your account address

asset = Asset(1185)  # Replace with your asset id

assert acct.is_opted_in(asset), "Account is not opted in to the asset"

return asset.balance(acct)

"""

Returns the balance of a specific asset in a provided account

@param account The account to check the asset balance for

@param asset The asset to check the balance of

@returns The asset balance of the account

"""

@abimethod

def get_asset_balance_with_arg(self, acct: Account, asset: Asset) -> UInt64:

assert acct.is_opted_in(asset), "Account is not opted in to the asset"

# Get the asset balance

return asset.balance(acct)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/smart_contracts/reference_account_asset/contract.py#L1)

Here are three different ways you can provide both the account reference and the asset reference when calling a contract method using the AlgoKit Utils library.

### Method \#1: Automatic Resource Population

[Section titled “Method #1: Automatic Resource Population”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-1-automatic-resource-population-3)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-867)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-868)

```
// Configure automatic resource population per app call

const result1 = await accountAssetReferenceAppClient.send.getAssetBalance({

args: {},

populateAppCallResources: true,

})

console.log('Method #1 Asset Balance', result1)

// Or set the default value for populateAppCallResources to true globally and apply to all app calls

Config.configure({

populateAppCallResources: true,

})

const result2 = await accountAssetReferenceAppClient.send.getAssetBalance({

args: {},

})

console.log('Method #1 Asset Balance', result2)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/account-asset-reference.ts#L13)

```
# Configure automatic resource population per app call

result1 = account_asset_reference_app_client.send.get_asset_balance(

send_params=SendParams(populate_app_call_resources=True)

)

print("Method #1 Asset Balance", result1.abi_return)

# Or set the default value for populate_app_call_resources to true globally and apply to all app calls

config.config.configure(populate_app_call_resources=True)

result2 = account_asset_reference_app_client.send.get_asset_balance()

print("Method #1 Asset Balance", result2.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/account_asset_reference.py#L28)

### Method \#2: Using Reference Types

[Section titled “Method #2: Using Reference Types”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-2-using-reference-types-3)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-873)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-874)

```
// Include the account and asset references in the app call arguments to be populated automatically

const result = await accountAssetReferenceAppClient.getAssetBalanceWithArg({

args: {

account: 'R3J76MDPEXQEWBV2LQ6FLQ4PYC4QXNHHPIL2BX2KSFU4WUNJJMDBTLRNEM',

asset: referenceAssetId,

},

})

console.log('Method #2 Asset Balance', result)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/account-asset-reference.ts#L40)

```
# Include the account and asset references in the app call arguments to be populated automatically

result = account_asset_reference_app_client.send.get_asset_balance_with_arg(

args=GetAssetBalanceWithArgArgs(

acct="R3J76MDPEXQEWBV2LQ6FLQ4PYC4QXNHHPIL2BX2KSFU4WUNJJMDBTLRNEM",

asset=reference_asset_id,

)

)

print("Method #2 Asset Balance", result.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/account_asset_reference.py#L51)

### Method \#3: Manually Input

[Section titled “Method #3: Manually Input”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-3-manually-input-3)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-861)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-862)

```
// Manually provide both account and asset references in the respective arrays

const result = await accountAssetReferenceAppClient.getAssetBalance({

args: {},

accountReferences: ['R3J76MDPEXQEWBV2LQ6FLQ4PYC4QXNHHPIL2BX2KSFU4WUNJJMDBTLRNEM'],

assetReferences: [referenceAssetId],

})

console.log('Method #3 Asset Balance', result)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/account-asset-reference.ts#L58)

```
# Manually provide both account and asset references in the respective arrays

result = account_asset_reference_app_client.send.get_asset_balance(

params=CommonAppCallParams(

account_references=[\
\
            "R3J76MDPEXQEWBV2LQ6FLQ4PYC4QXNHHPIL2BX2KSFU4WUNJJMDBTLRNEM"\
\
        ],

asset_references=[reference_asset_id],

)

)

print("Method #3 Asset Balance", result.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/account_asset_reference.py#L70)

## Account + Application Example

[Section titled “Account + Application Example”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#account--application-example)

Here is a simple smart contract named `AccountAndAppReference` with two methods that read the local state `my_counter` of an account in the `Counter` smart contract.
The `AccountAndAppReference` smart contract requires both the `Counter` application reference and the account reference to be provided during invocation.

- [Algorand TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-875)
- [Algorand Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-876)

```
import {

Contract,

op,

abimethod,

Account,

Application,

LocalState,

Txn,

Global,

assert,

Bytes,

} from '@algorandfoundation/algorand-typescript'

import type { uint64 } from '@algorandfoundation/algorand-typescript'

import { Address, readonly } from '@algorandfoundation/algorand-typescript/arc4'

/**

* A contract that maintains a per-account counter in local state

* Accounts must opt in to use the counter

*/

export class MyCounter extends Contract {

// Define a local state variable for the counter

public myCounter = LocalState<uint64>({ key: 'my_counter' })

/**

* Initialize the counter when an account opts in

*/

@abimethod({ allowActions: 'OptIn' })

public optIn(): void {

this.myCounter(Txn.sender).value = 0

}

/**

* Increment the counter for the sender and return its new value

* @returns The new counter value

*/

public incrementMyCounter(): uint64 {

assert(Txn.sender.isOptedIn(Global.currentApplicationId), 'Account must opt in to contract first')

this.myCounter(Txn.sender).value = this.myCounter(Txn.sender).value + 1

return this.myCounter(Txn.sender).value

}

}

/**

* A contract that demonstrates how to reference accounts and applications

* to access local state from external contracts

*/

export default class ReferenceAccountApp extends Contract {

/**

* Get the counter value from another account's local state with hardcoded values

* @returns The counter value or 0 if it doesn't exist

*/

@readonly

public getMyCounter(): uint64 {

const address = new Address('WMHF4FLJNKY2BPFK7YPV5ID6OZ7LVDB2B66ZTXEAMLL2NX4WJZRJFVX66M')

const addressBytes = address.bytes

const account = Account(addressBytes)

const app = Application(1717) // Replace with your application id

// Check if the counter value exists in the account's local state for the specified app

const [value, hasValue] = op.AppLocal.getExUint64(account, app, Bytes('my_counter'))

if (!hasValue) {

return 0

}

return value

}

/**

* Get the counter value from another account's local state with provided parameters

* @param account The account to check

* @param app The application to query

* @returns The counter value or 0 if it doesn't exist

*/

@readonly

public getMyCounterWithArg(account: Account, app: Application): uint64 {

// Check if the counter value exists in the account's local state for the specified app

const [value, hasValue] = op.AppLocal.getExUint64(account, app, Bytes('my_counter'))

if (!hasValue) {

return 0

}

return value

}

}
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/contracts/ReferenceAccountApp/contract.algo.ts#L1)

```
from algopy import (

Account,

Application,

ARC4Contract,

Global,

LocalState,

Txn,

UInt64,

op,

)

from algopy.arc4 import abimethod

"""

A contract that maintains a per-account counter in local state

Accounts must opt in to use the counter

"""

class MyCounter(ARC4Contract):

def __init__(self) -> None:

# Define a local state variable for the counter

self.my_counter = LocalState(UInt64)

"""

Initialize the counter when an account opts in

"""

@abimethod(allow_actions=["OptIn"])

def opt_in(self) -> None:

self.my_counter[Txn.sender] = UInt64(0)

"""

Increment the counter for the sender and return its new value

@returns The new counter value

"""

@abimethod

def increment_my_counter(self) -> UInt64:

assert Txn.sender.is_opted_in(Global.current_application_id)

self.my_counter[Txn.sender] += 1

return self.my_counter[Txn.sender]

"""

A contract that demonstrates how to reference accounts and applications

to access local state from external contracts

"""

class ReferenceAccountApp(ARC4Contract):

"""

Get the counter value from another account's local state with hardcoded values

@returns The counter value or 0 if it doesn't exist

"""

@abimethod

def get_my_counter(self) -> UInt64:

acct = Account(

"WMHF4FLJNKY2BPFK7YPV5ID6OZ7LVDB2B66ZTXEAMLL2NX4WJZRJFVX66M"

)  # Replace with your account address

app = Application(1717)  # Replace with your application id

# Check if the counter value exists in the account's local state for the specified app

my_count, exist = op.AppLocal.get_ex_uint64(acct, app, b"my_counter")

if not exist:

return UInt64(0)

return my_count

"""

Get the counter value from another account's local state with provided parameters

@param account The account to check

@param app The application to query

@returns The counter value or 0 if it doesn't exist

"""

@abimethod

def get_my_counter_with_arg(self, acct: Account, app: Application) -> UInt64:

# Check if the counter value exists in the account's local state for the specified app

my_count, exist = op.AppLocal.get_ex_uint64(acct, app, b"my_counter")

if not exist:

return UInt64(0)

return my_count
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/smart_contracts/reference_account_app/contract.py#L1)

Here are three different ways you can provide both the account reference and the application reference when calling a contract method using the AlgoKit Utils library.

### Method \#1: Automatic Resource Population

[Section titled “Method #1: Automatic Resource Population”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-1-automatic-resource-population-4)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-871)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-872)

```
// Configure automatic resource population per app call

const result1 = await referenceAccountAppAppClient.send.getMyCounter({

args: {},

populateAppCallResources: true,

})

console.log('Method #1 My Counter', result1.return)

// Or set the default value for populateAppCallResources to true globally and apply to all app calls

Config.configure({

populateAppCallResources: true,

})

const result2 = await referenceAccountAppAppClient.send.getMyCounter({

args: {},

})

console.log('Method #1 My Counter', result2.return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/account-app-reference.ts#L7)

```
# Configure automatic resource population per app call

result1 = reference_account_app_app_client.send.get_my_counter(

send_params=SendParams(populate_app_call_resources=True)

)

print("Method #1 My Counter", result1.abi_return)

# Or set the default value for populate_app_call_resources to true globally and apply to all app calls

config.config.configure(populate_app_call_resources=True)

result2 = reference_account_app_app_client.send.get_my_counter()

print("Method #1 My Counter", result2.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/account_app_reference.py#L14)

### Method \#2: Using Reference Types

[Section titled “Method #2: Using Reference Types”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-2-using-reference-types-4)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-893)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-894)

```
// Include the account and app references in the app call arguments to be populated automatically

const result = await referenceAccountAppAppClient.send.getMyCounterWithArg({

args: {

account: randomAccountA.addr.toString(),

app: 1717n, // Using the default app ID from the contract

},

})

console.log('Method #2 My Counter', result.return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/account-app-reference.ts#L34)

```
# Include the account and app references in the app call arguments to be populated automatically

result = reference_account_app_app_client.send.get_my_counter_with_arg(

args=GetMyCounterWithArgArgs(

acct=account_a.address,

app=1717,  # Using the default app ID from the contract

)

)

print("Method #2 My Counter", result.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/account_app_reference.py#L37)

### Method \#3: Manually Input

[Section titled “Method #3: Manually Input”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-3-manually-input-4)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-887)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-888)

```
// Manually provide both account and app references in the respective arrays

const result = await referenceAccountAppAppClient.send.getMyCounter({

args: {},

accountReferences: [randomAccountA.addr],

appReferences: [1717n], // Using the default app ID from the contract

})

console.log('Method #3 My Counter', result.return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/account-app-reference.ts#L52)

```
# Manually provide both account and app references in the respective arrays

result = reference_account_app_app_client.send.get_my_counter(

CommonAppCallParams(

account_references=[account_a.address],

app_references=[1717],  # Using the default app ID from the contract

)

)

print("Method #3 My Counter", result.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/account_app_reference.py#L56)

## Application + Box Reference Example

[Section titled “Application + Box Reference Example”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#application--box-reference-example)

Here is a simple smart contract with a methods that increments the counter value stored in a `BoxMap`.
Each box uses `box_counter` \+ `account address` as its key and stores the counter as its value.
This smart contract requires the box reference to be provided during invocation.

- [Algorand TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-895)
- [Algorand Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-896)

```
import {

Contract,

readonly,

Account,

BoxMap,

Txn,

Global,

gtxn,

assert,

Uint64,

GlobalState,

contract,

} from '@algorandfoundation/algorand-typescript'

import type { uint64 } from '@algorandfoundation/algorand-typescript'

/**

* A contract that uses box storage to maintain a counter for each account

* Each account needs to pay for the Minimum Balance Requirement (MBR) for their box

* Constants for box storage are stored in global state

*/

@contract({ stateTotals: { globalUints: 4 } })

export default class ReferenceAppBox extends Contract {

// Define constants for box storage in global state

public keyLength = GlobalState<uint64>({ initialValue: Uint64(32 + 19) }) // Account address (32 bytes) + key prefix overhead (19 bytes)

public valueLength = GlobalState<uint64>({ initialValue: Uint64(8) }) // uint64 (8 bytes)

public boxSize = GlobalState<uint64>() // Calculated in constructor

public boxMbr = GlobalState<uint64>() // Calculated in constructor

// Create a box map to store counter values per account

public accountBoxCounter = BoxMap<Account, uint64>({ keyPrefix: 'counter' })

/**

* Initialize calculated values in constructor

*/

public constructor() {

super()

// Calculate the total box size and MBR in constructor

this.boxSize.value = this.keyLength.value + this.valueLength.value

this.boxMbr.value = Uint64(2500) + this.boxSize.value * Uint64(400) // Base MBR + (size * per-byte cost)

}

/**

* Increments the counter for the transaction sender

* Requires a payment transaction to cover the MBR for the box

* @param payMbr Payment transaction covering the box MBR

* @returns The new counter value

*/

@readonly

public incrementBoxCounter(payMbr: gtxn.PaymentTxn): uint64 {

// Verify the payment covers the MBR cost and is sent to the contract

assert(payMbr.amount === this.boxMbr.value, 'Payment must cover the box MBR')

assert(payMbr.receiver === Global.currentApplicationAddress, 'Payment must be to the contract')

const [counter, hasCounter] = this.accountBoxCounter(Txn.sender).maybe()

if (hasCounter) {

// Increment existing counter

this.accountBoxCounter(Txn.sender).value = counter + 1

return counter + 1

} else {

// Initialize new counter to 1

this.accountBoxCounter(Txn.sender).value = Uint64(1)

return Uint64(1)

}

}

/**

* Gets the current counter value for the transaction sender

* @returns The current counter value or 0 if not set

*/

@readonly

public getBoxCounter(): uint64 {

const [counter, hasCounter] = this.accountBoxCounter(Txn.sender).maybe()

if (hasCounter) {

return counter

}

return 0

}

/**

* Gets the current counter value for any account

* @param account The account to check

* @returns The current counter value or 0 if not set

*/

@readonly

public getBoxCounterForAccount(account: Account): uint64 {

const [counter, hasCounter] = this.accountBoxCounter(account).maybe()

if (hasCounter) {

return counter

}

return 0

}

/**

* Returns the MBR cost for creating a box

* @returns The MBR cost in microAlgos

*/

@readonly

public getBoxMbr(): uint64 {

return this.boxMbr.value

}

/**

* Returns all the box size configuration values

* @returns A tuple containing [keyLength, valueLength, boxSize, boxMbr]

*/

@readonly

public getBoxConfiguration(): [uint64, uint64, uint64, uint64] {

return [this.keyLength.value, this.valueLength.value, this.boxSize.value, this.boxMbr.value]

}

/**

* Updates the box size configuration values

* @param newKeyLength The new key length

* @param newValueLength The new value length

*/

@readonly

public updateBoxConfiguration(newKeyLength: uint64, newValueLength: uint64): void {

this.keyLength.value = newKeyLength

this.valueLength.value = newValueLength

// Recalculate derived values

this.boxSize.value = this.keyLength.value + this.valueLength.value

this.boxMbr.value = Uint64(2500) + this.boxSize.value * Uint64(400)

}

}
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/contracts/ReferenceAppBox/contract.algo.ts#L1)

```
from algopy import Account, ARC4Contract, BoxMap, Global, GlobalState, Txn, UInt64, gtxn

from algopy.arc4 import abimethod

"""

A contract that uses box storage to maintain a counter for each account

Each account needs to pay for the Minimum Balance Requirement (MBR) for their box

Constants for box storage are stored in global state

"""

COUNTER_BOX_KEY_LENGTH = 32 + 19

COUNTER_BOX_VALUE_LENGTH = 8

class ReferenceAppBox(ARC4Contract):

def __init__(self) -> None:

# Define constants for box storage in global state

self.key_length = GlobalState(

UInt64(COUNTER_BOX_KEY_LENGTH)

)  # Account address (32 bytes) + key prefix overhead (19 bytes)

self.value_length = GlobalState(

UInt64(COUNTER_BOX_VALUE_LENGTH)

)  # uint64 (8 bytes)

self.box_size = GlobalState(UInt64)  # Calculated in constructor

self.box_mbr = GlobalState(UInt64)  # Calculated in constructor

# Create a box map to store counter values per account

self.account_box_counter = BoxMap(Account, UInt64, key_prefix="counter")

@abimethod(create="require")

def create(self) -> None:

self.box_size.value = self.key_length.value + self.value_length.value

self.box_mbr.value = UInt64(2_500) + self.box_size.value * UInt64(

400

)  # Base MBR + (size * per-byte cost)

"""

Increments the counter for the transaction sender

Requires a payment transaction to cover the MBR for the box

@param payMbr Payment transaction covering the box MBR

@returns The new counter value

"""

@abimethod

def increment_box_counter(self, pay_mbr: gtxn.PaymentTransaction) -> UInt64:

# Verify the payment covers the MBR cost and is sent to the contract

assert pay_mbr.amount == self.box_mbr.value, "Payment must cover the box MBR"

assert (

pay_mbr.receiver == Global.current_application_address

), "Payment must be to the contract"

counter, has_counter = self.account_box_counter.maybe(Txn.sender)

if has_counter:

self.account_box_counter[Txn.sender] += 1

return self.account_box_counter[Txn.sender]

else:

self.account_box_counter[Txn.sender] = UInt64(1)

return UInt64(1)

"""

Gets the current counter value for the transaction sender

@returns The current counter value or 0 if not set

"""

@abimethod(readonly=True)

def get_box_counter(self) -> UInt64:

counter, has_counter = self.account_box_counter.maybe(Txn.sender)

if has_counter:

return counter

return UInt64(0)

"""

Gets the current counter value for any account

@param account The account to check

@returns The current counter value or 0 if not set

"""

@abimethod(readonly=True)

def get_box_counter_for_account(self, account: Account) -> UInt64:

counter, has_counter = self.account_box_counter.maybe(account)

if has_counter:

return counter

return UInt64(0)

"""

Returns the MBR cost for creating a box

@returns The MBR cost in microAlgos

"""

@abimethod(readonly=True)

def get_box_mbr(self) -> UInt64:

return self.box_mbr.value

"""

Returns all the box size configuration values

@returns A tuple containing [keyLength, valueLength, boxSize, boxMbr]

"""

@abimethod(readonly=True)

def get_box_configuration(self) -> tuple[UInt64, UInt64, UInt64, UInt64]:

return (

self.key_length.value,

self.value_length.value,

self.box_size.value,

self.box_mbr.value,

)

"""

Updates the box size configuration values

@param newKeyLength The new key length

@param newValueLength The new value length

"""

@abimethod

def update_box_configuration(

self, new_key_length: UInt64, new_value_length: UInt64

) -> None:

self.key_length.value = new_key_length

self.value_length.value = new_value_length

# Recalculate derived values

self.box_size.value = self.key_length.value + self.value_length.value

self.box_mbr.value = UInt64(2_500) + self.box_size.value * UInt64(400)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/smart_contracts/reference_app_box/contract.py#L1)

Here are two different ways you can provide the box reference when calling a contract method using the AlgoKit Utils library.

### Method \#1: Automatic Resource Population

[Section titled “Method #1: Automatic Resource Population”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-1-automatic-resource-population-5)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-891)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-892)

```
// Create payment for MBR

const payMbr = await algorand.createTransaction.payment({

amount: microAlgos(boxMBR),

sender: randomAccountA,

receiver: counterAppAddress,

})

// Method 1: Using populateAppCallResources in sendParams

const response1 = await referenceAppBoxAppClient.send.incrementBoxCounter({

args: {

payMbr: payMbr,

},

sender: randomAccountA,

populateAppCallResources: true,

})

console.log('Method #2 Box Counter (explicit)', response1.return)

// Method 2: Configure globally

// Set the default value for populateAppCallResources to true once and apply to all contract invocations

Config.configure({ populateAppCallResources: true })

// Create another payment for MBR

const payMbr2 = await algorand.createTransaction.payment({

amount: microAlgos(boxMBR),

sender: randomAccountA,

receiver: counterAppAddress,

})

// With global configuration, we don't need to specify populateAppCallResources

const response2 = await referenceAppBoxAppClient.send.incrementBoxCounter({

args: {

payMbr: payMbr2,

},

sender: randomAccountA,

})

console.log('Method #1 Box Counter (global)', response2.return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/app-box-reference.ts#L23)

```
# Create payment for MBR

pay_mbr = algorand_client.create_transaction.payment(

PaymentParams(

sender=account_a.address,

receiver=counter_app_address,

amount=AlgoAmount(micro_algo=box_mbr),

)

)

# Method 1: Using populate_app_call_resources in send_params

response1 = reference_app_box_app_client.send.increment_box_counter(

args=IncrementBoxCounterArgs(pay_mbr=pay_mbr),

params=CommonAppCallParams(sender=account_a.address),

send_params=SendParams(populate_app_call_resources=True),

)

print("Method #1 Box Counter (explicit):", response1.abi_return)

# Method 2: Configure globally

# Set the default value for populate_app_call_resources to true once and apply to all contract invocations

config.config.configure(populate_app_call_resources=True)

# Create another payment for MBR

pay_mbr2 = algorand_client.create_transaction.payment(

PaymentParams(

sender=account_a.address,

receiver=counter_app_address,

amount=AlgoAmount(micro_algo=box_mbr),

)

)

# With global configuration, we don't need to specify populate_app_call_resources

response2 = reference_app_box_app_client.send.increment_box_counter(

args=IncrementBoxCounterArgs(pay_mbr=pay_mbr2),

params=CommonAppCallParams(sender=account_a.address),

)

print("Method #1 Box Counter (global):", response2.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/app_box_reference.py#L41)

### Method \#2: Manually Input

[Section titled “Method #2: Manually Input”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#method-2-manually-input)

- [TypeScript](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-889)
- [Python](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#tab-panel-890)

```
const boxPrefix = 'counter' // box identifier prefix

const encoder = new TextEncoder()

const boxPrefixBytes = encoder.encode(boxPrefix) // UInt8Array of boxPrefix

const publicKey = randomAccountB.addr.publicKey

// Create the box reference

const boxReference = new Uint8Array([...boxPrefixBytes, ...publicKey])

// Create payment for MBR

const payMbr = await algorand.createTransaction.payment({

amount: microAlgos(boxMBR),

sender: randomAccountB,

receiver: counterAppAddress,

})

// Call the smart contract with manually specified box reference

const response = await referenceAppBoxAppClient.send.incrementBoxCounter({

args: {

payMbr: payMbr,

},

boxReferences: [boxReference],

sender: randomAccountB,

})

console.log('Method #2 Box Counter', response.return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/typescript-examples/algokit-utils-ts/references/app-box-reference.ts#L84)

```
box_prefix = b"counter"  # box identifier prefix

public_key = account_b.public_key

# Create the box reference

box_reference = box_prefix + public_key

# Create payment for MBR

pay_mbr = algorand_client.create_transaction.payment(

PaymentParams(

sender=account_b.address,

receiver=counter_app_address,

amount=AlgoAmount(micro_algo=box_mbr),

)

)

# Call the smart contract with manually specified box reference

response = reference_app_box_app_client.send.increment_box_counter(

args=IncrementBoxCounterArgs(pay_mbr=pay_mbr),

params=CommonAppCallParams(

sender=account_b.address, box_references=[box_reference]

),

)

print("Method #2 Box Counter:", response.abi_return)
```

[Source](https://github.com/algorandfoundation/devportal-code-examples/blob/refs/heads/main/projects/python-examples/algokit_utils_py_examples/references/app_box_reference.py#L106)

## Access List: A Mutually Exclusive Alternative to Reference Arrays

[Section titled “Access List: A Mutually Exclusive Alternative to Reference Arrays”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#access-list-a-mutually-exclusive-alternative-to-reference-arrays)

Starting with AVM v12 in consensus v41, the Access List, `txn.Access` or `al`, provides a more flexible way to specify resources. It serves as a mutually exclusive alternative to the traditional reference arrays: Accounts, Assets, Applications, Boxes. You cannot use both in the same transaction. Providing an Access List means no foreign arrays are used, and vice versa.

### Key Features

[Section titled “Key Features”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#key-features)

- **Simple Resources**:
  - Address (`d`): References an account (e.g., for balance checks).
  - Asset (`s`): References an ASA (e.g., for params like total supply).
  - App (`p`): References another application (e.g., for global state reads).
- **Complex Resources** (for sublist access):
  - Holding (`h`): Explicitly references an account’s holding of a specific asset (account + asset ID).
  - Locals (`l`): References an account’s local state for a specific app (account + app ID).
  - Box (`b`): References a box with an app index and box name (e.g., for reading/writing box data).
- **Empty BoxRefs**: Use `{}` for boxes where the App ID is unknown or defaults to the current app.

- **Limits**: Up to 16 entries via consensus parameter `MaxAppAccess`, higher than the 8 total for foreign references.

- **Cross-Product vs. Explicit Access**: Traditional foreign arrays enable “cross-product” access (e.g., all combinations of listed accounts and assets for holdings). Access Lists require explicit listing of each needed resource (e.g., specify each holding individually), but allow more granular control and higher limits without combinatorial explosion.

## Access List Examples

[Section titled “Access List Examples”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#access-list-examples)

These examples show how to structure the `al` (Access List) field in an application transaction JSON. In practice, the SDKs set these fields for you.

### Simple Resources

[Section titled “Simple Resources”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#simple-resources)

#### Address Reference

[Section titled “Address Reference”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#address-reference)

This references a single account, e.g., for balance checks.

```
{

"al": [\
\
    {\
\
      "d": "BOBBYB3QD5QGQ27EBYHHUT7J76EWXKFOSF2NNYYYI6EOAQ5D3M2YW2UGEA"\
\
    }\
\
  ]

}
```

#### Asset Reference

[Section titled “Asset Reference”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#asset-reference)

This references a single ASA, e.g., for params like total supply.

```
{

"al": [\
\
    {\
\
      "s": 1010\
\
    }\
\
  ]

}
```

#### Application Reference

[Section titled “Application Reference”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#application-reference)

This references another application, e.g., for global state reads.

```
{

"al": [\
\
    {\
\
      "p": 1042\
\
    }\
\
  ]

}
```

### Complex Resources

[Section titled “Complex Resources”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#complex-resources)

#### Holding Reference

[Section titled “Holding Reference”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#holding-reference)

This explicitly references an account’s holding of a specific asset. Requires including the address and asset.

```
{

"al": [\
\
    {\
\
      "d": "BOBBYB3QD5QGQ27EBYHHUT7J76EWXKFOSF2NNYYYI6EOAQ5D3M2YW2UGEA"\
\
    },\
\
    {\
\
      "s": 1010\
\
    },\
\
    {\
\
      "h": {\
\
        "d": 1,\
\
        "s": 2\
\
      }\
\
    }\
\
  ]

}
```

Explanation: The holding (`h`) points to the 1st address (`d:1`) and 2nd asset (`s:2`) in the list.

#### Locals Reference

[Section titled “Locals Reference”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#locals-reference)

This references an account’s local state for a specific app. Requires including the app and address.

```
{

"al": [\
\
    {\
\
      "p": 1042\
\
    },\
\
    {\
\
      "d": "BOBBYB3QD5QGQ27EBYHHUT7J76EWXKFOSF2NNYYYI6EOAQ5D3M2YW2UGEA"\
\
    },\
\
    {\
\
      "l": {\
\
        "d": 2,\
\
        "p": 1\
\
      }\
\
    }\
\
  ]

}
```

#### Box Reference

[Section titled “Box Reference”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#box-reference)

This references a box with an app index and box name.

```
{

"al": [\
\
    {\
\
      "p": 1042\
\
    },\
\
    {\
\
      "b": {\
\
        "i": 1,\
\
        "n": "Ym94TmFtZQ=="\
\
      }\
\
    }\
\
  ]

}
```

### Empty BoxRefs

[Section titled “Empty BoxRefs”](https://dev.algorand.co/concepts/smart-contracts/resource-usage/#empty-boxrefs)

This provides extra budget without specifying a particular box.

```
{

"al": [{}]

}
```

Ask AI

reCAPTCHA

Recaptcha requires verification.

protected by **reCAPTCHA**
