UTXO vs Account-Based Blockchains
Bitcoin and Ethereum differ in many ways. In this article, I will cover one of their differences: the way they keep track of what coins a user owns. Bitcoin uses a model based on Unspent Transaction Outputs (UTXO) while Ethereum follows an account-based approach. I’ll explain both in detail in the next sections, with examples, and analyze the pros and cons of the UTXO and account-based models.
Here we will examine the concept of UTXO in detail.
Anatomy of a Transaction
A Bitcoin transaction is made of several parts. For the purposes of this article, we can focus only on:
- The transaction inputs, this is, the coins we are going to spend.
- The transaction outputs, this is, who is going to receive our coins.
A transaction must have at least one input and at least one output. The output(s) of a transaction become the input(s) of another transaction. This way, the history of a coin can be traced back to the block where it was mined.
A good analogy to understand how this system works is to imagine we’re using cash to buy a product. Imagine you have one $10, one $20 and one $50 bill. When paying, you may find yourself in one of these situations:
- The product costs $10. You can pay that with one $10 bill. This transaction has only one input (the $10 bill) and one output (the $10 bill the cashier receives).
- The product costs $30. You still can pay, but this time you need two different bills: 10 and 20. This is the case where a transaction has multiple inputs (the $10 and $20 bills) and one output (the $30 the cashier gets).
- The product costs $45. You pay with a $50 bill. The cashier gives you back $5. This case is equivalent to one input (the $50 bill) and multiple outputs ($45 for the cashier and $5 back to you).
- The product costs $55. You pay with a $10 and a $50, which amounts to $60. The cashier gives you back $5. This case is equivalent to multiple inputs (the $10 and $50 bills) and multiple outputs ($55 for the cashier and $5 back to you).
As you can see, the bills you give to the cashier (and the ones you receive back) will be used in the future to make other payments. Similarly, outputs of a Bitcoin transaction become inputs for future transactions. Until they are used, they are unspent, hence the name Unspent Transaction Output (UTXO).
If you wanted to know how much cash you own, you need to add the values of all the bills and coins you have in your wallet(s). In Bitcoin’s case, wallets keep track of the UTXOs associated with the user’s keys. This way, they know how many coins the user owns.
Note: even though this is a simplification (for instance, we have not mentioned transaction fees), the analogy to understand UTXO-based systems is still helpful.
A good analogy to understand Ethereum’s account-based model is to think of a bank account. A client has a certain amount of money in their account. If client A transfers $5 to client B, assuming client A has at least $5, client A’s account will be debited $5 while client B’s account will be credited $5.
In a nutshell, this is the way Ethereum accounts work. Also, there are 2 types of accounts:
- Externally Owned Account (EOA). They are controlled by users via private keys. If you’re not familiar with public and private keys, imagine your account address, which is derived from the public key, to be a bank account number (you can safely share it with anyone to receive payments) and the private key is similar to the secret PIN (only you know this number and you use it to access the funds).
- Contract Account. These accounts are controlled by smart contract code. Since they are not controlled by private keys, they cannot initiate transactions. A transaction sent to a smart contract can cause this contract to call functions from other contracts.
All accounts have the following fields:
- Balance: how much ether the account owns.
- Nonce: the number of confirmed transactions that the account has generated. I will explain this in more detail later.
- Storage: permanent data store, only used by smart contracts. This is empty for EOAs.
- Code: only used by smart contracts. EOAs don’t have any code.
All transactions in Ethereum are initiated by EOAs. Both EOAs and contract accounts can receive and send ether:
- If the receiving account is an EOA, its balance will increase.
- If the receiving account is a Contract Account its code will be executed. In turn, this smart contract can call another smart contract, send ether to another smart contract, send ether to an EOA, etc.
Smart contracts only run when an account invokes them. They can be called from EOAs or from other smart contracts, but ultimately, everything has its origin in a transaction created by an EOA.
A double-spending attack occurs when the same token (the same coin) is spent more than once. If you have a $10 bill, you cannot spend it twice because it won’t be under your control as soon as you pay for something and hand it to someone else. However, with digital tokens, how do you ensure that the same token is not spent in different transactions?
How Bitcoin Solves the Double-Spending Problem
When a coin is used in a transaction, it is removed from the UTXO set. Similarly, when new transactions are mined, their outputs are added to the UTXO set. Therefore avoiding double-spending attacks is as simple as checking if the coin you are trying to spend is part of the UTXO set. If it is, you can safely spend it. Otherwise, it has already been spent.
Each full node maintains a list of all the UTXO, which makes this verification quick.
Since you cannot track individual coins in Ethereum, the concept of double-spending attack does not apply. The closest is the replay attack I will describe now.
How Ethereum Prevents Replay Attacks
Imagine you want to buy a car and you send the dealer 10 ether. You receive the car, the dealer receives 10 ether and you’re both happy. However, as this is a valid transaction, what is stopping the dealer from sending that same transaction to the Ethereum network over and over, effectively draining your account? This is known as replay attack.
Ethereum uses the concept of nonce to solve this. In cryptography, a nonce is a number that can be used just once in a cryptographic communication.
In Ethereum, a nonce is a number that is associated with an account and represents the number of transactions sent from that account. If it is a contract account, it represents the number of contracts that the contract has created (not called).
How Does the Nonce Work
Your transaction will include a nonce value, making it unique. If the attacker tries to replay the same transaction, nodes will see that a transaction for that amount of ether from your address to the dealer’s address with that nonce has already been processed and will be considered as a duplicate transaction.
It is important to notice that the attacker can only try to create a transaction for the exact same amount. It the attacker were to change the amount, that would invalidate the signature, making it an invalid transaction that nodes would reject.
Your next transaction, regardless of the address you’re sending ether to, will have incremented its nonce.
This mechanism not only prevents replay attacks but also allows for transactions to be executed in a certain order. If you send a series of transactions with nonces 3, 4, and 5 even if the transactions with nonces 4 and 5 are received first, they will stay in the mempool until the transaction with nonce 3 has been confirmed. Unless you’re writing code to send transactions, you do not need to worry about this issue. Everything will be handled by your wallet.
Pros and Cons of Each Model
- It’s easy to check if an output has already been spent, avoiding double-spending attacks.
- Transactions can easily be processed in parallel, which results in better scalability.
- It has slightly better privacy since users can use a new address for each transaction.
- Difficult for new users to get a grasp of this system.
- Harder to implement smart contracts because UTXOs don’t keep track of any state.
- Easy to implement smart contracts.
- Transactions are more compact, saving space.
- Tricky to implement concurrent (parallel) transactions, since there is a global state that is affected by different transactions.
- Less privacy, since transactions are bound to an account.
- Relies on nonces to prevent replay attacks.
In this article, you have learned how the UTXO and account models work, prevent double-spending attacks, and their advantages and disadvantages.
I already introduced the concept of UTXO and UTXO set in this article. It is a bit more technical than this piece, so don’t feel bad it you cannot fully understand it at this moment. You can always come back a bit later and read it.