Smart Contracts on Algorand Best Practises - Part 1
A smart contract connects functions and lines of code and works out a contract between the two. Nowadays they are a certain standard for decentralized applications and finance. Additionally, they enhance security by immutably recording outcomes on the underlying blockchain.
Our Team focuses on constructing and auditing smart contracts, that's why we decided to prepare a compendium of our knowledge for you that compiles best practices for smart contract creation. Apart from focusing on smart contracts, the other angle is highlighting smart contracts on the Algorand Blockchain. As official partners of Algorand we do believe in the highest quality of Algorand projects and can vouch for Algorand’s highly advanced and open source technology, that is well-positioned to create a borderless economy where everyone can participate. This blog post was co-written with Łukasz Ptak, Ulam Labs Blockchain Developer.
The Benefits of Algorand Smart Contracts
Algorand provides strong benefits to businesses that want to create their app on the blockchain. Mainly, the Algorand blockchain was designed as a smart contract platform with scalability in mind. It can include thousands of transactions in each block. Transactions are final immediately after being included there, what means that the waiting time for a confirmation can be less than 5 seconds. Additionally, the transactions there are very cheap (~$0.001).
The developer experience has become much better over the past few months, the documentation has been improved and if the information is lacking, there is a Discord Channel and official forums where questions are answered by very active Algorand developers.
Key strategies around Security to consider
- In many cases, some of the application’s endpoints can only be called out in a certain order. For example, there might be an initialization step, for which a special “initialize” endpoint has to be called before any other interaction can happen. Similarly, there could be a deprecation step which will allow only certain endpoints to be accessed. In such cases, it’s a good idea to have a special global state variable that determines the current “phase” of the app and each method has to check whether it is executed in the phase it’s meant to be. Don’t rely on magic numbers or implied state.
- Since TEALv5 release it’s possible to create a smart contract that can directly make transactions from its own account. This approach is much safer than the legacy SSC + escrow solution.
- While validating transactions, pay close attention to the fields that appear in a given transaction type. For example the sender and receiver fields of an Algo transfer are called “sender” and “receiver” respectively. However, the sender and receiver of an asset transfer are “sender” and “asset_receiver” respectively. The “asset_sender” field is completely unrelated to a standard ASA transfer.
- It should not be possible to call a named method with OnComplete set different than NoOp. When creating an entry point for a smart contract, it’s usually a good idea to firstly branch off based on the OnComplete code, and only if it’s NoOp try to branch to a specific method. Example of this can be found in the official PyTEAL introduction.
- Minimize the amount of endpoints, in general it’s easier to test a smart contract that exposes less of them.
- During smart contract design process think about invariants of calculations that are performed during a state transition. Test if those invariants are actually held.
Strategies to make the code of the smart contract run faster
In terms of contract code there are two key limitations to pay attention to: contract size and execution cost. There is a default opcode budget of 700, which only allows the contract to perform a limited amount of operations. Such a small upper bound is intentional, as it allows the Algorand blockchain to process many application calls in each block. Many general code optimization techniques apply in smart contract development as well.
Here are some examples of optimizations that apply to Algorand:
- Pay attention to opcode cost of specific operations.
- Avoid using byte math when unnecessary, as almost every Bytes operation is an order of magnitude more expensive.
- Move expensive calculations off-chain. Occasionally, it’s possible to compute a complex formula’s result off-chain and validate the result on-chain (this could possibly be done with significantly less computation).
If you run into a situation where the opcode quota is exceeded and there is no good optimization for the worst case path, it might simply be better to increase the quota. Just remember that “Premature optimization is the root of all evil”.
Important facts around the Teal and PyTeal language to keep in mind
PyTEAL provides a lot of useful abstraction for applications. However, it’s important to know what happens with the compiled code and how AVM works. Knowledge of TEAL is very useful during debugging as it’s not quite possible to debug PyTEAL directly. With each blockchain there are a lot of subtle differences that one needs to be aware of. With each created solution it is best to validate the ideas with a set of on-chain tests.
This article is only the first part of our knowledge compendium around Smart Contracts on Algorand. Further parts will follow soon.
If you are interested in bringing your ideas to life and creating smart contracts on Algorand, please let us know. We embrace every opportunity of a crypto related project.