IRIS Improvements

IRIS hardfork – the long anticipated protocol improvements

Almost a year and a half has passed since the lima hardfork. The time has come to upgrade the protocol with iris. This is the first potential hard fork after the three
initially scheduled ones and thus it requires a community vote. In the following
sections we will go through the improvements that iris brings. There is no big,
new functionality, but rather a lot of significant improvements and bug fixes for
the existing ones. The biggest changes are in the realm of smart contracts but
there are also some positive changes in every part of the protocol.

As there has been mention of it in the public channels, it is worth mentioning that
iris is not a HyperChain release.

FATE improvements

lima introduced the Fast Aetenity Transaction Engine (FATE) which made contracts more efficient both in terms of computations required to run a contract and of the memory footprint of a contract. Ever since, we’ve been growing our knowledge base, doing R&D on how we can further improve it. This is how FATE VM v2 was born. It brings a lot of enhancements under the hood but what users will actually notice are the new primitives:

  • Native BLS12-381 crypto pairing operations. At last there will be Zero-Knowledge (ZK) proofs on Æternity. This could benefit both on-chain and offchain contract calls and it is a great addition to the arsenal of tools Æ already has.

  • AENS has been revised and certain opcodes have been added: AENS.update (now you can update name pointers from a contract) and AENS.lookup (now you can inspect existing names in a contract). This will improve further the usability of names. There are some bug fixes there: AENS.resolve used to crash on an invalid name and the TTL of preclaim transactions was always set to 0, disregarding the value provided.

  • Oracles has been improved with a new primop: Oracle.expiry so a contract can inspect when an oracle expires on-chain.

  • Chain.block_hash(Chain.block_height) used to always return None. Now it returns whatever is the current generation’s key block hash.

  • Transaction introspection in generalized accounts via Auth.tx - generalized accounts now can perform deep inspection of the transaction to be authenticated. Dry-run endpoints can optionally access Auth.tx.

  • The string operations have been revisited as well: there are some new ones -, and Char.to_lower/upper which can help with conversion of data. The String.length now returns the length of to_list on the string instead of its byte_size, which feels much more natural from a user’s perspective.

  • Adds a new named argument “protected : bool” to remote contract calls. A remote call with protected = true gets its result wrapped in an option type, with failing calls returning None. When the protected call fails then any side effects from executing the protected call are rolled back.

  • The persisted on-chain bytecode now includes the compiler version.

  • One of the improvements under the hood is that the FATE VM v2 garbage collector had been reworked - from iris some operations are much cheaper, especially nested maps.

  • The persisted on-chain bytecode now includes the init function. The init function is not callable after deployment but can be used to clone an existing contract.

  • Contract factories - Solidity-style contract creation capabilities come to Sophia. The factories bring a lot of improvements with regards to user experience, for example DeFi services on Æ can now be wrapped in a single transaction. This is something we’ve discussed a lot and due to popular demand, will be included in iris.

  • Contract cloning: cheap and reusable clones of existing on-chain contracts.

  • Contract bytecode introspection - contracts now can query the code hash of existing FATE contracts - further improving UX and improving the security of Æ based DEFI services.

Paying Transaction paying_for

Currently in order to include transactions, one must have a balance to start with,
as at least some fees are required for a transaction. iris brings the functionality
to wrap your transaction in a special new paying_for transaction. This allows a new entity for the transaction - so called payer - to cover the fees and the gas cost on behalf of the origin. Note that any amount spent by the origin still will be deducted from their account and not the payer's. Still, this allows onboarding
users without existing accounts for various business cases.


The aens support has been around ever since the roma release but has undergone a few iterations and improvements during its lifespan. The latest ones originate from the community. For example the name expiration time was a pain point for users all along. It used to be 50000 generations (~100 days) which means in order for your names not to expire - you must update them more than 3 times a year. Since names are intended to act like DNS on the blockchain, this feels unnatural and leads to bad UX and expired names. There was an on-chain vote in order to let the community decide what would be better. The community spoke and name expirations were changed accordingly to 180000 generations (~375 days). Another improvement regarding names is the restriction of AENS name pointers.The goal of names is to provide shortcuts to certain addresses and some of those are predefined (like account_pubkey, contract_pubkey and oracle_pubkey) but there is also support for users to create their own. Since now the network is maturing we propose certain restrictions so the aens is more finely tuned, ex: no duplicate pointer keys are allowed anymore, a maximum number of pointers is enforced per name and now there is a certain restriction on key length.

Generalized accounts

Generalized accounts allow for newer and greater authentication methods, better
fitting the specific use case of the user. This is further improved with the ZK proof
support in FATE VM v2. The changes to GA here in iris are incremental and simply polish: the pricing model is improved and the TTL handling of transactions is more finely tuned.

AEVM deprecation

AEVM was the initial smart contract VM. It was based on the EVM (Ethereum Virtual
Machine) but since now we have the much more efficient FATE VM, it is rendered
obsolete. For some time now it has only imposed a technical debt while it brings
absolutely no added value. We deprecate it from iris on. This will allow us to add
more opcodes faster.

State Channels

State channels provide means for virtually unlimited transaction throughput by
moving those transactions off-chain. They rely on participants being online, protecting their own interest. This assumption is not always a practical one and
that is why we have delegates: a third party that can provide off-chain state onchain in order to protect the interest of a participant. We have revisited delegates and completely reworked them. From iris on, delegates are per participant. They can not only provide slash transactions but if needed they can also provide a snapshot. If the channel is already closing and a participant has enough stake in a contract, a delegate can even do a force_progress on their behalf. This all makes delegates a much more useful and powerful tool for keeping participants safe offchain. So far the list of delegates was immutable: one could not change them after the channel had been created which is particularly bad for long running state channels. From iris on there is a new transaction type - set_delegates that allows participants to modify the list of delegates while the channel is running.

Bug fixing

We have identified an odd bug in force_progress: if a participant calls a contract offchain and this call fails, the amount in the call is still locked in the contract. This behaviour is even more odd when the function called is not payable. This off-chain propagated on-chain via force_progress transaction. All of this is fixed in iris.


Oracles provide data from the physical world on-chain. So far one had to query an
oracle using its address, but iris brings the functionality of named oracles as well: if there is an aens record for that name and it has a set pointer for key oracle_pubkey - one will be able to use the name handle in their query transactions.