Discover AVM 1.0
This week marks a major milestone release for the Algorand blockchain. We are pleased to announce the release of the 1.0 version of the Algorand Virtual Machine (AVM). This release is accompanied by a whole new Developer Portal experience, with new guides to get you up and running quickly! This article will cover some of the highlights that are now available in the AVM in addition to some additional blockchain changes.
Discover what’s new with a brand new Developer Portal experience
Algorand’s developer site has been updated with a whole new look and feel! We’ve added brand new getting started guides that will teach you the basics of blockchain, how to build dApps, tokenize assets, and integrate with the Algorand blockchain. We will take you through a guided tour of how to tokenize and auction an asset using virtually all of the technologies available on Algorand. The auction is implemented with a Python smart contract that showcases many of the AVM 1.0 features. These guides are further enhanced to allow you to run examples on repl.it instantly with no setup required.
The Get details section has been updated as well to reflect all changes to Algorand in this latest release. Make sure to check out getting started and get details on the revised developer site.
Note
As a particular note of interest, Algorand has renamed stateful and stateless smart contracts to smart contracts and smart signatures to better reflect their use case. See the new Developer Portal to read all about them!
AVM 1.0 features
With this release of the AVM, smart contracts are much more full-featured. In addition to looping and subroutines from the 0.9 release, contracts can now issue transactions and function as escrows. Contracts also now support opcode budget pooling which allows building contracts with much longer run times. The limit for the number of smart contracts that can be opted into has been increased to 50 and many new TEAL opcodes have been added.
Inner transactions
Smart contracts now have the ability to generate transactions! Any smart contract can generate up to 16 transactions. These are referred to as Inner Transactions. These inner transactions are actually contained in the application transaction that triggers the smart contract to execute and are applied within the same block as the outer transaction. Inner transactions can also take advantage of fee pooling allowing either the outer application transaction or some other transaction within an atomic transaction group to pay the transaction fees. As a simple example, here is PyTeal snippet for creating a simple payment transaction.
Seq(
InnerTxnBuilder.Begin(),
InnerTxnBuilder.SetFields(
{
TxnField.type_enum: TxnType.Payment,
TxnField.receiver: Txn.sender(),
TxnField.amount: Int(5000),
}
),
InnerTxnBuilder.Submit(),
)
Because smart contracts can now do inner transactions, they can function as escrow accounts where payouts are determined by on-chain logic which can be verified by anyone. This also means every smart contract will have an Algorand address generated as part of its deployment. This is in addition to the unique ID that is currently generated. The goal
command-line tool has been enhanced to provide this address for any created smart contract. This information can also be retrieved by any of the SDKs.
./goal app info --app-id=1234 -d data
Outputs:
Application ID: 1234
Application account: WCS6TVPJRBSARHLN2326LRU5BYVJZUKI2VJ53CAWKYYHDE455ZGKANWMGM
Creator: GBPNTV4Z6N74SOK4FJET73B5UW6SJ5DZGACBNT7WY36W5V5CYBON4ZXUAM
Approval hash: LBASN64GUZO5367IYC2AOCV4F2G5TDZWTJFIUVZ5V2ONCS23HG7TMTPPCE
Clear hash: 2GGBZSOTPJAQV4GCAWVRGREDGUDF66EK4A5Y4JBKA4H2XUEZHXXY44MBFA
Max global byteslices: 0
Max global integers: 1
Max local byteslices: 0
Max local integers: 0
Where the account is listed as Application account.
In addition to standard payment transactions, All asset transactions can be initiated in an inner transaction. This includes creating, deleting, transferring, freezing, or revoking an asset. Smart contracts that create an asset can issue asset configuration transactions allowing them to modify the asset’s mutable properties as well. Smart contracts can also opt into an existing Asset. Some examples are shown below.
Opting a smart contract into an existing asset. Similar logic can be used to transfer an asset.
Seq(
InnerTxnBuilder.Begin(),
InnerTxnBuilder.SetFields(
{
TxnField.type_enum: TxnType.AssetTransfer,
TxnField.xfer_asset: assetID,
TxnField.asset_receiver: Global.current_application_address(),
TxnField.asset_amount: Int(0),
}
),
InnerTxnBuilder.Submit(),
)
Creating an Asset.
Seq(
InnerTxnBuilder.Begin(),
InnerTxnBuilder.SetFields(
{
TxnField.type_enum: TxnType.AssetConfig,
TxnField.config_asset_name: Byte('gold'),
TxnField.config_asset_unit_name: Byte('oz'),
TxnField.config_asset_total: Int(10000000),
TxnField.config_asset_decimals: Int(3),
TxnField.config_asset_url: Byte('https://gold.rush/'),
TxnField.config_asset_manager: Global.current_application_address(),
TxnField.config_asset_reserve: Global.current_application_address(),
TxnField.config_asset_freeze: Global.current_application_address(),
TxnField.config_asset_clawback: Global.current_application_address(),
}
),
InnerTxnBuilder.Submit(),
App.globalPut(created_asa_key, InnerTxn.created_asset_id()),
Return(Int(1)),
)
Note that in the above examples, the smart contract is the sender. This field is not explicitly set as this is the default. Other Algorand accounts can be rekeyed to a smart contract allowing the smart contract to control the rekeyed accounts assets and algos. When doing this, the smart contract should set the sender field to the rekeyed account. Note that the account must also be in the accounts array to enable this functionality.
Inner transactions provide a significant improvement to smart contracts and should simplify applications development. To read more about inner transactions, see the new developer documentation that is available.
Pooled opcode budget
The AVM bounds all smart contracts on runtime by using an opcode budget. This is a numerical value that represents the amount of computing power the smart contract uses on any particular call to the smart contract. If the budget is exceeded the contract will fail. With the AVM 1.0 release, this budget can be extended by grouping the application transaction with additional application transactions. When grouped, multiple application transactions combine their allotted opcode budget into one large budget. This effectively allows longer running smart contract calls when grouped with contract calls that are very quick. To read more about opcode budgets see the AVM documentation.
Opt in to more contracts
Smart contracts can store values on the Algorand blockchain. As part of this they can store values that are specific to the contract and global in nature. In addition, smart contracts can store values for a specific user that is interacting with the contract. These are called local state variables. If a smart contract needs to use local variables the individual account must opt into the contract. If local variables are not used, the accounts are not required to opt into the smart contract to interact with it. With this release, the number of contracts an account can opt into has been upped from 10 contracts to 50. To read more about global and local variables in smart contracts, see the developer documentation.
Additional opcodes
Algorand smart contracts have a set of calls that the AVM interprets when running a smart contract. These are referred to as opcodes and can be thought of as functions available to smart contracts. With this release, new opcodes are available for various functions, including new verification opcodes, new opcodes for manipulating the stack, and additional opcodes for getting grouped transaction properties. One specific new opcode is Log
. This opcode allows the contract to log information within the contract execution. These log entries are written to the blockchain as part of the completed transaction. This effectively gives the smart contract the ability to return a value. With AVM 1.0, smart contracts can issue up 32 separate log calls with a total of 1kb of data that will be stored as part of the transaction. To execute the log
opcode using PyTeal, use the following code.
Log(Bytes(‘Value that needs to be logged’))
To see the updated list of opcodes available to smart contracts see the documentation.