Asset Information¶
In addition to manipulating state on the blockchain, stateful smart contracts can also look up information about assets and account balances.
Algo Balances¶
The Balance
expression can be used to look up an account’s balance in microAlgos (1 Algo = 1,000,000 microAlgos).
For example,
senderBalance = Balance(Int(0)) # get the balance of Txn.accounts[0] (the sender)
account1Balance = Balance(Int(1)) # get the balance of Txn.accounts[1]
The MinBalance
expression can be used to find an account’s minimum balance.
This amount is also in microAlgos. For example,
senderMinBalance = MinBalance(Int(0)) # get the minimum balance of Txn.accounts[0] (the sender)
account1MinBalance = MinBalance(Int(1)) # get the minimum balance of Txn.accounts[1]
Additionally, Balance
and MinBalance
can be used together to calculate how many Algos
an account can spend without closing. For example,
senderSpendableBalance = Balance(Int(0)) - MinBalance(Int(0)) # calculate how many Algos Txn.accounts[0] (the sender) can spend
account1SpendableBalance = Balance(Int(1)) - MinBalance(Int(1)) # calculate how many Algos Txn.accounts[1] can spend
Asset Holdings¶
In addition to Algos, the Algorand blockchain also supports additional on-chain assets called Algorand Standard Assets (ASAs).
The AssetHolding
group of expressions can be used to look up information about the ASAs that
an account holds.
Similar to external state expressions, these expression return a MaybeValue
.
This value cannot be used directly, but has methods MaybeValue.hasValue()
and MaybeValue.value()
.
If the account has opted into the asset being looked up, hasValue()
will return 1
and value()
will return the value being looked up (either the asset’s balance or frozen status).
Otherwise, hasValue()
and value()
will return 0
.
Balances¶
The AssetHolding.balance
expression can be used to look up how many units of an asset an
account holds. For example,
# get the balance of Txn.accounts[0] (the sender) for asset 31566704
# if the account is not opted into that asset, returns 0
senderAssetBalance = AssetHolding.balance(Int(0), Int(31566704))
program = Seq([
senderAssetBalance,
senderAssetBalance.value()
])
# get the balance of Txn.accounts[1] for asset 27165954
# if the account is not opted into that asset, exit with an error
account1AssetBalance = AssetHolding.balance(Int(1), Int(27165954))
program = Seq([
account1AssetBalance,
Assert(account1AssetBalance.hasValue()),
account1AssetBalance.value()
])
Frozen¶
The AssetHolding.frozen
expression can be used to check if an asset is frozen for an account.
A value of 1
indicates frozen and 0
indicates not frozen. For example,
# get the frozen status of Txn.accounts[0] (the sender) for asset 31566704
# if the account is not opted into that asset, returns 0
senderAssetFrozen = AssetHolding.frozen(Int(0), Int(31566704))
program = Seq([
senderAssetFrozen,
senderAssetFrozen.value()
])
# get the frozen status of Txn.accounts[1] for asset 27165954
# if the account is not opted into that asset, exit with an error
account1AssetFrozen = AssetHolding.frozen(Int(1), Int(27165954))
program = Seq([
account1AssetFrozen,
Assert(account1AssetFrozen.hasValue()),
account1AssetFrozen.value()
])
Asset Parameters¶
Every ASA has parameters that contain information about the asset and how it behaves. These
parameters can be read by TEAL applications for any asset in the Txn.assets
array.
The AssetParam
group of expressions are used to access asset parameters. Like AssetHolding
,
these expressions return a MaybeValue
.
The hasValue()
method will return 0
only if the asset being looked up does not exist
(i.e. the ID in Txn.assets
does not represent an asset).
For optional parameters that are not set, hasValue()
will still return 1
and value()
will return a zero-length byte string (all optional parameters are TealType.bytes
).
The different parameters that can be accessed are summarized by the table below. More information about each parameter can be found on the Algorand developer website.
Expression | Type | Description |
---|---|---|
AssetParam.total() |
TealType.uint64 |
The total number of units of the asset. |
AssetParam.decimals() |
TealType.uint64 |
The number of decimals the asset should be formatted with. |
AssetParam.defaultFrozen() |
TealType.uint64 |
Whether the asset is frozen by default. |
AssetParam.unitName() |
TealType.bytes |
The name of the asset’s units. |
AssetParam.name() |
TealType.bytes |
The name of the asset. |
AssetParam.url() |
TealType.bytes |
A URL associated with the asset. |
AssetParam.metadataHash() |
TealType.bytes |
A 32-byte hash associated with the asset. |
AssetParam.manager() |
TealType.bytes |
The address of the asset’s manager account. |
AssetParam.reserve() |
TealType.bytes |
The address of the asset’s reserve account. |
AssetParam.freeze() |
TealType.bytes |
The address of the asset’s freeze account. |
AssetParam.clawback() |
TealType.bytes |
The address of the asset’s clawback account. |
Here’s an example that uses an asset parameter:
# get the total number of units for Txn.assets[0]
# if the asset is invalid, exit with an error
assetTotal = AssetParam.total(Int(0))
program = Seq([
assetTotal,
Assert(assetTotal.hasValue()),
assetTotal.value()
])