Skip to content
This new developer portal is under construction. For complete documentation, please refer to the old developer portal.

Global Storage

Global state is associated with the app itself Global storage is a feature in Algorand that allows smart contracts to persistently store key-value pairs in a globally accessible state. This guide provides comprehensive information on how to allocate, read, write, and manipulate global storage within smart contracts.

Manipulating Global State Storage

Smart contracts can create, update, and delete values in global state using TEAL (Transaction Execution Approval Language) opcodes. The number of values that can be written is limited by the initial configuration set during smart contract creation. State is represented as key-value pairs, where keys are stored as byte slices (byte-array values), and values can be stored as either byte slices or uint64 values. TEAL provides several opcodes for facilitating reading and writing to state, including app_global_put, app_global_get, app_global_get_ex.

Allocation

Global storage can include between 0 and 64 key/value pairs and a total of 8K of memory to share among them. The amount of global storage is allocated in key/value units and determined at contract creation, which cannot be edited later. The contract creator address is responsible for funding the global storage by an increase to their minimum balance requirement.

1
def __init__(self) -> None:
2
self.global_int_full = GlobalState(UInt64(50)) # UInt64 with default value = 50
3
self.global_int_simplified = UInt64(
4
10
5
) # UInt64 simplified with default value = 10
6
self.global_int_no_default = GlobalState(UInt64) # UInt64 with no default value
7
8
# example: INIT_BYTES
9
self.global_bytes_full = GlobalState(
10
Bytes(b"Hello")
11
) # Bytes with default value = bytes(Hello)
12
self.global_bytes_simplified = Bytes(
13
b"Hello"
14
) # Bytes simplified with default value = bytes(Hello)
15
self.global_bytes_no_default = GlobalState(Bytes) # Bytes with no default value
16
# example: INIT_BYTES
17
18
self.global_bool_simplified = True # Bool
19
self.global_bool_no_default = GlobalState(bool) # Bool
20
21
self.global_asset = GlobalState(Asset) # Asset
22
self.global_application = GlobalState(Application) # Application
23
self.global_account = GlobalState(Account) # Account

Reading from Global State

The global storage of a smart contract can be read by any application call that specifies the contract’s application ID in its foreign apps array. The key-value pairs in global storage can be read on-chain directly, or off-chain using SDKs, APIs, and the goal CLI. Only the smart contract itself can write to its own global storage.

TEAL provides opcodes to read global state values for the current smart contract. The app_global_get opcode retrieve values from the current contract’s global storage, respectively. The app_global_get_ex opcode returns two values on the stack: a boolean indicating whether the value was found, and the actual value if it exists.

These _ex opcodes allow reading global states from other accounts and smart contracts, as long as the account and contract are included in the accounts and applications arrays. Branching logic is typically used after calling the _ex opcodes to handle cases where the value is found or not found.

1
@arc4.abimethod
2
def get_global_state(self) -> UInt64:
3
return self.global_int_full.get(default=UInt64(0))
4
5
@arc4.abimethod
6
def maybe_global_state(self) -> tuple[UInt64, bool]:
7
int_value, int_exists = self.global_int_full.maybe() # uint64
8
if not int_exists:
9
int_value = UInt64(0)
10
return int_value, int_exists
11
12
@arc4.abimethod
13
def get_global_state_example(self) -> bool:
14
assert self.global_int_full.get(default=UInt64(0)) == 50 # uint64
15
assert self.global_int_simplified == UInt64(10) # get function cannot be used
16
assert self.global_int_no_default.get(default=UInt64(0)) == 0
17
18
assert self.global_bytes_full.get(Bytes(b"default")) == b"Hello" # byte
19
return True

Refer Sinppet Source to get global storage value for different data types

In addition to using TEAL, the global state values of a smart contract can be read externally using SDKs and the goal CLI. These reads are non-transactional queries that retrieve the current state of the contract.

Example command:

Terminal window
goal app read --app-id 1 --guess-format --global --from <ADDRESS>

This command returns the global state of the smart contract with application ID 1, formatted for readability.

Example Output

Output.json
1
{
2
"Creator": {
3
"tb": "FRYCPGH25DHCYQGXEB54NJ6LHQG6I2TWMUV2P3UWUU7RWP7BQ2BMBBDPD4",
4
"tt": 1
5
},
6
"MyBytesKey": {
7
"tb": "hello",
8
"tt": 1
9
},
10
"MyUintKey": {
11
"tt": 2,
12
"ui": 50
13
}
14
}

Interpretation:

  • The keys are Creator, MyBytesKey, and MyUintKey.
  • The tt field indicates the type of the value: 1 for byte slices (byte-array values), 2 for uint64 values.
  • When tt=1, the value is stored in the tb field. The --guess-format option automatically converts the Creator value to an Algorand address with a checksum (instead of displaying the raw 32-byte public key).
  • When tt=2, the value is stored in the ui field.

The app_global_get_ex is used to read not only the global state of the current contract but any contract that is in the applications array. To access these foreign apps, they must be passed in with the application call.

Terminal window
goal app call --foreign-app APP1ID --foreign-app APP2ID

In addition to modifying its own global storage, a smart contract can read the global storage of any contract specified in its applications array. However, this is a read-only operation. The global state of other smart contracts cannot be modified directly. External smart contracts can be changed per smart contract call (transaction).

Writing to Global State

Can only be written by smart contract. To write to global state, use the app_global_put opcode.

1
@arc4.abimethod
2
def set_global_state(self, value: Bytes) -> None:
3
self.global_bytes_full.value = value

Refer Sinppet Source to set global storage value for different data types

Deleting Global State

Global storage is deleted when the corresponding smart contract is deleted. However, the smart contract can clear the contents of its global storage without affecting the minimum balance requirement.

1
@arc4.abimethod
2
def del_global_state(self) -> bool:
3
del self.global_int_full.value
4
return True

Refer Sinppet Source to delete global storage value for different data types

Summary of Global State Operations

For manipulating global storage data like reading, writing, deleting and checking if exists:

TEAL: Different opcodes can be used

FunctionDescription
app_global_getGet global data for the current app
app_global_get_exGet global data for other app
app_global_putSet global data to the current app
app_global_delDelete global data from the current app
app_global_get_exCheck if global data exists for the current app
app_global_get_exCheck if global data exists for the other app

Different functions of globalState class can be used. The detailed api reference can be found here

FunctionDescription
GlobalState(type_)Initialize a global state with the specified data type
get(default)Get data or a default value if not found
maybe()Get data and a boolean indicating if it exists