Architectures of Elrond and EOSIO

cc32d9
6 min readMar 7, 2021

Elrond is a relatively new player on the blockchain market, offering a new and scalable platform for WASM smart contracts. In this article I summarize the differences, advantages and disadvantages between two platforms that I found while reading through Elrond documentation. As I’m mostly working in EOSIO environment, this is probably not a very objective review.

Accounts and fees

EOSIO accounts are 64-bit integers represented in alphanumeric notation. The user has a possibility to pick human-readable names. Account permissions delegate the authorization to public keys (or a combination of keys for multi-signature), and the system supports multiple ECC key standards. Currently secp256k1, secp256r1, and Webauthn keys are supported.

Elrond accounts are 256-bit public keys, similar to Ethereum. Ed25519 signatures are in use.

In order to transact, an EOSIO account needs to spend its CPU and NET allowance. Typically this is regulated by staking of the system token. There are also mechanisms for other accounts to sponsor the transaction CPU and NET. Also a smart contract action may require the user to spend some RAM from the account allowance, and the user needs to buy enough RAM in advance.

On Elrond, the sender account is charged a fee in EGLD for each transaction. The smart contract data storage is unlimited, and each read and write operation deducts a gas fee proportional to the length of key and value. The owner of the contract receives 30% of collected fees.

Transaction execution

An Elrond transaction consists of one method invocation on one smart contract. The transaction fee is proportional to the number of WASM instructions executed. There is a hard limit of 1.5Billion wei on gas fees for any single transaction. If a transaction fails, it does not alter the contract memory state, but the fee is deducted, and the transaction is recorded in a block.

EOSIO allows atomic execution of multiple actions on multiple smart contracts. The transaction input may consist of several action executions, and each action may spawn other action executions if needed by the contract logic. Each action is executed in an isolated WASM virtual machine, and only one at a time: if action X spawns another action Y, the Y is executed after X finishes, in a stacked order. If any of actions fails, the whole transaction fails, and it’s not recorded in a block. Also the CPU allowance is not deducted in a failed transaction, and contract RAM state stays intact.

Block signing

In EOSIO, accounts register themselves as block producer candidates, and then the governance mechanism is assigning some of them to block production. Typically 21 producers are selected by voting among staked token holders. Voting can also be delegated via proxies, and the proxy owner decides how to distribute the votes. Typically the 2/3+1 of the top 21 producers have the privilege to update the system smart contract and enforce certain actions, such as changing the authority of accounts. The EOSIO system contract is completely customizable, so the producer assignment and superuser privileges are solely dependent on the agreed governance model, and not fixed in stone by the core software.

In Elrond, blocks are signed by validators in a randomized schedule. Each validator needs to stake 2500 EGLD (around $350k in current prices) in order to be eligible for block signing. I didn’t spend enough time on learning the governance model at Elrond. The blockchain is split in multiple shards, and there’s a communication mechanism between them, enabling virtually unlimited scaling.

EOSIO finality is achieved by 2/3+1 block producers signing the blocks, which results in about 3 minutes waiting. Elrond finality is a matter of 5–6 seconds for transactions within the same shard, and about 12 seconds between shards. I did not study what are the possibilities for an Elrond transaction to fail due to network congestion. On EOSIO, transactions may expire while waiting in the signing queue.

Token implementation

EOSIO has no tokens (kidding). Or better say, the core software does not know much about tokens. A token contract is just a regular smart contract managing holding balances, and typically one system token is managed by eosio.token account, and is used for on-chain governance and economics. The default set of system smart contracts delivered by Block.one contains the logic of using the system token for staking, allocating CPU, NET, and RAM resources, and BP voting. The recent PowerUp feature implements resource renting. Again, all this logic is not part of the system core software (nodeos), and is completely adaptable to the needs of a particular EOSIO network.

