# Introducing the FuelVM and Sway
:::warning
This note is mostly copied from the following references
1. [Exploring the FuelVM](https://medium.com/blockchain-capital-blog/exploring-the-fuelvm-86cf9ccdc159)
2. [Predicates in Sway](https://fuellabs.github.io/fuels-rs/v0.25.1/getting-started/predicates.html#predicates)
3. [What is Account Abstraction](https://www.argent.xyz/blog/wtf-is-account-abstraction/)
4. [The Fuel Rust SDK](https://fuellabs.github.io/fuels-rs/v0.31.0/)
5. [Solidity Bytecode and Opcode Basics](https://medium.com/@blockchain101/solidity-bytecode-and-opcode-basics-672e9b1a88c2)
6. [Geth, which implements DevP2P specifications in Go.](https://geth.ethereum.org/docs/interface/devp2p)
7. [Merkle Patricia Trie](https://medium.com/@chiqing/merkle-patricia-trie-explained-ae3ac6a7e123)
8. [The Fuel Book](https://fuellabs.github.io/fuel-docs/master/index.html)
9. [The Sway Programming Language](https://fuellabs.github.io/sway/v0.31.1/)
10. [FuelVM Bootcamp](https://www.youtube.com/watch?v=GKNuaFcPaXc)
11. [The Rust Programming Language](https://doc.rust-lang.org/book/)
12. [Fuel Website](https://www.fuel.network/)
:::
<p float="left">
<img src="https://assets.website-files.com/62e273f312d561347ce33306/630500bd9e32db63fbd441ef_Fuel_MonolithicLayer_Labels_B_Compressed_Cropped-p-800.png" width="350" />
<img src="https://assets.website-files.com/62e273f312d561347ce33306/630500bed675d01bf02a75b5_Fuel_ModularLayer_Labels_Final_Compressed_cropped-p-800.png" width="350" />
</p>
- Build by [Fuel Lab](https://www.fuel.network/)
- Fuel Virtual Machine (FuelVM)
- A fully purpose-built, custom virtual machine for executing smart contracts
- Designed to be modular
- It can plug in as the execution engine for any blockchain
- [Fuel VM Specification](https://fuellabs.github.io/fuel-specs/master/vm/index.html)
- Sway
- A domain-specific language (DSL) for the (FuelVM)
- Based on Rust, and includes syntax to leverage a blockchain VM without needlessly verbose boilerplate
- [The Sway Programming Language](https://fuellabs.github.io/sway/v0.31.1/)
# FuelVM
## What is the FuelVM?
- Designed from the start to be easily fraud-provable
- Can be used as the transaction execution layer for an optimistic rollup
- Optimized to **better utilize hardware** to **increase the throughput** of transaction execution
- UTXO based
- Every transaction requires to explicitly define the UTXOs that it will touch
- Execution engine can identify exactly what state every transaction touches
- Able to find the transactions that are not contentious and parallelize them
## Why does the VM matter?
- The VM is the operating system for the smart contract blockchain
- All widely used smart contract chains today are using the same VM as Ethereum: the EVM
- For the EVM, the bandwidth is cheap, the next bottleneck will be computational throughput ([reasons](https://medium.com/blockchain-capital-blog/exploring-the-fuelvm-86cf9ccdc159))
- Goal of FuelVM: execute transactions fast while keeping the underlying hardware requirements low enough for sufficient decentralization
## FuelVM’s Differentiators
### Execution + Validation Parallelization
- The secret behind the FuelVM’s parallelizable virtual machine is its strict access lists
- Require users (clients or wallets) to indicate which contract(s) their transaction will touch
- [Transaction Layout](https://fuellabs.github.io/fuel-specs/master/protocol/tx_format/transaction.html)
- Just list a few fields below
| Field | Description |
| --------------- | -------------------------------------------------------------------------------------------------------- |
| **Inputs** | List of all contract UTXOs that the transaction will touch + data to unlock the UTXO or predicate script |
| Outputs | Define the UTXOs that will be created |
| Gas Information | gas price + gas limits |
| Witnesses | metadata + digital signature for authorization |
- The **inputs** lists all the UTXOs that will be consumed
- Before executing any code, the VM is able to tell which contracts a transaction will touch
- It can safely execute all other non-contentious state-accessing transactions in parallel
<p float="left">
<img src="https://miro.medium.com/max/1100/1*1avkHndlTD9RhwMMYBaL7w.png" width="350" />
<img src="https://miro.medium.com/max/1100/1*nIXbEQkuMQ2p2g5GF-R9IQ.png" width="350" />
</p>
- Transaction outputs are explicitly included for validation
- In the process of asserting that a block that another node proposed was correct, there is no need to execute the overlapping transactions sequentially
- Validation can happen fully in parallel regardless of state contention
- When nodes are syncing the network, they can achieve even greater parallelization and can catch up faster
### Native Asset System
- In the EVM, there is one native asset: ETH
- All other assets are implemented via a smart contract that handles accounting for balances ([ERC20](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/))
- In Fuel, developers are **free to implement assets** in smart contracts
- FuelVM is allowed the to handle the assets natively
- Advantages
- Native asset manipulation is cheaper (in terms of gas) than manipulating state in a smart contract
- This can be attributed to its running at lower-level primitives (UTXO system is used instead of manipulating storage)
- Native assets have better UX
- E.g., Sending ETH directly is much simpler than sending ERC20s (no need for setting approvals)
- From [ERC777](https://eips.ethereum.org/EIPS/eip-777)
> "The tokensReceived hook allows to send tokens to a contract and notify it in a single transaction, unlike ERC-20 which requires a double call (approve/transferFrom) to achieve this."
- From [Native Support for Multiple Asset Types](https://fuellabs.github.io/sway/v0.31.1/blockchain-development/native_assets.html) in [The Sway Programming Language](https://fuellabs.github.io/sway/v0.31.1/)
> "The FuelVM has built-in support for working with multiple assets.
>
> What does this mean in practice?
>
> As in the EVM, sending ETH to an address or contract is an operation built into the FuelVM, meaning it doesn't rely on the existence of some token smart contract to update balances to track ownership.
>
> However, unlike the EVM, the process for sending any native asset is the same. This means that while you would still need a smart contract to handle the minting and burning of fungible tokens, the sending and receiving of these tokens can be done independently of the token contract."
### Native Account Abstraction + Predicates
- Account abstraction has been a hot topic of research and several attempts have been made at EIPs ([EIP-86](https://eips.ethereum.org/EIPS/eip-86), [EIP-2938](https://eips.ethereum.org/EIPS/eip-2938), [EIP-3074](https://eips.ethereum.org/EIPS/eip-3074), [EIP-4337](https://eips.ethereum.org/EIPS/eip-4337), [EIP-5003](https://eips.ethereum.org/EIPS/eip-5003))
- It is difficult to implement and upgrade Ethereum to support account abstraction
- Due to the associated complexity
- No engineering bandwidth
- A long list of higher priority items
- Many rollups have the opportunity to implement account abstraction from the start on their novel execution environments
- FuelVM for example
- Native account abstraction
- [Predicates](https://fuellabs.github.io/fuels-rs/v0.25.1/getting-started/predicates.html#predicates)
- A **predicate** is a pure (does not access state) contract script that simply returns a boolean (true or false)
- UTXOs can be locked behind a predicate so they can only be spent whenever the conditions defined in the predicate are met
- Users can set a transaction to execute only under certain conditions
- Once the predicate is met, their transaction can automatically execute
- Predicates can be pruned when they are destroyed, so they do not contribute to state bloat
### Multi-dimensional Resource Pricing
- Resource pricing allows the system to charge users for consuming **work** from the nodes in the network
- In the EVM, one of the most common reasons for the introduction of [EIPs](https://eips.ethereum.org/) has been for opcode re-pricing
- Opcodes have hardcoded gas prices
- The underlying price of resources do not scale proportionally to each other (historically, CPUs improve more rapidly than SSDs)
- The FuelVM
- Implements dynamic multi-resource pricing that can incentivize node runners to optimize their underlying hardware better while still optimizing for the maximum *utility per block*
<p float="left">
<img src="https://miro.medium.com/max/1400/1*bLvTVR8HlGdSYIgoZvd8AQ.png" width="600" />
</p>
- In this figure, one smart contract has significantly higher demand than others
- With localized resource pricing, other contracts are not impacted to the same extent
- A smart contract with a specific resource profile will be priced differently than another contract
- For the NFT drop example, the hot contract might have a resource profile that is very storage intensive but very computationally cheap
- Smart contracts that have high compute requirements relative to storage would not be as impacted by the noisy NFT drop
- Example: An **extremely high storage load** on the system because of an event where many different NFTs are being minted simultaneously
- **The fees are very low** because not all this traffic is happening on a single account
- The per-account fee model does solve the hot partition problem for accounts but leaves scenarios where the system is not correctly pricing underlying resources, so **it can still lead to failures**
- It is simply cleaner and more accurate to price the system based on the underlying hardware resources
- Instead of trying to add a network-specific abstraction layer like accounts to base the multi-market resource pricing on
### State-bloat Considerations
- Historically, SSDs do not improve as quickly as the state size is growing, so this cost will continue to impact the decentralization of the network.
- From [A Theory of Ethereum State Size Management](https://hackmd.io/@vbuterin/state_size_management)
>State refers to information that a node must hold in order to be able to process new incoming blocks and transactions. It is typically contrasted with history, information about past events which can be held for later rebroadcasting and archiving purposes, but is not strictly needed to continue to process the chain.
- FuelVM
- By a combination of appropriate resource pricing and a more clear data model for state pruning with the UTXO system, it will be able to keep the state under control, reducing the cost of running a node, which is equivalent to increasing the decentralization of the network
### Decentralization of the “sequencer”
- The **sequencer** is a privileged node that is responsible for
- Ordering transactions
- Executing state transitions
- Submitting the state root update along with compressed transaction information to L1
- A single **super-computer** responsible for sequencing can **execute more transactions per epoch than** a multitude of **smaller computers** redundantly executing the same sequence of transactions
- Several key problems with this centralized sequence
- Controlling the ordering of transactions is very profitable
- MEV is one of the main sources of income for those who order blocks
- A single party controlling ordering and MEV capture eventually leads to worse execution for users
- A centralized sequencer can be a single point of failure both from an availability and regulatory perspective
- If a single or a small number of organizations are running sequencers they can go down or be taken down.
- A liveness risk to the network
- A centralized sequencer may censor transactions on the L2
- The sequencer gets to choose whatever transactions and place them in any order during the construction of a block
- This leads to the ability to censor
- Sequencers can make inconsistent promises about the state of the chain to users of the rollup
- The sequencer can make a misleading promise about some state of the L2
- Fast finality on the rollup is a trusted step
- A sequencer can abuse this trust that leads users to do things they do not intend
- How does Fuel solve these problems?
- Fuel is not just a rollup or an L1 blockchain
- It is a system that **simply applies state transitions** that can be posted to an L1 if configured as a rollup or operate in a network to achieve consensus as an L1.
- The Fuel execution engine **does not care about consensus or transaction ordering**
- Fuel is only responsible for applying the transactions as quickly as possible
- Layer 2 tokenomics with decentralization is on-going
- [A Token Model for Layer-2 Block Production](https://fuel-labs.ghost.io/token-model-layer-2-block-production/)
>Rollups need new token models, and currently-deployed models have shortcomings. In this blog post we propose a new model for layer-2 block production.
- It lays out a design for a token that helps decentralize block production by allowing rollups to tokenize block space scarcity through the right to collect fees as a block producer
- Fee collection is only one portion of the income for block producers
- MEV is another large portion of the income
- **Similarly to block space scarcity, MEV income will also be tokenized via the right to produce blocks**
## The State Model: UTXO vs Account Based
- The account model is more similar to a bank ledger
- Naturally lead to hot pieces of state because every transaction is trying to access the same account
- UTXOs can be likened to cash bills (IOTA DAG)
- It is less contentious if designed correctly
- Enables better parallelization and also can prevent state bloat by simplifying the process of state pruning
- An example follows
- UXTO: 2 cash transactions can happen at the same time and they don’t need to have any knowledge of each other
- Acount-based: 2 account updates on a ledger, both transactions would have to update the same shared ledger
<p float="left">
<img src="https://miro.medium.com/max/1100/1*sjfvqbqpQT_MLCe_HsPhNg.png" width="350" />
<img src="https://miro.medium.com/max/640/1*daR6MsOjX5wPl5BRyypIpA.png" width="350" />
</p>
## Summary of FuelVM
- Unlike other L2s, Fuel has plans to decentralize the sequencer role from the start by designing the VM
- Expensive hardware is not required to increase scale
- FuelVM is flexible
- It can be deployed in many environments, but the priority is to be Ethereum aligned as an Optimistic Rollup
- Fuel’s UX will be much better than the EVM’s because of native and novel ways of interacting with the chain
- Such as account abstraction, scripts, and predicates
- The UTXO data model is naturally less contentious than the account data model and will lead to more parallelism AND less state bloat
# Sway
- Sway is a domain-specific language (DSL) for the Fuel Virtual Machine (FuelVM), a blockchain-optimized VM designed for the Fuel blockchain
- Sway is based on [Rust](https://www.rust-lang.org/), and includes syntax to leverage a blockchain VM without needlessly verbose boilerplate
## Programing Type
A Sway program itself has a **type**: it is either a **contract**, a **predicate**, a **script**, or a **library**. The first three of these things are all deployable to the blockchain. A library is simply a project designed for code reuse and is never directly deployed to the chain.
### Contracts
- The program starts with a declaration of what program type it is. A contract must also either define or import an Application Binary Interface (ABI) declaration and implement it
- It is considered good practice to define your ABI in a separate library and import it into your contract
- This allows callers of your contract to simply import the ABI directly and use it in their scripts to call your contract
- A contract example:
```rust
library wallet_abi;
abi Wallet {
#[storage(read, write)]
fn receive_funds();
#[storage(read, write)]
fn send_funds(amount_to_send: u64, recipient_address: Address);
}
```
### Libraries
- Libraries are defined using the library keyword at the beginning of a file, followed by a name so that they can be imported
- The most prominent example of this is the [Sway Standard Library](https://fuellabs.github.io/sway/v0.31.1/introduction/standard_library.html)
- A library example:
```rust
library my_library;
// library code
```
### Scripts
- A script is runnable bytecode on the chain which executes once to perform some task
- It does not represent ownership of any resources and it cannot be called by a contract
- A script can return a single value of any type.
- Scripts are **state-aware** in that while they have no persistent storage (because they only exist during the transaction) they can call contracts and act based upon the returned values and results
- A script example:
```rust
script;
use std::constants::ZERO_B256;
use wallet_abi::Wallet;
fn main() {
let contract_address = 0x9299da6c73e6dc03eeabcce242bb347de3f5f56cd1c70926d76526d7ed199b8b;
let caller = abi(Wallet, contract_address);
let amount_to_send = 200;
let recipient_address = Address::from(0x9299da6c73e6dc03eeabcce242bb347de3f5f56cd1c70926d76526d7ed199b8b);
caller.send_funds {
gas: 10000,
coins: 0,
asset_id: ZERO_B256,
}(amount_to_send, recipient_address);
}
```
### Predicates
- From the perspective of Sway, predicates are programs that return a Boolean value and which represent ownership of some resource upon execution to true
- They have no access to contract storage
- Here is a trivial predicate, which always evaluates to true:
```rust
predicate;
// All predicates require a main function which returns a Boolean value.
fn main() -> bool {
true
}
```
- Debugging Predicates
- Because they don't have any side effects (they are pure), predicates cannot create receipts.
- They cannot have logging or create a stack backtrace
- **There is no native way to debug them aside from using a single-stepping debugger**
- The [fuel-debugger PR](https://github.com/FuelLabs/fuel-debugger/pull/1) is now merged
- [Not released yet](https://docs.rs/forc-debugger/latest/forc_debugger/)
- As a workaround, the predicate can be written, tested, and debugged first as a script, and then changed back into a predicate
## Blockchain Development with Sway
- Hashing and Cryptography
- The Sway standard library provides easy access to a selection of cryptographic hash functions (sha256 and EVM-compatible keccak256), and EVM-compatible secp256k1-based signature recovery operations
- Contract Storage
- **Persistent storage**, often just called storage in this context, is a place where you can store values that are persisted inside the contract itself
- This is **in contrast to a regular value in memory**, which disappears after the contract exits
- Contract storage is like saving data to a hard drive
- That data is saved even after the program which saved it exits
- Function Purity
- A function is pure if it does not access any persistent storage
- Conversely, the function is impure if it does access any storage
- Naturally, as storage is only available in smart contracts, **impure functions cannot be used in predicates, scripts, or libraries**
- A pure function cannot call an impure function
- **In Sway, functions are pure by default** but can be opted into impurity via the storage function attribute
- The storage attribute may take read and/or write arguments indicating which type of access the function requires
- Identifiers
- Addresses in Sway are similar to EVM addresses. The two major differences are:
- Sway addresses are 32 bytes long (instead of 20)
- Sway addresses are computed with the SHA-256 hash of the public key instead of the keccak-256 hash
- Contracts, on the other hand, are uniquely identified with a contract ID rather than an address
- A contract's ID is also 32 bytes long and is calculated [here](https://fuellabs.github.io/fuel-specs/master/protocol/id/contract)
- Native Assets
- As in the EVM, sending ETH to an address or contract is an operation built into the FuelVM, meaning it doesn't rely on the existence of some token smart contract to update balances to track ownership
- Access Control
- Smart contracts require the ability to restrict access to and identify certain users or contracts
- Unlike account-based blockchains, **transactions in UTXO-based blockchains (i.e. Fuel) do not necessarily have a unique transaction sender**
- Additional logic is needed to handle this difference, and is provided by the standard library
- Calling Contracts
- Smart contracts can be **called** by other contracts or scripts. In the FuelVM, this is done primarily with the call instruction
- Sway provides a nice way to manage callable interfaces with its **abi** system. The Fuel ABI specification can be found [here](https://fuellabs.github.io/fuel-specs/master/protocol/abi)
## Examples and Quick DEMO
- [Counter](https://fuellabs.github.io/sway/v0.31.1/examples/counter.html#counter)
- [Subcurrency](https://fuellabs.github.io/sway/v0.31.1/examples/subcurrency.html)
- [FizzBuzz](https://fuellabs.github.io/sway/v0.31.1/examples/fizzbuzz.html)
- [Wallet Smart Contract](https://fuellabs.github.io/sway/v0.31.1/examples/wallet_smart_contract.html)
- [Liquidity Pool](https://fuellabs.github.io/sway/v0.31.1/blockchain-development/native_assets.html#liquidity-pool-example)
- [Native Token](https://fuellabs.github.io/sway/v0.31.1/blockchain-development/native_assets.html#native-token-example)