In Elrond, the native token is part of the base protocol (similar to Ethereum). In addition, the base protocol allows anyone register their own token using built-in ESDT token format, so the fungible tokens typically are not implemented by smart contracts. According to the authors, this allows very fast transfers. If a token with complex behavior is needed, it can be implemented in a smart contract.

Smart contracts in Elrond can be made payable, and the transfer transaction should specify the contract method to be called during the transfer. I have not dug deep enough to see how this affects the user experience. The smart contracts are as versatile as in EOSIO, and allow implementing all kinds of locking and payment schemes.

Accessing the smart contract data

One of strong features in Elrond is data getters: the WASM smart contract implements methods for retrieving and interpreting the data from smart contract storage (in Elrond, a contract gets just one key-value tree with arbitrary key length). So, the API client receives prepared data from the storage, according to the contract logic. I did not check if it’s possible for a smart contract to access other contracts’ data.

In EOSIO, the contract deals with a number of tables, each represented by a binary tree. The primary index is always of uint64 type, and the values are stored as serialized structures. The CDT and the HTTP API provide also all the logic for secondary indexes (which are also binary trees under the hood). Also an uint64 scope value adds an additional dimension to the tables. In many cases just one scope value is used, but in general this extends the key width to 128 bits. The smart contract serializes and deserializes the data according to its structure definitions. The HTTP API is representing the data in user-friendly format by using the ABI definitions which are normally stored along the smart contract. The CDT compiler is generating the ABI from the same source code as the WASM binary. As the smart contract cannot prepare the data for the API client, the client has to deal with raw data in the tables, and rely on ABI definitions. The ABI does not describe secondary indexes, so the client needs to have access to the source code of the contract in order to be able to retrieve the needed data if a secondary index lookup is involved.

Transaction signing and sending

An EOSIO transaction is a number of serialized actions and their arguments, authorization data (accounts and permissions of the signors, a reference to an existing block hash, and one or multiple signatures of the whole. All transactions are formed in the same way, regardless if they are token transfers or some other contract methods.

An Elrond transaction is a JSON object with fields in a specific order (I don’t know how critical the order is, but the guide insists on it). The transaction has only one signature (multisig operations are managed by a multisig contract).

One specific thing about Elrond is that every transaction should contain an integer sequence number that is specific to the sender account and is exactly next after a previously signed transaction. This limits the possibilities for high-volume transactions and parallel sending. In EOSIO, hundreds of backend systems can send transactions simultaneously on behalf of the same account, and it’s up to the smart contracts to avoid double spending and the sequence of operations.

Smart contract development

Elrond smart contracts are developed in Rust and C++, with most of effort dedicated to Rust implementation. The development framework provides also a testing environment where the contracts can be tested and debugged without deploying on a blockchain.

EOSIO contract development toolkit provides a C++ compiler, and all smart contracts are written in C++. There is no built-in testing framework, and a debugger is not available. The developers can use print statements to output the intermediate state.

Conclusion

Depending on your your project’s business requirements, both projects offer their distinctive features that might suite the requirements in a better way.

  • EOSIO is more mature, and a lot of software has been written around it. Elrond is fresh, and its contract development tools and surrounding infrastructure software are in active development. But Elrond provides a contract debugger from the start.
  • Elrond provides a standard fungible token behavior, limiting the possibilities for abuse. In EOSIO, a token contract requires auditing and verification. But EOSIO allows also implementing tokens with more complex behavior.
  • Different resource management models: direct transaction fees vs. resource allowance.
  • Different possibilities for parallel operation.
  • Built-in multisignatures and hierarchical permissions model in EOSIO vs. single-key signatures in Elrond.
  • EOSIO is easily adaptable for custom deployments: a new chain can be spawned with its own governance and resource model, or even without a system token. With Elrond, the fees and staking are built into base the protocol.
  • Different finality model, different model of trust.

--

--

cc32d9

Telegram: cc32d9, Discord: cc32d9#8327, EOS account: "cc32dninexxx"