## 1. Project Overview & Quickstart (FuelLabs/using-generated-types)

# using-generated-types

Open-source repository FuelLabs/using-generated-types

### Repository Details
- **Repository:** [FuelLabs/using-generated-types](https://github.com/FuelLabs/using-generated-types)
- **Primary Language:** Code

*Note: High-volume repository documentation is actively indexed and synchronized by YakaAI.*

## 2. Official Technical Reference & Guides (FuelLabs/docs)

## File: README.md

Fuel Docs
===

[](https://discord.gg/xfpK4Pe)

A complete set of documentation for the Fuel-powered tools and services.

## Building From Source

### Install Dependencies

```bash
npm install
```

### Build

```bash
npm run build
```

### Start

```bash
npm run start
```

---

## File: package.json

{
  "name": "fuel-docs",
  "version": "1.0.0",
  "description": "The Fuel documentation.",
  "main": "config/build.js",
  "scripts": {
    "start": "npm run build && http-server dist --cors",
    "build": "parcel build public/index.html --out-dir build && node config/build",
    "publish": "npm run build && now dist && now alias https://dist.fuellabs.now.sh docs.fuel.sh",
    "publish-staging": "npm run build && now dist && now alias https://dist.fuellabs.now.sh docs.staging.fuel.sh",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/FuelLabs/docs.git"
  },
  "keywords": [
    "fuel",
    "docs",
    "documentation"
  ],
  "author": "Nick Dodson <nick.dodson@fuel.sh>",
  "license": "Apache-2.0",
  "bugs": {
    "url": "https://github.com/FuelLabs/docs/issues"
  },
  "homepage": "https://github.com/FuelLabs/docs#readme",
  "dependencies": {
    "copy-text-to-clipboard": "^2.2.0",
    "fs-extra": "^9.0.1",
    "markdown-to-txt": "^1.0.1",
    "hyperapp": "^2.0.4",
    "esm-import-regex": "1.0.0",
    "hyperapp-styled-components": "^0.1.2",
    "showdown": "^1.9.1",
    "regenerator-runtime": "^0.13.5"
  },
  "devDependencies": {
    "cssnano": "^4.1.10",
    "http-server": "^0.12.3",
    "parcel": "^1.12.4"
  }
}

---

## File: src/v1.0.0/1. Introduction/1. Welcome.md

Welcome
===

**Before we begin:**

Try out our live interactive [🕹️ Fuel Plays Pokémon demo](https://fuelplayspokemon.com)!

Check out the [⚡ Block Explorer](https://rinkeby.fuel.sh/network).

Use the one-click [💻 Wallet SDK Example](../2.%20Getting%20Started/1.%20One-Click%20Example.md).

We are always available to... [](https://discord.gg/xfpK4Pe)

Introduction
---

Fuel is a permissionless and trustless layer-2 protocol for Ethereum, targeted at low-cost high-throughput value-transfer transactions. Fuel is powered by a highly-optimized _optimistic rollup design_.

Fuel's Features
---

- Completely decentralized: non-custodial, censorship resistant, and permissionless
- The most scalable optimistic rollup in the world, with unique UTXO-based design
- 500 TPS maximum on-chain throughput (1,500-2,000 with BLS aggregate signatures)
- Up to 10,000 TPS surge intake capacity
- Send and receive using any Ethereum address, no registration required
- ETH and all ERC-20 tokens are supported
- Non-custodial token swaps between any tokens
- Fees can be paid in any token, not just ETH
- HTLCs for cross-chain atomic swaps and additional usecases
- Withdrawals in under 10 minutes using atomic swaps

What Makes Fuel Different
---

- UTXO-based design optimized for maximum scalability
    - Parallelism: transactions can be validated in parallel on consumer-grade hardware
    - No state bottleneck: unique fraud proof scheme doesn't require state serialization
- No special key formats or on-chain account registration required
- No upfront collateral requirements (unlike channels)
- Permissionless and censorship-resistant (unlike Plasma/Validium)
- No burdensome proof generation with high latency (unlike ZK rollups and Validium)
- No exotic cryptography (unlike ZK rollups and Validium)
- No trusted setup (unlike SNARK-based ZK rollups and Validium)
- No worse-than-useless protocol-specific token (unlike...too many to count)
- Care and attention to user-level issues
    - Can deposit using simple transfers from any account (including exchange accounts) using Funnel contracts
    - Can use a smart contract wallet to authorize transactions on Fuel

What To Read Next?
---

System benchmarks can be found [on the next page](2.%20Benchmarks.md).

If you want to know more about the fundamentals of Fuel's architecture, our [Technical Fundamentals](./../3.%20Concepts/0.%20Fundamentals/1.%20Fuel%20Overview.md) is your next stop. A detailed analysis on the security and scalability of Fuel [is available](./../3.%20Concepts/0.%20Fundamentals/2.%20Security%20Analysis.md).

If you're a developer and want to build on top of, or integrate with, Fuel, check out our [Getting Started](../2.%20Getting%20Started/0.%20Using%20the%20Wallet%20SDK.md) guide and [wallet SDK documentation](../2.%20SDK/1.%20Wallet.md).

For examples of tools and applications that can built on top of Fuel, start [here](../4.%20Tools%20and%20Applications/1.%20Token%20Minting.md).

Finally, our technical roadmap can be found [here](../5.%20Future%20Roadmap/1.%20Planned%20Features.md).

---

## File: src/v1.0.0/1. Introduction/2. Benchmarks.md

Benchmarks
===

- [Simulations](#simulations)
    - [Running Locally](#running-locally)
- [Benchmarks](#benchmarks)
    - [Fuel v1 on Ropsten](#fuel-v1-on-ropsten)
- [Audits](#audits)

Simulations
---

Below are simulation results for Fuel [v1](../5.%20Future%20Roadmap/1.%20Planned%20Features.md), for a number of different representative usecases. Usecase-specific and context-sensitive optimizations _are not_ done, so these numbers are representative of normal usage. Such optimizations include batching multiple transactions from the same sender in the same rollup block to save space, or reducing the number of bits to represent token types to only handle a tiny number of tokens.

### Running Locally

The simulation can be ran locally:

```bash
git clone git@github.com:FuelLabs/fuel.git
npm install
npm run benchmark
```

**100k Transfers**

Standard one-input two-output [transfers](../3.%20Concepts/0.%20Fundamentals/4.%20Transaction%20Architecture.md#simple-send-example).

- Transactions Submitted: 100000
- Roots committed: 360
- Blocks committed: 3
- Cumulative gas used: 185387356
- Ethereum blocks used: 23
- @100 Gwei: 18.539 ETH
- @$300 USD / ETH: $5562

**100k Token Minting**

One-input eight-output [mass token minting transactions](../4.%20Tools%20and%20Applications/1.%20Token%20Minting.md).

- Claims Processed: 100000
- Transactions Submitted: 12500
- Roots committed: 134
- Blocks committed: 2
- Cumulative gas used: 72457791
- Ethereum blocks used: 9
- @100 Gwei: 7.246 ETH
- @$300 USD / ETH: $2174

**75k Token Burns**

One-input three-output (burn, memo, change).

- Transactions Submitted: 75000
- Roots committed: 275
- Blocks committed: 3
- Cumulative gas used: 140909433
- Ethereum blocks used: 17.613679125
- @100 Gwei: 14.091 ETH
- @$300 USD / ETH: $4227

**25k Subscriptions**

One-input two-output.

- Transactions Submitted: 25000
- Roots committed: 87
- Blocks committed: 1
- Cumulative gas used: 45442233
- Ethereum blocks used: 5
- @100 Gwei: 4.544 ETH
- @$300 USD / ETH: $1363

Benchmarks
---

Benchmarks use the same transaction types as the simulations above (i.e. they are representative of normal usage).

### Fuel v1 on Ropsten

**100k Transfers**

Contract deployed at [`0x57f51C778Dd66153A44881Cc5E6e9da421c4dC85`](https://ropsten.etherscan.io/address/0x57f51c778dd66153a44881cc5e6e9da421c4dc85).

- Cumulative gas used: 225360000
- @100 Gwei: 22.536 ETH
- @$300 USD / ETH: $6761

**100k Token Minting**

Contract deployed at [`0x47b13755d14BCEFC49C0606Aca5E62Dc2C1Da9eC`](https://ropsten.etherscan.io/address/0x47b13755d14bcefc49c0606aca5e62dc2c1da9ec).

- Cumulative gas used: 89184000
- @100 Gwei: 8.918 ETH
- @$300 USD / ETH: $2675

**75k Token Burns**

Contract deployed at [`0xf73788cD87267c68dA5ed3e3a37c4A610a07513d`](https://ropsten.etherscan.io/address/0xf73788cd87267c68da5ed3e3a37c4a610a07513d).

- Cumulative gas used: 176400000
- @100 Gwei: 17.640 ETH
- @$300 USD / ETH: $5292

**25k Subscriptions**

Contract deployed at [`0x232113aaC91Bab5b6351016497f966dA8C1BfB9C`](https://ropsten.etherscan.io/address/0x232113aac91bab5b6351016497f966da8c1bfb9c).

- Cumulative gas used: 56112000
- @100 Gwei: 5.611 ETH
- @$300 USD / ETH: $1683

Audits
---

- An audit with [Hashcloak](https://hashcloak.com) is currently underway.
- An audit with [Trail of Bits](https://www.trailofbits.com) is scheduled.

---

## File: src/v1.0.0/1. Introduction/3. Use Cases.md

Use Cases
===

In this section we explore various use cases for the Fuel [v1](../5.%20Future%20Roadmap/1.%20Planned%20Features.md#fuelv1) optimistic rollup. All the use cases covered below are examined in more detail in the [Tools and Applications](../4.%20Tools%20and%20Applications/0.%20Fast%20Withdrawals.md) section.

Transfers
---

Fuel can be used for high-performance, low-latency global transfers with any ERC-20 token or Ether.

**This is ideal for:**
- Global payment settlement
- Application-specific tokens
- Virtual gaming tokens and rewards
- Any situations where users are transferring ERC-20 tokens

Please see our interactive [🕹️ Fuel Plays Pokémon demo](https://fuelplayspokemon.com) for a live example of transfers in action.

Non-Custodial Exchange
---

Fuel's unique **multi-user transactions and HTLC support** are a perfect foundation for non-custodial exchanges.

**We support two kinds of exchange:**
- Multi-user on-Fuel swaps
- Cross-chain atomic swap with HTLCs

For further reading, please see [Non-Custodial Exchanges](../4.%20Tools%20and%20Applications/3.%20Non-Custodial%20Exchanges.md).

Mass Token Dispersal
---

Fuel supports multi-input, multi-output transactions, making it perfect for pre-signed mass token dispersal scenarios where a single account must disperse tokens to a large number of unique recipients cost-efficiently.

This is possible on Fuel with a Merkleized dispersal pattern and our deterministic transaction identifiers, allowing dispersal transactions to be pre-signed and distributed off-chain. Tokens are only actually dispersed when claimed, greatly reducing overhead costs for unclaimed tokens.

For further reading on how we accomplish this with low overheads, please see [Token Minting](../4.%20Tools%20and%20Applications/1.%20Token%20Minting.md)

Fast Withdrawals
---

Fuel allows for fast (~10 minute) withdrawals using our unique HTLC output. Liquidity providers on the intended exit chain (e.g. Ethereum or Bitcoin) can allow users on Fuel to withdraw with minimal effort and at low cost.

For further reading, please see [Fast Withdrawals](../4.%20Tools%20and%20Applications/0.%20Fast%20Withdrawals.md).

Subscriptions
---

Fuel's pre-signed transaction format is ideal for creating regular financial subscriptions, where a user can *sign up* to a subscription, pre-signing a set of transactions, and then allowing any service or system to collect payment on a regular basis non-interactively.

This is allows for cheap, care-free subscriptions for magazines, blogs, forums, and more.

For further reading, please see [Subscriptions](../4.%20Tools%20and%20Applications/2.%20Subscriptions.md).

Burning
---

Fuel has a "return data" transaction output, which can be used to store arbitrary data in Fuel such as: burn metadata, social media messages, timestamped hashes, or specific application data.

The burning of a token by sending it to the zero address can be associated with a specific event using the return data output, all within in the same transaction.

---

## File: src/v1.0.0/2. Getting Started/0. Using the Wallet SDK.md

Using the Wallet SDK
===

[](https://badge.fury.io/js/%40fuel-js%2Fwallet)

The wallet is how users and developers can interact with Fuel.

Install
---

The Fuel module is currently available as a UMD through CDN or NPM.

**node.js**

```bash
npm install --save @fuel-js/wallet
```

**browser (UMD)**

```html
<script src="https://unpkg.com/@fuel-js/wallet@latest/umd/fuel.umd.min.js" type="text/javascript">
</script>
```

**browser (ESM)**

```html
<script type="module">
  import fuel from "https://unpkg.com/@fuel-js/wallet@latest/umd/fuel.umd.min.js";
</script>
```

Creating a Wallet
---
The Fuel wallet can be used with or without a standard `web3` or `ethers` provider. The provider will be used for account signing or any Ethereum related actions, such as deposits and withdrawals.

If an override `privateKey` is not specified, the first `account` given by the provider will be used.

If an Ethereum `network` is not specified (e.g. `rinkeby`), it will be requested from the provider.

```js
import fuel from '@fueljs/wallet';

// no provider, privateKey is generated
const wallet = fuel.wallet(null);

// web3 provider, first account used, network gathered from provider
const wallet = fuel.wallet(window.web3.currentProvider);

// provider with override privateKey and network specified
const wallet = fuel.wallet(window.web3.currentProvider, {
  privateKey: fuel.utils.hexlify(fuel.utils.randomBytes(32)),
  network: 'rinkeby',
});
```

Fauceting
---

All Fuel test networks have a token faucet that will dispense fake tokens to requesting accounts (within several seconds to minutes).

The faucet will dispense `1000` `faucetTokens`.

The faucet test token identifier will always be available in `fuel.contants.faucetToken`.

```js
import fuel from '@fueljs/wallet';

// new wallet
const wallet = fuel.wallet(null, {
  network: 'rinkeby',
});

// faucet fake tokens
await wallet.faucet();

// check your balance
console.log('my balance: ', await wallet.balance(fuel.constants.faucetToken));
```


Depositing
---

You can deposit ERC-20 tokens or Ether into Fuel by using the `deposit` method. Simply specify the `token` and `amount` to deposit. Since Fuel uses Ethereum key pairs, this process can be done directly with your provided MetaMask account, for example.

The `deposit` method will make two Ethereum transactions, depositing your funds into Fuel and making them accessible for Fuel activities (e.g. transfers and swaps).

```js
import fuel from '@fuel-js/wallet';

const wallet = new fuel.Wallet(window.web3.currentProvider);

(async () => {

  // rinkeby dai address
  const daiAddress = '0xc3dbf84Abb494ce5199D5d4D815b10EC29529ff8';

  // deposit funds
  await wallet.deposit(daiAddress, fuel.utils.parseEther('1.0'));

})();
```

Transferring
---

Now that you have funds in Fuel, either by `deposit` or `faucet` you can begin to transfer them around.

Let's try transferring `1` Fuel token to our own wallet address and check the submission by its transaction ID.

```js
import fuel from '@fuel-js/wallet';

const wallet = new fuel.Wallet(window.web3.currentProvider);

(async () => {

  await wallet.faucet();

  // transfer one faucet token to our own wallet
  const { transactionId } = await wallet.transfer(
    fuel.constants.faucetToken,
    wallet.address,
    fuel.utils.parseEther('1.0'));

  console.log('view my transaction: https://rinkeby.fuel.sh/tx/' + transactionId);

})();
```

Withdrawing
---

Currently, the Fuel wallet only supports standard withdrawals, which means you will send an initial withdraw transaction on Fuel first, than release it after the finality delay of 1 week has expired. In the future, the wallet will support fast withdrawals via atomic swaps, where total withdraw time can be reduced safely to as little as 5-10 minutes.

In order to release the tokens on Ethereum, you must have some Ether for the transaction.

```js
import fuel from '@fuel-js/wallet';

const wallet = new fuel.Wallet(window.web3.currentProvider);

(async () => {

  await wallet.faucet();

  // withdraw one faucet token
  await wallet.withdraw(fuel.constants.faucetToken, utils.parseEther('1.0'));

  // wait one week...

  // release any withdrawals onto Ethereum
  await wallet.release();
})();
```

---

## File: src/v1.0.0/2. Getting Started/1. One-Click Example.md

One-Click Example
===

Below is our one-click **Wallet SDK example** using the Fuel test faucet on *Rinkeby*.

#### Try it out!

<style type="text/css" media="screen">
    #editor {
      min-height: 450px;
      width: 100%;
      font: 13px/normal 'Ubuntu Mono', 'Monaco', 'Menlo', 'Consolas', 'source-code-pro', monospace!important;
    }

    .ace_scroller {
      border-radius: 4px!important;
      border: 1px solid #F1F1F1!important;
      border-bottom-left-radius: 0px!important;
      border-bottom-right-radius: 0px!important;
    }

    .ace_gutter-active-line {
      display: none;
    }

    .ace_gutter-layer {
    }

    .ace_identifier {
      color:#625666!important;
    }

    .ace_string {
      color:#dd6546!important;
    }

    .ace_comment {
      color:#978998!important;
    }

    .ace_gutter {
      background: #FFF!important;
    }

    .ace_gutter-cell {
      color: rgba(151,137,152,.5)!important;
    }

    .ace_keyword {
      color:#4a91e2!important;
    }

    .ace_type {
      color:#4a91e2!important;
    }

    .run-wrapper {
      flex-direction: row;
      display: flex;
      justify-content: space-between;
      margin-left: 48px!important;
      background: #F1F1F1;
    }

    #run-message {
      text-align: left;
      font: 13px/normal 'Ubuntu Mono', 'Monaco', 'Menlo', 'Consolas', 'source-code-pro', monospace!important;
      font-size: bold;
      padding: 7px;
    }

    .run {
      background: #33b277;
      color: #FFF;
      width: 30px;
      text-align: center;
      font: 13px/normal 'Ubuntu Mono', 'Monaco', 'Menlo', 'Consolas', 'source-code-pro', monospace!important;
      cursor: pointer;
      font-size: bold;
      padding: 7px;
    }

    #run-console {
      width: 100%;
    }

    .run-console-entry {
      margin-left: 42px;
      margin-top: 10px;
      border-radius: 4px!important;
      border: 1px solid #F1F1F1!important;
      padding: 8px;
      background: #f9f8f7;
      word-wrap: break-word;
    }

</style>

await import('https://unpkg.com/@fuel-js/wallet@latest/umd/fuel.umd.min.js');

// Create a new wallet with a new key
// Tip: try setting `null` to `web3.currentProvider` to run with MetaMask
const wallet = new fuel.Wallet(null, {
  network: 'rinkeby',
});

// Get yourself some fake Moons
await wallet.faucet();

// Establish faucet token id
const faucetToken = fuel.constants.faucetToken;

// Get your fake moons balance
console.log('my balance: ',
  await wallet.balance(faucetToken, { format: 'ether' }));

// Send yourself some faucet token
const tx = await wallet.transfer(faucetToken, wallet.address, '4.5', { units: 'ether' });

// Checkout your transaction on the Block Explorer
console.log('check out your tx: ' + window.rinkebyTx + tx.transactionId);



  
  run



<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.3.3/ace.js" type="text/javascript" charset="utf-8"></script>

<script>
  var editor = ace.edit("editor");
  editor.renderer.setPadding(8);
  editor.setTheme("ace/theme/chrome");
  editor.setFontSize("15px");
  editor.setOption("highlightActiveLine", false);
  editor.session.setMode("ace/mode/javascript");
  editor.setShowPrintMargin(false);
  editor.session.setUseWorker(false);
  editor.renderer.setPadding(8);

  document.getElementById('run').addEventListener('click', () => {
    let code = editor.getValue()
      .replace('require("@fuel-js/wallet")', 'window.fuel')
      .replace(/console.log/g, "window.consoleLog");

    document.getElementById("run-console").innerHTML = '';

    document.getElementById("run-console").scrollIntoView();

    document.getElementById('run-message').innerHTML = 'running...';

    const regex1 = window.importRegex();

    (async () => {

      try {
        document.getElementById('run-message').innerHTML = 'running...';
        eval(`
        (async () => {
          try {
            ${code}
            document.getElementById('run-message').innerHTML = 'complete';
          } catch (syncError) {
            document.getElementById('run-message').innerHTML = 'error';
            window.consoleError(syncError);
          }
        })();
        `);
      } catch (error) {
        document.getElementById('run-message').innerHTML = 'error';
        window.consoleError(error);
      }

    })();
  });
</script>

---

## File: src/v1.0.0/2. Getting Started/2. Running a Node.md

Running a Node
===

[](https://badge.fury.io/js/%40fuel-js%2Fclient)

The Fuel client can be used to sync with Fuel and fully validate the chain.

Binary Releases
---

Binary releases can be found at [https://github.com/FuelLabs/fuel-js/releases](https://github.com/FuelLabs/fuel-js/releases)

Running from Command Line
---

Download a release ([above](#releases)) and use an available network specifier and RPC endpoint to get started.

```bash
fuel --network="rinkeby" --rpc="https://localhost:8545"
```

### Additional Parameters

```bash
⚡ fuel [options]

  Options:

    -n, --network         the ethereum network "rinkeby"; default "rinkeby"
    -r, --rpc             a standard Ethereum RPC provider (i.e. local go-ethereum)
    -i, --infura          an Infura service API key (--network must also be specified)
    -es, --etherscan      an Etherscan service API key (--network must also be specified)
    -e, --environment     use the environment variables to specify node parameters
    -o, --operators       a comma-separated list or seed phrase of Ethereum private keys used for block, root, and fraud commitments

  Examples:

    $ fuel --network="ropsten" --rpc="http://localhost:8545"
```

Running from GUI
---

Coming Soon™...

---

## File: src/v1.0.0/2. SDK/1. Wallet.md

Wallet SDK
===

[](https://badge.fury.io/js/%40fuel-js%2Fwallet)

new
---

**new _fuel_ . Wallet** ( provider [, options ] )

### Installation
**node.js**

```bash
npm install --save @fuel-js/wallet
```

**browser (UMD)**

```html
<script src="https://unpkg.com/@fuel-js/wallet@latest/umd/fuel.umd.min.js" type="text/javascript">
</script>
```

**browser (ESM)**

```html
<script type="module">
  import fuel from "https://unpkg.com/@fuel-js/wallet@latest/umd/fuel.umd.min.js";
</script>
```

### Usage
```js
import fuel from '@fuel-js/wallet';

// use the window provider key / account / eth_signTypedData_v4 for transaction signing
const wallet = new fuel.Wallet(window.web3.currentProvider);


(async () => {

  // make a deposit
  await wallet.deposit(daiAddress, fuel.utils.parseEther('1.0'));

  // make a transfer
  await wallet.transfer(daiAddress, recipientAddress, fuel.utils.parseEther('1.0'));

  // listen for new inputs and balance changes
  wallet.on('input', input => {
    console.log('listening for new inputs: ', input);
  });

  // get your address
  console.log('my address', wallet.address);

})();
```

### Description
The **Wallet** object allows you to interact with a Fuel instance.

This object is heavily powered by the [ethers](https://github.com/ethers-io/ethers.js/) library. [web3.js](https://github.com/ethereum/web3.js/) providers are also supported.

The **Wallet** wrapper will simply use the provided **provider** object's *eth_signTypedData_v4* method for signing transactions.

If neither are available, you can use the **Wallet** object as a read-only wallet. You may also provide an override **privateKey** which will be used in place of the provider. The storage and management of this privateKey is up to the developer.

Ethereum **gasPrice** and **gasLimit** options are only needed when using the **force** feature of SDK methods, which will allow users the option of creating their own rollup blocks.

### Params
- **provider** : ***Web3Provider*** | ***EthersProvider***; a web3 or ethers `Provider` object
- **options** : ***Object***


    - **privateKey** : `Hex` | `Uint8Array` |  `SignerKey`; the override 32 byte Ethereum standard private key used for signing transactions. Used instead of the provider signing using `eth_signTypedData_v4`
    - **gasPrice** : `Hex` |  `BigNumber`; the Ethereum gas price for forced transactions
    - **gasLimit** : `Hex` |  `BigNumber`; the Ethereum gas limit for forced transactions
    - **address** : `Hex`; the read-only 20-byte hex string address for watching balances
    - **db** : `LevelDown`; a [leveldown-compliant database instance](https://github.com/Level/leveldown) for storing inputs and outputs temporarily or persistently
    - **sync** : `Boolean`; sync before each wallet action, this can be turned off for better performance but you will have to manage `sync` manually by using `await wallet.sync()`, see [Performance and Syncing](#performanceandsyncing) for more details.

### Throws
  - If the `db` is invalid or will not open
  - If the `privateKey` is invalid or incorrect, if provided

```js
const wallet = new fuel.Wallet(window.web3.currentProvider, {
  db: require('level-js')(), // a leveldown-compliant database
});
```

deposit
---

**_wallet_ . deposit** ( token, amount [, options] ) => Promise<[`TransactionResponse`](#transactionresponse)>

### Description
The `deposit` method will deposit ERC-20 tokens or ETH into the Fuel.

### Params
- **token** : `Hex`; `Number`; `BigNumber`; the 20-byte ERC-20 token address or ID number
- **amount** : `Number` | `Hex` | `BigNumber`; the amount to deposit into Fuel
- **options** : [`OptionsObject`](#optionsobject)

### Returns
This method returns a [`TransactionResponse`](#transactionresponse) object.
- **response** : [`TransactionResponse`](#transactionresponse); the transaction response object

### Throws
- If there is insufficient balance of the ERC-20 token or ETH to cover amount and gas fees
- If the timeout has passed and no Fuel block producer has picked up the deposit

```js
await wallet.deposit(daiAddress, 500000, {
  // gasPrice: ...,
  // gasLimit: ...,
  // from: '0x...',
  // timeout: 10000, // seconds
});
```


faucet
---

**_wallet_ . faucet** ( [, options] ) => Promise<Void>

### Description
This method will call the Fuel network faucet, based upon your network, and send the `wallet.address` test tokens to play with.

Note, this method might take up to a few minutes to work and is rate-limited.

### Params
- **options** : [`OptionsObject`](#optionsobject)

### Throws
- If the `options.timeout`, default `100` seconds (or `100000` micro-seconds) times out.

```js
await wallet.faucet();
```

balance
---

**_wallet_ . balance** ( token, [, options] ) => Promise<[`BigNumber`](#bignumber)>

### Description
This method will give you your current balance for a specific token.

### Params
- **token** : `Hex`; `Number`; `BigNumber`; the 20-byte ERC-20 token address or ID number
- **options** : [`OptionsObject`](#optionsobject)

### Returns
This method returns a [`BigNumber`](#bignumber) object containing the balance.
- **balance** : [`BigNumber`](#bignumber); the balance for the token

### Throws
- If the token is invalid or is not registered with Fuel

```js
await wallet.balance(daiAddress);
```

transfer
---

**_wallet_ . transfer** ( token, to, amount [, options] ) => Promise<[`TransactionResponse`](#transactionresponse)>

### Params
- **token** : `Hex`; `Number`; `BigNumber`; the 20-byte ERC-20 token address or ID number
- **to** : `Hex`; the 20-byte recipient address
- **amount** : `Number` | `Hex` | `BigNumber`; the amount to transfer
- **options** : [`OptionsObject`](#optionsobject)

### Returns
This method returns a [`TransactionResponse`](#transactionresponse) object.
- **response** : [`TransactionResponse`](#transactionresponse); the transaction response object

### Throws
- If there is insufficient balance of the ERC-20 token or ETH to cover amount and fees
- If there is a connection or provider issue

```js
await wallet.transfer(daiAddress, someAddress, 250000, {
  // inputs: [], // specify explicit array of UTXO IDs to spend
  // feeLimit: 2000,
  // from: '0x....',
  // gasPrice: ..., // only used if forcing a tx
  // gasLimit: ..., // only used if forcing a tx
  // force: true, // will attempt for force tx on-chain
});
```

withdraw
---

**_wallet_ . withdraw** ( token, amount [, options] ) => Promise<[`TransactionResponse`](#transactionresponse)>

### Description
This function allows you to start a long withdraw from Fuel. You first send the withdraw transaction on Fuel, then you complete the withdrawal on Ethereum [2 weeks later](./../3.%20Concepts/0.%20Fundamentals/7.%20Deployment%20Parameters.md).

### Params
- **token** : `Hex`; `Number`; `BigNumber`; the 20-byte ERC-20 token address or ID number
- **amount** : `Number` | `Hex` | `BigNumber`; the amount to withdraw
- **options** : [`OptionsObject`](#optionsobject)

### Returns
This method returns a [`TransactionResponse`](#transactionresponse) object.
- **response** : [`TransactionResponse`](#transactionresponse); the transaction response object

### Throws
- If there is insufficient balance of the ERC-20 token or ETH to cover amount and fees
- If there is a connection or provider issue

```js
await wallet.withdraw(daiAddress, 250000, {
  // inputs: [], // specify explicit array of UTXO IDs to spend
  // feeLimit: 2000,
  // from: '0x....',
  // gasPrice: ..., // only used if forcing a tx
  // gasLimit: ..., // only used if forcing a tx
  // force: true, // will attempt for force tx on-chain
});
```

retrieve
---

**_wallet_ . retrieve** ( [options] ) => Promise<[`TransactionResponse`](#transactionresponse)>

### Description
This will complete finalized withdrawals. Withdrawals must first be started using [`withdraw`](#withdraw).

### Params
- **options** : [`OptionsObject`](#optionsobject)

### Returns
This method returns a [`TransactionResponse`](#transactionresponse) object.
- **response** : [`TransactionResponse`](#transactionresponse); the transaction response object

### Throws
- If there is insufficient balance of the ERC-20 token or ETH to cover amount and gas fees
- If there is a connection or provider issue

```js
// after 2 weeks...
await wallet.retrieve({
  // inputs: [], // specify explicit array of utxo hashes to retrieve
  // from: '0x....',
  // gasPrice: ..., // only used if forcing a tx
  // gasLimit: ..., // only used if forcing a tx
});
```

sync
---

**_wallet_ . sync** ( [options] ) => Promise<`Void`>

### Description
The `sync` method will simply download the current UTXOs for this wallet from the Fuel provider.

### Throws
- If there is a connection or provider issue
- If there was an issue getting the private account via `eth_getAccounts`
- If there was an issue getting the current Ethereum network from the provider

```js
  // sync your wallet with the Fuel api
  await wallet.sync();
```

on
---

**_wallet_ . on** ( type, listener )

### Description
The `on` method is used to register listeners for incoming transactions from the Fuel API. Once an `on` listener is registered, the wallet becomes _live_, and balances will automatically update.

If there is a problem with the listener at any time or it fails to bind, the `error` type will be used.

### Params
- **type** : `String`; either `input` or `error`
- **listener** : `Function`; a callback function which will include a single argument: a `UTXO`, `Root` or `Deposit` proof object

```js
wallet.on('input', utxoOrRootProof => {
  console.log(utxoOrRootProof);
});

wallet.on('error', error => {
  console.log(error);
});
```

fee
---

**_wallet_ . fee** ( token ) => Promise<`BigNumber`>

### Description
Get the current feerate for an ERC-20 token.

### Params
- **token** : `Hex`; `Number`; `BigNumber`; the 20-byte ERC-20 token address or ID number

### Returns
- **fee** : `BigNumber`; the feerate for this ERC-20 token

### Throws
- If this token has no feerate available, i.e. the Fuel operator has not allowed this token yet

```js
  // get the current fee for processing a specific token
  await wallet.fee(daiAddress);
```

Performance and Syncing
---

Note, that the **Wallet** by default will **sync** before each action (i.e. **transfer**, **balance** etc), you may turn this off by setting `{ ..., sync: false }` in either the global wallet options or per each method.

If you do this, you must manually manage **sync** operations using the **wallet.sync()** method when needed (e.g. upon account load or when the wallet balance is zero).

Objects
---

### OptionsObject
  - **inputs** : `Array [ Hex, ... ]`; an array of 32-byte hex values specifying either the `Root`, `Deposit` or `UTXO` IDs you would like to spend
  - **feeLimit**: `BigNumber`; the maximum feerate to accept for submitting the transaction
  - **gasPrice** : `Hex` |  `BigNumber`; the Ethereum gas price for forced transactions
  - **gasLimit** : `Hex` |  `BigNumber`; the Ethereum gas limit for forced transactions
  - **from** : `Hex`; the 20-byte sender address to specify either the provider signer or the override private key
  - **timeout** : `Number`; the timeout to wait in seconds for the `Promise` to either fail or be accepted
  - **force** : `Boolean`; force this method into a single `Root` on Ethereum
  - **sync** : `Boolean`; do an account `sync` before the given method or action.

### UTXO
  - **transactionId** : `Hex`;
  - **outputIndex** : `BigNumber`;
  - **outputType** : `BigNumber`;
  - **owner** : `Hex`;
  - **amount** : `BigNumber`;
  - **token** : `BigNumber`;
  - **digest** : `Hex`;
  - **expiry** : `BigNumber`;
  - **returnOwner** : `Hex`;

### Root
  - **producer** : `Hex`;
  - **merkleTreeRoot** : `Hex`;
  - **commitmentHash** : `Hex`;
  - **length** : `BigNumber`;
  - **feeToken** : `BigNumber`;
  - **fee** : `BigNumber`;

### Deposit
  - **owner** : `Hex`;
  - **token** : `BigNumber`;
  - **blockNumber** : `BigNumber`;
  - **value** : `BigNumber`;

### BigNumber
  - This is an `ethers` wrapped BigNumber object, using BN.js under the hood.

Response Objects
---

### TransactionResponse
  - **transactionId** : `Hex`; the Ethereum transaction hash
  - **receipts** : `Array`; an array of Ethereum transactions receipts, if any. Namely for deposits, withdrawals or forced transfers.

---

## File: src/v1.0.0/3. Concepts/0. Fundamentals/1. Fuel Overview.md

Fuel Overview
===

This section of the docs goes over the fundamental technical details of the Fuel rollup chain: what it is, how it works, and why it is scalable and secure.

Background
---

Fuel is an _optimistic rollup_, a special sidechain architecture that is both trust-minimized and permissionless. Unlike a [traditional sidechain](https://blockstream.com/sidechains.pdf), where the safety of user funds is dependent on the honest majority of some set of validators that is disjoint from the main chain's miners, optimistic rollups borrow security directly from the main chain (Ethereum).

The simplified version of [optimistic rollups](https://ethresear.ch/t/minimal-viable-merged-consensus/5617) is as follows. Anyone may construct a rollup block off-chain and [submit it to Ethereum as _calldata_](https://vitalik.ca/general/2019/08/28/hybrid_layer_2.html) (i.e. simple binary data attached to a transaction). Each block submitted in this manner must build upon the previous rollup block (a contract keeps track of block header hashes for the rollup chain) and include a parametrizable bond. If a block is invalid, a [compact fraud proof](https://arxiv.org/abs/1809.09044) can be submitted and processed on-chain by anyone, which will roll back the rollup chain to the previous block, burn a portion of the bond, and reward the fraud prover with the rest. After a parametrizable timeout, rollup blocks are _finalized_, and are considered valid (i.e. can no longer be proven fraudulent) and their bond unlocked. Withdrawals are initiated by burning coins on the rollup, then completing the withdrawal after that rollup block has finalized.

Interacting with Fuel
---

|    |
| :------------------------------------: |
| _Fuel node interacting with Ethereum._ |

Users send Fuel transactions to a Fuel node, which enters the node's mempool as an unconfirmed transaction. The client combines transactions into a Fuel block, which is then sent to Ethereum as _calldata_, at which point the Fuel block is confirmed. The node also reads deposit events from Ethereum, adding deposits as spendable state elements on Fuel.

|  |
| :-------------------------------------------------------: |
|  _Fuel normal (above) and forced (below) transactions._   |

There are two ways of getting Fuel transactions included in blocks. In the first, under normal operation, the users send transactions to a Fuel node, which then combines them into batches (roots), and finally into a block (which contains several roots). In the second, a user wants to use their own Fuel node to submit a new block, i.e. a forced transaction. In this case, they can create a root and block independently of any other node and submit it to Ethereum directly.

|  |
| :------------------------------------------: |
|               _Entering Fuel._               |

Depositing funds into Fuel is done by simply sending them to the Fuel contract (or optionally through a [token funnel](./../4.%20Additional%20Modules/Funnels.md)), at which point the deposits will be added to the state of the Fuel chain.

|             |
| :---------------------------------------------------: |
| _Exiting Fuel normally (above) with quickly (below)._ |

Withdrawing funds from Fuel can be done in two ways: standard and fast. For standard withdrawals, a user simply burns their coins on Fuel, then after a [delay](./7.%20Deployment%20Parameters.md), can complete the withdrawal on Ethereum. For [fast withdrawals](./../../4.%20Tools%20and%20Applications/0.%20Fast%20Withdrawals.md), a user contacts a liquidity provider and atomic swaps funds from Fuel to Ethereum in a matter of minutes.

Architecture: A High-Level View
---

Fuel is unique among Ethereum rollups in that it uses a [UTXO](https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch06.asciidoc#transaction-outputs-and-inputs)-based transaction system. This allows for parallel transaction validation, and in the future stateless predicate validation for spending conditions, greatly increasing scalability compared to contemporary accounts-based blockchains and rollups.

Each transaction can spend [up to eight inputs and produce up to eight outputs](./4.%20Transaction%20Architecture.md). This allows atomic multi-user transactions, e.g. for an on-chain atomic exchange, which also means that non-custodial exchanges [can be built on top of Fuel](./../../4.%20Tools%20and%20Applications/3.%20Non-Custodial%20Exchanges.md). The deterministic and stateless nature of computing state element (UTXO) IDs produced and consumed by transactions enables long chains and [even trees of pre-signed transactions](../../4.%20Tools%20and%20Applications/1.%20Token%20Minting.md) to be constructed.

State elements (UTXOs and deposits) can be [_colored_](https://en.bitcoin.it/wiki/Colored_Coins), i.e. represent different assets. This allows transactions to natively handle both ETH and any ERC-20 token.

Fuel supports a number of spending conditions that allow for powerful implicit expressivity:
- [HTLC outputs](https://en.bitcoin.it/wiki/Hash_Time_Locked_Contracts), which have both a hashlock and a timelock. These enable cross-chain atomic swaps (including between Fuel and Ethereum for [instant withdrawals](./../../4.%20Tools%20and%20Applications/0.%20Fast%20Withdrawals.md)). They can also be used as a signaling mechanism (e.g. to vote in a DAO), and when combined with a chain of pre-signed transactions, for cancellable subscriptions.
- [Return outputs](https://en.bitcoin.it/wiki/OP_RETURN), which are unspendable and can include a long binary blob. These can be used to build applications that are executed client-side and use Fuel for timestamping messages cheaply.

The fraud proof scheme used by Fuel is unique in that [it does not require state serialization](https://ethresear.ch/t/compact-fraud-proofs-for-utxo-chains-without-intermediate-state-serialization/5885) (computing the Merkle root of the state) after every transaction, or even after every block. State serialization is one of the biggest bottlenecks for Ethereum and accounts-based rollups today, and remains a Herculean challenge to optimize implementations around. This, along with parallelizable transaction validation, make Fuel the most scalable rollup in the world.

Fuel's block production model is entirely permissionless, and requires no token (and will never require a token). Anyone may start by submitting a [_root_](./../1.%20Data%20Structures/Roots.md), a bundle of Fuel transactions, to Ethereum. The root can then be included in a [Fuel block](../1.%20Data%20Structures/Blocks.md) by anyone, with a small caveat. The Fuel operator has a short period of time (on the order of minutes, a parameter) where they are the only one that can use this root in a block. This allows the operator to reliably provide a soft confirmation to a recipient that a transaction will be included in the next Fuel block. While this is the default and preferred configuration, using an operator is a system parameter that can be disabled trivially on contract creation if soft confirmations aren't needed.

What To Read Next
---

For a detailed analysis of Fuel's security guarantees, and how it compares to other scaling technologies, see [the next page](2.%20Security%20Analysis.md). (_Warning: this document assumes a high level of technical proficiency._)

A more in-depth survey of Fuel's components is given [here](6.%20System%20Description%20Primer.md), with [block](3.%20Block%20Architecture.md) and [transaction](4.%20Transaction%20Architecture.md) architecture descriptions also available.

The canonical serialization scheme is defined [here](5.%20Serialization.md).

Finally, the parameters used for deployments across different networks is found [here](7.%20Deployment%20Parameters.md).

---

## File: src/v1.0.0/3. Concepts/0. Fundamentals/2. Security Analysis.md

Security Analysis
===

- [Common Definitions](#common-definitions)
    - [Desiderata](#desiderata)
- [Channels](#channels)
    - [Channel Networks](#channel-networks)
- [Sidechains](#sidechains)
- [Plasma](#plasma)
    - [Plasma MVP](#plasma-mvp)
    - [Plasma Cash](#plasma-cash)
    - [Validium](#validium)
- [Rollups](#rollups)
    - [ZK Rollups](#zk-rollups)
    - [Optimistic Rollups](#optimistic-rollups)
        - [Interactive Verification Games](#interactive-verification-games)
- [Optimistic vs ZK Rollups](#optimistic-vs-zk-rollups)
- [Rollup Mythbusting](#rollup-mythbusting)
- [Conclusion](#conclusion)
- [See Also](#see-also)

This page will provide a comprehensive overview of the security and scalability properties of Fuel as it compares to other so-called "scaling solutions." It argues that Fuel is uniquely positioned in the trade-off space to be the best scaling architecture today.

Common Definitions
---

We must first begin by establishing common definitions for desirable properties in a scaling solution. The following definitions are informal, but sufficiently precise to enable proper discussion on the matter. Note that they apply to both "layer-2" constructions as well as base "layer-1" blockchains.

**Security** Security can be roughly defined as the cost to manipulate history. Example: the security of Proof-of-Work blockchains can be measured as the capex and opex of producing new blocks. The security of Proof-of-Stake blockchains can be measured [as the penalty that can be applied](https://medium.com/@ercwl/proof-of-stake-is-less-wasteful-b2854a191766) if a history re-organization is done.

**Trustless** Trustlessness has two components: [_state liveness_ and _state safety_](https://arxiv.org/abs/1904.06441). State is live if it can be consumed by its owner in finite time (in other words, it cannot be burned/locked forever), and safe if it cannot be consumed by its non-owners ever (in other words, it cannot be stolen). This is a more precise concept than _non-custodial_. It is critical to evaluate the trustlessness of a system across both these dimensions, not only state safety. It is also critical to consider worst-case scenarios (i.e. failure modes), not only the optimistic case.

Decentralized blockchains cannot be completely trustless; to illustrate, consider that 51% of miners in a Proof-of-Work blockchain could censor any future transaction (effectively burning censored funds, which allows for [indirect theft](https://ethresear.ch/t/trustless-validator-blackmailing-with-the-blockchain/6922)) or even re-organize the history from genesis to steal all funds. Therefore we measure trustlessness as _the assumptions under which_ a system is trustless. As an example, if we assume 51% of miners are honest, then a blockchain is trustless. We can describe a system that is almost as trustless as another as **trust-minimized** with respect to the other (e.g. a trust-minimized sidechain is trustless under almost the same assumptions as its main chain).

**Permissionless** A system is permissionless if it requires no in-system action for a new user to begin participating. It is permissioned otherwise.

**Decentralization** While commonly (and incorrectly) described as "the number of nodes," decentralization is measured as [the cost to run a fully validating node](https://www.truthcoin.info/blog/measuring-decentralization/). Actually running a full node at all times is not required, but we must consider the worst-case scenario of having to run a full node. While permissionlessness is a necessary property for decentralization, it does not otherwise provide a metric for measuring decentralization. _Note:_ this definition is actually [missing a very important detail](#zk-rollups), but will suffice for now.

**Scalability and Throughput** Often a point of contention and confusion, scalability is front-and-center as the most obvious problem for contemporary blockchains. First, _throughput_ is the total transaction throughput of the system, measured in transactions per second. This is often the metric incorrectly advertized as scalability. _Scalability_ is the ratio of total transaction throughput to cost of running a node. Therefore, comparing transactions per second between two systems without simultaneously comparing their costs is comparing apples to oranges. It is trivial to increase throughput by just increasing the cost to run a node, but that is not an increase in scalability.

> **Note:** It is critical to consider _worst-case_ scalability, not average-case or optimistic-case. Blockchains are adversarial environments; if something can be griefed and DoSed it will be griefed and DoSed.

> **Note:** While the _naming_ of the above properties may certainly be debated, that they are desirable properties in any scaling solution, and good metrics for evaluating such solutions, cannot. Trustlessness is especially critical; consider needing to choose between using an unscalable decentralized blockchain and a high-throughput custodial exchange. Neither option is even a choice.

### Desiderata

In order to be a "good" layer-2 scaling solution, we need the following properties _simultaneously_:
1. The system must have equal or almost-equal security to the main chain. Non-trivial trade-offs in security are unacceptable from a scaling solution.
1. The system must be trust-minimized with respect to Ethereum. Adding meaningful trust assumptions, similar to reducing security, is unacceptable.
1. The system should be permissionless. This is not a hard requirement, so long as the system is trustless, but is highly desirable.
1. The system must have higher throughput than Ethereum.
1. The system should be more scalable than Ethereum. In the context of decentralization (cost of running a full node): the marginal cost of each layer-2 transaction must be lower than the marginal cost the same transaction at layer-1.
1. Additional desiderata include:
    - No need for hot keys
    - Backups support, only private keys are sufficient to recover funds
    - No novel cryptography
    - Capital efficient
    - Low latency
    - Generalizability/expressivity

Lastly, similar decentralization to Ethereum: running a node for the layer-2 must not be more expensive than running a full node for Ethereum. Note that this is a deployment parameter, and is not intrinsic to any of the schemes discussed here. To have a common basis for comparison: we want to be able to handle more transactions in our layer-2 than layer-1 Ethereum (with the same or similar trust assumptions), with the same hardware.

Put another way, everyone who could ever be interested in a particular interaction must fully validate that interaction (trust-minimization). If a layer-2 interaction is cheaper to validate than it would have been to validate on layer-1, then the layer-2 system provides scalability. If there are trustless guarantees that a particular interaction does not need to be validated by all users, then this can increase total transaction throughput without proportionally increasing full node costs (i.e. _unconditional scalability_). If there are no guarantees of this, then there may be _conditional scalability_, usually by deploying multiple instances of a scaling scheme with different participants.

Channels
---

Channels are one of the earliest blockchain scaling proposals. Originally taking the form of [payment channels](https://en.bitcoin.it/wiki/Payment_channels), they can be extended to arbitrary computation with [state channels](https://www.jeffcoleman.ca/state-channels).

A fixed set of participants open a channel with an on-chain transaction that defines the rules of the channel. Updates to the channel state are made by unanimous consent: all participants signing a state update, communicated off-chain. Any participant may attempt to close the channel on a particular state, which starts a timeout during which anyone may submit a later state to penalize a fraudulent channel close attempt. If no later state has been shown by the timeout, the channel closes, settling balances based on the closing state.

Metrics:
1. Same security as the main chain. Channel updates are not timestamped to Ethereum, so technically it is possible to manipulate the channel history, but only under the same failure mode as a trust-minimization failure (below).
1. Trust-minimized, with an additional trust assumption: if the majority of miners censor transactions (which requires attacking the main chain), a proof of fraudulent channel close attempt can be censored, allowing theft of funds. Miners [can already indirectly steal funds through censorship of the main chain](https://twitter.com/jadler0/status/1227321845407506432), so this is not a meaningfully stronger trust assumption.
1. It is permissionless to open a channel, but participation in any specific channel is permissioned and fixed. This means e.g. [Uniswap](https://uniswap.org) cannot be implemented using only channels.
1. The total aggregate throughput can be substantially increased by using channels.
1. For a single channel, scalability depends on the execution model used, but it will usually be much cheaper to execute a transaction in a channel than it would be to validate it on Ethereum. For multiple channels, there is conditional scalability if the sets of participants is disjoint, which is usually the case since open-participation systems cannot be built with channels in the first place.
1. Additional concerns:
    - Hot keys are required to take advantage of the low latency of channels.
    - Backups are not possible, only copies (backups can recover everything but a delta, while copies are all-or-nothing). Only the latest channel state is useful, and in fact old channel states are worse-than-useless as attempting to close the channel with an old state will result in a penalty. Private key backups are insufficient to ensure funds cannot be lost.
    - Capital inefficient: funds must be locked up inside a channel before being used, and cannot be unlocked quickly without cooperation from the specific channel participants.
    - Instant finality: as soon as a state update is signed unanimously, it is instantly finalized.
    - Generalizable to contracts between a fixed participant set.

In summary, while trust-minimized, channels make enormous sacrifices in terms of capital efficiency, user experience, and open participation to achieve instant finality, which is a feature not possible with blockchains. As such, unless instant finality is a critical requirement, channels are unsuitable as a scaling solution.

### Channel Networks

[Channel networks](https://en.bitcoin.it/wiki/Lightning_Network) link together multiple channels with atomic multi-channel interactions. This allows for interactions between distinct channels, but still does not allow open participation on a shared state (i.e. [Uniswap](https://uniswap.org) cannot be implemented using a channel network). They are unreliable unless an overwhelming majority of channel network participants are online simultaneously, which facilitates and aggravates [a](https://arxiv.org/abs/2006.01418) [number](https://arxiv.org/abs/2006.08513) [of](https://arxiv.org/abs/2003.12470) [attacks](https://arxiv.org/abs/1904.10253).

In summary, channel networks do not diverge meaningfully from channels in the trade-off space.

Sidechains
---

[Sidechains](https://blockstream.com/sidechains.pdf) are blockchains that fully validate another blockchain as part of their consensus rules (e.g. a sidechain to Ethereum is a blockchain that validates the Ethereum chain). There are a number of ways sidechain blocks can be produced, including Proof-of-Authority (PoA, a single block producer), a federation, Nakomoto Consensus with Proof-of-Work (PoW), or even a consensus protocol using Proof-of-Stake (PoS) for Sybil resistance.

The _two-way peg_ design of the sidechain (i.e. the mechanism for locking tokens for use on the sidechain, then unlocking them back to the main chain) is critical. A trust-minimized two-way peg is ideal, but is not feasible with plain sidechains.

Metrics:
1. Sidechains _can_ have the same security as the main chain by timestamping sidechain block header hashes on the main chain.
1. A trust-minimized two-way peg is not possible with plain sidechains, since data withholding [is not a uniquely attributable fault](https://github.com/ethereum/research/wiki/A-note-on-data-availability-and-erasure-coding). A sidechain that adds features to make its two-way peg trust-minimized ends up becoming a [Plasma](#plasma) or a [rollup](#rollups).
1. Due to data withholding, sidechains degenerate to being permissioned: a cabal of sidechain block producers can create a block that other sidechain block producers can never build upon.
1. Any number of sidechains may be deployed in parallel, so throughput can be greatly increased.
1. Sidechains may have any execution model. As such, they can have a different—and more scalable—execution model than the main chain.
1. Additional concerns:
    - Sidechains are flexible: they can be faster, cheaper, and more expressive than the main chain.

In summary, plain sidechains have a number of nice features, namely their flexibility, but are not trust-minimized. As such, they are unacceptable as a scaling solution.

Plasma
---

[Plasma](https://plasma.io/plasma.pdf) is a scheme for trust-minimized but permissioned sidechains with exponentially lower on-chain costs. This requires transaction data to be kept entirely off-chain. Different flavors of Plasma (described below) have some common elements. Each Plasma block header is submitted by an _operator_ to a contract on Ethereum (which means Plasma has at least as high a latency as Ethereum). Withdrawals from the Plasma chain (i.e. _exits_) are involved, and are what allows for (in theory) a trust-minimized two-way peg.

All Plasma variants are permissioned, or degenerate to become permissioned. Even if more than a single operator is used (e.g. using some PoS protocol for Plasma block production) a cabal of operators can produce a block and withhold data, preventing other operators from ever building upon it. In fact, using PoS for Plasma block production is actively detrimental and worse-than-useless, as it adds friction and cost to end users without actually providing any of the nice properties of PoS-based consensus protocols. This is because [we cannot recover from PoS consensus failures without hard forks](https://ethresear.ch/t/against-proof-of-stake-for-zk-op-rollup-leader-election/7698), and it is impossible to trustlessly upgrade a smart contract.

This scaling scheme [has mostly been abandoned](https://medium.com/dragonfly-research/the-life-and-death-of-plasma-b72c6a59c5ad) in favor of [rollups](#rollups) for additional reasons that will become apparent soon.

### Plasma MVP

[Plasma MVP](https://ethresear.ch/t/minimal-viable-plasma/426) variants were the first concrete flavor of Plasma. A Plasma operator aggregates transactions off-chain, then commits to them in a Plasma block header that is processed on-chain. The UTXO data model is used, but the accounts data model can be used just as well. Exits are initiated on Ethereum against any block. If an exit is invalid (e.g. trying to exit a spent coin), a fraud proof can cancel it; otherwise, the exit is placed in a priority queue based on Plasma block number. After a timeout, the exit can be completed and funds withdrawn from the contract.

However, since Plasma block data can be withheld, the operator can create an invalid Plasma block that gives them all funds, then exit them. Block data is unavailable, so no one can prove the exit is fraudulent. Therefore all users must exit _before_ the timeout expires by exiting their funds from an earlier (available) Plasma block than the malicious operator's exit. This is called a [mass exit](https://ethresear.ch/t/basic-mass-exits-for-plasma-mvp/3316), an involves putting the Plasma chain's entire _state_ onto Ethereum in a short amount of time.

Metrics:
1. Security is borrowed from the main chain, as Plasma blocks are timestamped by Ethereum.
1. Plasma MVP variants are only trust-minimized in theory. In practice, mass exits allow an adversary to start an attack with constant cost (posting a single invalid Plasma block header on-chain) that requires unbounded cost to defend against (users must exit the entire state in a short time, and state is essentially unbounded in size). Therefore Plasma MVP variants degenerate in practice to sidechains.
1. Plasma MVP is a Plasma and thus permissioned.
1. Plasma MVP may have higher throughput depending on the execution model. However, this is purely dependent on the execution model (and has no relation to having a single operator), as all users must fully validate the Plasma MVP chain to ensure their funds are safe.
1. Increased scalability is possible with a more efficient execution model than the EVM.
1. Additional concerns:
    - No need for hot keys.
    - Since data is not available on-chain, users must save a copy of their off-chain state. Private key backups are insufficient to ensure funds cannot be lost.
    - Capital efficient for both users and the operator.
    - Latency cannot be lower than Ethereum, as Plasma blocks are only valid once they are committed to Ethereum.
    - Ethereum-style smart contracts [are not possible on Plasma](https://ethresear.ch/t/why-smart-contracts-are-not-feasible-on-plasma/2598). Predicate spending conditions on UTXOs are possible.

In summary, Plasma MVP variants degenerate to sidechains, with funds being trivial to steal by the operator. As such, they are unacceptable as a scaling solution.

### Plasma Cash

[Plasma Cash](https://ethresear.ch/t/plasma-cash-plasma-with-much-less-per-user-data-checking/1298) variants are the second concrete flavor of Plasma. As with Plasma MVP, a Plasma operator aggregates transactions off-chain, then commits to them in a Plasma block header that is processed on-chain. However, unlike Plasma MVP, a _coins data model_ is used, where each state element is a non-fungible coin (similar to a channel, each coin is uniquely identifiable and cannot be broken up or combined). In order to accept a coin, its entire transaction history must also be downloaded and validated. Exits are initiated on Ethereum against any block. An invalid exit can be disputed or challenged (explained below); otherwise, after a timeout, the exit can be completed and funds withdrawn from the contract.

Since each coins has a distinct owner, each user only needs to check exits that try to withdraw coins they own. There are [two distinct exit challenges](https://www.gakonst.com/plasmacash.pdf):
1. Non-interactive: the exit is spending an spent coin, and you can prove you owned this coin at a later time, within a timeout.
1. Interactive: the exit is spending a coin that you currently own. This is challenged by asking for a valid spend for your currently-owned coin (which should not exist). This can be responded to or not, within a timeout.

In order to always be able to respond to the challenges above, the _entire history_ of a coin (in the form of inclusion and exclusion proofs) must be kept, for each coin. This can quickly become enormous. Attempts to compress this history have led to [research dead ends](https://ethresear.ch/t/rsa-accumulators-for-plasma-cash-history-reduction/3739), or involve simply posting transaction data on-chain (i.e. degenerate to a [rollup](#rollups)).

Users must verify their coins haven't been exited at least once per timeout to ensure safety. However, due to the interactive challenge, watchtowers [cannot be used instead](https://ethresear.ch/t/watchtowers-may-not-work-in-plasma-cash/1968), so users _must_ do this themselves.

Metrics:
1. Security is borrowed from the main chain, as Plasma blocks are timestamped by Ethereum.
1. Plasma Cash variants are trust-minimized in the same way as [channels](#channels), with a synchrony assumption on main chain censorship.
1. Plasma Cash is a Plasma and thus permissioned.
1. Throughput can be substantially higher than Ethereum, as each user only needs to validate the history of coins they own, not the entire Plasma chain.
1. Scalability is conditional on the number of coins a user owns. If the user owns sufficient coins, it might be more expensive to download and validate inclusion and exclusion proofs than fully validating Ethereum.
1. Additional concerns:
    - No need for hot keys.
    - Since data is not available on-chain, users must save a copy of their off-chain state. Private key backups are insufficient to ensure funds cannot be lost.
    - Capital efficient for both users and the operator.
    - Latency cannot be lower than Ethereum, as Plasma blocks are only valid once they are committed to Ethereum.
    - Ethereum-style smart contracts [are not possible on Plasma](https://ethresear.ch/t/why-smart-contracts-are-not-feasible-on-plasma/2598). Predicate spending conditions on UTXOs are possible.

In summary, Plasma Cash is trust-minimized, unlike Plasma MVP. However, it is permissioned, requires enormous off-chain cost to transfer coin history, and requires users to store state lest they lose their funds. As such, it is unsuitable as a scaling solution.

### Validium

_Validium_ is a Plasma-like protocol that uses [validity proofs](https://eprint.iacr.org/2018/046) instead of fraud proofs and a synchrony assumption. In plain English:
- Validity proof: succinct (exponentially cheaper to verify) proof that some computation has a certain result.
- Fraud proof: proof that the result of some computation was incorrect. Requires a synchrony assumption (i.e. a timeout), after which the result is deemed correct if no fraud proof was submitted.

Validium has the benefits over Plasma of not having to worry about the operator producing an invalid block, and being resistant to miner censorship attacks for state safety. This means Validium blocks can be considered immediately finalized, while Plasma blocks are only finalized after the fraud proof timeout has expired. However, the production of validity proofs is expensive and has higher latency, involves novel and hard-to-audit cryptography, and may require a [trusted setup](https://eprint.iacr.org/2012/718).

There is one issue: how do we handle exits? Sure, the operator cannot _steal_ user funds, but they can _lock/burn_ user funds. We must always analyze [both state liveness and state safety](#common-definitions). In a Validium, as in a Plasma, block data is kept off-chain. As such, users may not have the state at the latest block, which would be required to exit seamlessly. We have a few choices:
1. Users initiate an exit on Ethereum, and the operator must process it with a validity proof within some timeout (or provide a proof that the exit is invalid), otherwise the Plasma chain halts. This does not work, as it does not guarantee users can exit since the operator can simply stop processing anything.
1. Users initiate an exit on Ethereum, and if it is not processed by the operator within some timeout, it is force-processed, unless proven invalid with a fraud proof. This means a user can get an invalid exit processed, which defeats the point of using validity proofs.
1. Users initiate an exit on Ethereum, and if it is not processed by the operator within some timeout, the Validium chain _rolls back_ to a previous block. This means we no longer have immediate finality. If we allow [unbounded roll back](https://ethresear.ch/t/roll-up-roll-back-snark-side-chain-17000-tps), then there are no finality guarantees ever (which is unacceptable). If we allow [bounded roll back](https://ethresear.ch/t/mvr-minimally-viable-rollback/7538), then that introduces a synchrony assumption which can be used to steal user funds.

Surprisingly, there is no way to ensure state liveness without re-introducing a synchrony assumption, which makes using validity proofs worse than useless!

> **Note:** Synchrony assumptions can often be obfuscated. From the last link above: "The assumption is that we can recover to a state based on a history that took place not more than k batches ago." This `k` is a synchrony assumption, and user funds can be stolen if it is violated.

In summary, Validium does not actually exist as a separate cryptoeconomic system than Plasma. The use of validity proofs is superfluous, and increases latency and cost for no concrete benefit.

Rollups
---

Different flavors of _rollups_ have many common features:
- Anyone may construct a rollup block (permissionless), and post the _entire block_ to an Ethereum smart contract as _calldata_. The rollup block is not validated in the contract; instead, block validity is ensured by either a validity proof ([ZK rollups](#zk-rollups)) or a fraud proof + synchrony assumption ([optimistic rollups](#optimistic-rollups)). Since rollup block data is available, we can guarantee that block production can always be permissionless, unlike [Plasma](#plasma).
- Withdrawals are initiated on the rollup chain, not Ethereum. Because of this, it is critical that anyone can have a transaction included into the rollup chain in bounded time. This means there is no requirement to monitor and challenge individual exits as in [Plasma](#plasma).
- Rollups borrow security from Ethereum, as all rollup blocks are timestamped on Ethereum. As such, the latency of a rollup chain cannot be lower than Ethereum's blocktime.
- Rollups may provide conditional scalability if multiple instances of a rollup (or multiple different rollups) are used, essentially as a form of heterogenous sharding. How much scalability this provides depends entirely on how often cross-rollup (similar to cross-shard) interactions happen.

> **Note:** An alternative to permissionless block production is permissionless withdrawals only (but permissioned block production). This only works by halting the rollup chain if a withdrawal request isn't processed within some timeout. While technically trust-minimized, this is sub-optimal: exiting from the rollup may be very expensive, especially if the rollup has a lot of state.

### ZK Rollups

ZK rollups were first concretely proposed [by Barry Whitehat](https://github.com/barryWhiteHat/roll_up), and later [refined and simplified](https://ethresear.ch/t/on-chain-scaling-to-potentially-500-tx-sec-through-mass-tx-validation/3477).

In ZK rollups, each rollup block posted to the contract must be accompanied by a [validity proof](#validium) (a succinct proof that the block is valid), which is also verified by the contract. Blocks are thus finalized immediately, and withdrawals can be processed in the same Ethereum block. The block posted as calldata only includes sufficient information to _apply_ each state transition (transaction). Witness data (signatures) can be excluded, as the validity proof proves that such signatures exist and are valid.

Users must do the following work to ensure their funds are safe:
- Audit the circuit, which involves novel cryptography.
- If a trusted setup is used, participate in the trusted setup, or [assume the trusted setup was not compromised](https://twitter.com/AnnaRRose/status/1173594162287054848).
- Fully validate Ethereum.
    - This includes downloading all state transitions.
    - Also includes verifying a validity proof for all rollup blocks. Individual state transitions do not need to be validated.

However, we must analyze the work users must do in the worst case, not the best case. In the worst case, the rollup block producers all go offline and the user must produce their own block. In other words, we must consider both state liveness and state safety, not only state safety.

To produce a new block, a user must re-apply every state transition in the rollup to get the latest state. This is actually the whole point of posting transactions to Ethereum! Notice that while the validity proof proves that a state transition is _valid_, it does not help at all in _applying_ the state transition (which involves database reads and writes). In other words, the "succinct verification" property of validity proofs _only applies to computation with no side effects, not state transitions_.

> **Note:** ZK rollups can only handle transfers and simple variants (such as multi-user transfer and swaps). This is because validity proofs operate on circuits rather than programs, and every possible execution path must be proved at all times. The cost of proving generic computation is intractable in practice, and has never been demonstrated to be viable.

As ZK rollups are limited to transfers, the only computation the validity proof can reduce is signature verification. However, this is not even remotely the bottleneck; modern processors can easily verify _tens of thousands of ECDSA signatures per second_ with [libsecp256k1](https://github.com/bitcoin-core/secp256k1). The bottleneck [is actually state accesses](https://github.com/ethereum/EIPs/issues/648#issuecomment-311351949). In other words, since they do not target the bottleneck, validity proofs in this context provide essentially zero scalability.

Metrics:
1. Security is borrowed from the main chain, as rollup blocks are timestamped by Ethereum.
1. ZK rollups are trust-minimized under the assumptions: 1) that the novel cryptography is sound, and has been implemented correctly despite immature tooling and few qualified auditors, 2) if a trusted setup is used, that the trusted setup was not compromised.
1. Rollups are permissionless.
1. ZK rollups will have higher throughput than Ethereum.
1. Scalability is increased, as the data and execution model is much simpler than Ethereum.
1. Additional concerns:
    - No need for hot keys.
    - Private key backup is sufficient to recover funds.
    - Novel cryptography must be audited by user, or trusted.
    - Capital efficient.
    - Latency cannot be lower than Ethereum, as rollup blocks are only valid once they are committed to Ethereum. ZK rollup blocks are immediately finalized once committed, however due to proof generation times take several minutes or more to be committed.
    - Anything but simple transfer are not possible on ZK rollups.

### Optimistic Rollups

In [optimistic rollups](https://ethresear.ch/t/minimal-viable-merged-consensus/5617), each rollup block posted to the contract must be accompanied by the bond. Blocks are finalized after a timeout, at which point the bond can be recovered. The block posted as calldata must include both state transition information and witness data, unlike [ZK rollups](#zk-rollups).

Anyone may post a fraud proof against a non-finalized block, causing the rollup chain to roll back to the previous block (and burning a fraction of the bond while rewarding the rest to the fraud prover). Therefore, on-chain finality requires waiting until the timeout expires. Valid blocks are guaranteed to finalize, however, so anyone may validate the rollup chain to get immediate finality for off-chain applications (e.g. accepting a payment, or performing an atomic swap).

Fungible tokens can be withdrawn immediately with atomic swaps between the rollup and Ethereum [using a liquidity provider](https://ethresear.ch/t/trustless-two-way-bridges-with-side-chains-by-halting/5728). Note that non-fungible tokens (NFTs) by definition cannot be liquid, therefore withdrawing NFTs from an optimistic rollup must wait the finalization timeout.

There is no inherent restriction on the execution model of an optimistic rollup, so long as [a compact fraud proof](https://arxiv.org/abs/1809.09044) can be produced, and verifying a fraud proof can be done within a single Ethereum block (modulo splitting up a fraud proof into several non-interactive steps). **However, accounts-based execution models will have much lower scalability than Ethereum today.**

This is because fraud proofs for accounts-based execution models require serializing the state after every transaction (or greatly increasing the size of transactions, rendering it strictly inferior to simply using the UTXO data model to begin with). Ethereum _used to_ do this, but [no longer does](https://github.com/ethereum/EIPs/issues/98) since serializing the state is, as the name implies, a sequential (serial) operation, and in general is a huge bottleneck for Ethereum today. The UTXO data model, in addition to parallel transaction validation, allows for [fraud proofs without serializing state](https://ethresear.ch/t/compact-fraud-proofs-for-utxo-chains-without-intermediate-state-serialization/5885), resulting in greatly increased scalability.

Metrics:
1. Security is borrowed from the main chain, as rollup blocks are timestamped by Ethereum.
1. Optimistic rollup are trust-minimized under the assumptions: 1) 51% of miners are not censoring Ethereum for an extended period of time, and 2) there is at least one interested party that will submit a fraud proof if a fraudulent rollup block is committed (which could be the user themselves).
1. Rollups are permissionless.
1. Optimistic rollups may have higher throughput than Ethereum, depending on execution model.
1. Scalability may be increased over Ethereum, depending on execution model. An EVM-based optimistic rollup will result in zero scalability improvements (and in fact scalability will be much worse). A UTXO-based optimistic rollup will be much more scalable than Ethereum.
1. Additional concerns:
    - No need for hot keys.
    - Private key backup is sufficient to recover funds.
    - No novel cryptography.
    - Capital efficient.
    - Latency cannot be lower than Ethereum, as rollup blocks are only valid once they are committed to Ethereum. Valid optimistic rollup blocks are immediately finalized once committed, if clients validate them immediately (allowing immediate off-chain interactions, such as atomic swaps). Otherwise, the timeout to finality can be quite long (for on-chain interactions).
    - Virtually anything can be done in an optimistic rollup, so long as a compact fraud proof can be produced.

#### Interactive Verification Games

An alternative to fraud proofs is an [interactive verification game](https://www.usenix.org/system/files/conference/usenixsecurity18/sec18-kalodner.pdf), in which an interactive game bisects an execution trace until a difference is found. This bounds the maximum cost of a single step of this game to the cost of executing a single step of the trace, unlike fraud proofs where an entire transaction must be executed.

Beyond this distinction, there is little cryptoeconomic difference between optimistic rollups with fraud proofs and interactive verification games. Interactive verification games allow for more flexible execution models (e.g. a single transaction in the rollup that consumes 20 million gas), but result in lower scalability than using a UTXO-based execution model directly (or possibly even worse scalability than Ethereum) since a special virtual machine must be used to execute transactions off-chain. This virtual machine must be designed to have cheap individual operations, but is difficult to optimize for performance.

> **Note:** In theory, an interactive verification game will be more robust against chain congestion attacks that fraud proofs. For example, if a fraud proof costs 9M gas to verify and the block gas limit is 10M, an attacker only needs to fill up blocks up to 1.1M gas to prevent fraud proof transactions from being included. Each step of the interactive verification game is very cheap, so an attacker would need to spam much more to block them from being included. In practice however, the cost of any individual fraud proofs should be intentionally low (less than 20% of the block gas limit or so), so there is no difference.

> **Note:** When using fraud proofs, valid blocks are guaranteed to finalize, as they cannot be proven fraudulent. When using an interactive verification game, a valid block could be rolled back if a challenge on a valid block is intentionally lost. In practice this is not an issue as it requires unanimous participation to throw a challenge.

In summary, if more flexibility is absolutely required (e.g. single huge transactions that cannot be verified with a fraud proof), then an interactive verification game is a good idea. If not, a UTXO-based optimistic rollup with fraud proofs will be more scalable with no downsides.

Optimistic vs ZK Rollups
---

In terms of trust-minimization, users will have to make orthogonal trust assumptions for ZK rollups and optimistic rollups:
- ZK rollups
    - that the novel cryptography is sound, and has been implemented correctly despite immature tooling and few qualified auditors
    - if a trusted setup is used, that the trusted setup was not compromised
- optimistic rollups
    - 51% of miners are not censoring Ethereum for an extended period of time
    - there is at least one interested party that will submit a fraud proof if a fraudulent rollup block is committed (which could be the user themselves)
These assumptions aren't directly comparable, so we cannot really say that one makes stronger assumptions than the other.

It may be tempting to say that miners can steal funds from an optimistic rollup but not a ZK rollup, but that ignores that layer-2 schemes do not exist _in vacuo_. If a majority of miners can censor Ethereum for an extended period of time, then they can also freeze user funds, which allows them to steal funds indirectly [through blackmail](https://ethresear.ch/t/trustless-validator-blackmailing-with-the-blockchain/6922).

Along the same vein, a common talking point in favor is ZK rollups is that a user can walk away for a decade and come back to their coins where they left them...but this is actually not true, even with ZK rollups! It is entirely possible that the layer-1 blockchain itself gets re-organized or otherwise mutated such that a user's funds in a ZK rollup–or even on the layer-1 chain–disappear. Decentralized blockchain are nothing more than mechanisms to facilitate social coordination; [they are governed by people, not math or code](https://uncommoncore.co/unpacking-bitcoins-social-contract/). If a user does not actively watch the layer-1 chain (and the layer-2 with it) at regular intervals, then they cannot defend it–and their funds–from potential adversaries. In other words, regardless of what layer-2 scheme we use, we can assume that the base blockchain provides censorship resistance, because if not we must _actively_ defend it in a timely manner.

In addition, we must consider the following facts:
- In May of 2019, [an attacker stole approximately 7000 BTC from the Binance exchange](https://www.blockchain.com/btc/tx/e8b406091959700dbffcff30a60b190133721e5c39e89bb5fe23c5a554ab05ea) (worth approximately $40M at the time). A bounty [could have been put up to incentivize miners to re-organize the Bitcoin blockchain](https://twitter.com/JeremyRubin/status/1125919526485254144), however was met with community uproar. Miners did not even get the chance to decide on whether to take the bounty or not, because it was never put up.
- In June of 2020, [a bounty of at least $5M (at least two separate $2.5M bounties) was put up to re-organize the Ethereum blockchain even a single block](https://twitter.com/jadler0/status/1270766562870509569). No miner took the bounty.
- In August 2020, approximately $4.5B (4M ETH) [was locked up in Decentralized Finance (DeFi) on Ethereum](https://defipulse.com/). A vast majority of DeFi protocols rely on primitives with timeouts, and assume censorship-resistance of layer-1 to function correctly. Primitives include: oracles, auctions, liquidations, and more. If miners censored Ethereum for any meaningful length of time, they could destroy the equivalent of the economy of a small nation _today_.

In terms of scalability, as mentioned [in the analysis of ZK rollups](#zk-rollups), the specific use of validity proofs provides no scalability. We must consider the worst-case failure mode of all the ZK rollup block producers disappearing or otherwise refusing to produce new blocks, at which point users must apply all state transitions themselves, for which the validity proofs do not help at all. Signature verification is not a bottleneck, so it's all a wash between validating signatures and verifying the validity proofs.

Validity proofs are useful for safe low-latency light clients, which fraud proofs cannot provide as their timeout must be long. This allows for immediate withdrawals (especially of NFTs) and composable interaction between a ZK rollup and other systems (similar to an atomic cross-shard transactions). However, since ZK rollups are limited to transfers and simple variations thereof, the practical usability of composable interactions is dubious.

In terms of on-chain efficiency (i.e. the marginal size of each transaction that must be posted as calldata), witness size for optimistic rollups is not a problem long-term. Rather than using per-transaction signatures, [BLS aggregate signatures](https://ethresear.ch/t/pragmatic-signature-aggregation-with-bls/2105) can be used instead, reducing the on-chain footprint of witness data to constant size per block. Interestingly, optimistic rollups are even more gas-efficient than ZK rollups, as the latter require the validity proof to be posted and verified as well.

To wrap up, the assumptions under which both optimistic rollups and ZK rollups are trust-minimized aren't comparable, and thus saying that one is inherently more trust-minimized than the other would be intellectually dishonest. ZK rollups provide zero scalability gains in practice over optimistic rollups, are more limited in their expressivity, are more expensive to use, and have higher latency-to-first-confirmation. On the other hand, optimistic rollups can only support immediate withdrawals of fungible assets, so they are cumbersome to use with NFTs.

In summary, if using NFTs is critical, then ZK rollups are the better choice. For everything else, UTXO-based optimistic rollups are superior: cheaper, lower latency-to-first-confirmation, more expressive, more scalable.

Rollup Mythbusting
---

**Using PoS for block production is a good idea!** False. _Staking_ a token is worse-than-useless, as 1) [we don't need a native token for security, since we're borrowing security from Ethereum](https://medium.com/@adlerjohn/the-why-s-of-optimistic-rollup-7c6a22cbb61a), and 2) [we can't implement a proper PoS protocol without hard forks, which cannot be done with a smart contract](https://ethresear.ch/t/against-proof-of-stake-for-zk-op-rollup-leader-election/7698). A token simply adds costs and friction and provides nothing in return that cannot be done with ETH. Fuel does not have, and will never have, a "utility" token.

**Rollup transactions are gas-free!** False. Transactions in a rollup still require metering in order to prevent DoS attacks, and to ensure that invalid transactions are fraud-provable. If the execution model of the rollup is the EVM or some other generic VM, then rollup transactions will have to be metered similarly. Fuel currently meters transactions based on size (in bytes), as generic smart contracts are not supported at this time.

> **Note**: The above exclamation is actually half-true. Rollup transactions do not have to pay ETH fees, as the rollup block producer is the only party that must interact with Ethereum to progress the rollup. Therefore rollups can be thought of as [meta-transaction](https://medium.com/@austin_48503/ethereum-meta-transactions-90ccf0859e84) systems, allowing users to pay fees in any token the rollup block producers accepts.

**Rollup transactions are _free_ (as in "free beer")!** False. Each rollup transaction has a marginal cost that must be paid by the block producer as calldata. If a rollup advertizes free transactions, then they are being subsidized from elsewhere–meaning someone else is overpaying fees. Fuel does not advertize transactions as being free.

**Rollup transactions are instant!** False. Rollup blocks must be posted to Ethereum, therefore a rollup cannot have a lower blocktime than Ethereum. [Without a fully-collateralized bond](https://twitter.com/jadler0/status/1184015361475108864), an adversary can double-spend transactions in an unconfirmed rollup block and guarantee a profit. A system with a fully-collateralized bond would end up as a channel. Fuel makes the explicit choice of not having a bond, since that would increase costs without providing any cryptoeconomic guarantees. Instead, our [priority aggregator model](./1.%20Fuel%20Overview.md) allows the Fuel operator to promise an unconfirmed transaction will be included with high reliability, completely non-custodially.

**EVM rollups can do {1000, 10000, 100000, `A(4,3)`} TPS with no downsides!** False. EVM execution is the bottleneck for Ethereum. Throughput cannot be increased beyond the current ~15 TPS without a fundamental sacrifice elsewhere. This could be reduced decentralization with increased full node costs, or an additional trust assumption if users simply don't fully validate the rollup. Both are unacceptable in a scaling solution. Fuel uses a unique UTXO-based execution model that is much more scalable than the EVM, allowing for unparalleled throughput without changing decentralization. This does come at a cost for now: no generic smart contracts (which will be implemented in [Fuel v2](./../../5.%20Future%20Roadmap/1.%20Planned%20Features.md)).

**ZK rollups scale because you only have to verify a succinct proof!** False. Validity proofs [are useless for applying state transitions](#optimistic-vs-zk-rollups), which is by far the bottleneck in contemporary blockchain architectures.

Conclusion
---

Fuel's UTXO-based optimistic rollup is uniquely suited as the best scaling solution for Ethereum available today. It is trust-minimized and permissionless, and provides high scalability along with a number of other desireable properties, the particular combination of which is unmatched.

See Also
---


1. [Scaling Ethereum with Rollups](https://www.youtube.com/watch?v=l4jccXoqLGM) at EthDenver 2020
1. [Fuel - A Trustless Scalable Sidechain](https://www.youtube.com/watch?v=gdPe05vZXh8) at EthCC 2020
1. [Fuel: Scaling Ethereum with Optimistic Rollups](https://www.youtube.com/watch?v=68hoClK3X8s) at NonCon 2020

---

## File: src/v1.0.0/3. Concepts/0. Fundamentals/3. Block Architecture.md

Block Architecture
===

Being a UTXO-based blockchain, Fuel is designed with a number of similarities to existing UTXO-based chains, such as Bitcoin. Consult the [Bitcoin developer reference](https://developer.bitcoin.org/reference/) for an overview of the minimal block layout required for such a chain.

|  |
| :-----------------------------------------: |
|        _Overview of block contents._        |

This page describes intuitions behind the top-level data structures, from blocks to leaves in the transaction tree. Discussion on the transaction architecture is relegated to [the next page](4.%20Transaction%20Architecture.md).

Block Header
---

In any blockchain, [block headers](../1.%20Data%20Structures/Blocks.md) commit to a list of transactions, and contain other important metadata. Blocks are block headers plus the explicit list of transactions, but do not exist as an independent data structure in Fuel.

Each block header in Fuel contains the usual suspects: an identifier for the block producer, the previous block header's hash, and the _block height_ (the index of this rollup block in the rollup chain). A few other fields, that diverge from traditional blockchains, are also present.

First, the _block number_, i.e. the Ethereum block number when this rollup block was submitted to Ethereum, is included. Note that the expressions **\[block\] height** and **\[block\] number** are used to refer to the rollup block height and the Ethereum block number, respectively.

> **Note:** Including the block number in the header (or, more specifically, requiring an Ethereum block number and Ethereum block hash to match [when committing a new rollup block](../1.%20Data%20Structures/Blocks.md)) prevents miners from re-organizing Ethereum and moving a submission transaction to an earlier block number, which could invalidate the timelock conditions of Fuel transactions.

Additionally, the maximum [token ID](../1.%20Data%20Structures/Tokens.md) and [address ID](../1.%20Data%20Structures/Addresses.md) used through the rollup block (i.e. in this and all previous rollup blocks) is included in the header. The [transaction architecture page](4.%20Transaction%20Architecture.md) will discuss these in more details, but for now it is sufficient to know that addresses (token are identified by an address as well) can be _registered_, which allows them be to referenced by a short numerical ID rather than a full 20-byte address, resulting in smaller (and thus cheaper) transactions.

> **Note:** An attacker can craft a rollup block that includes a transaction with a not-yet-registered ID (i.e. an invalid block). When they see a transaction that proves that block is invalid, they can front-run it with a transaction that registers the ID. Checking for maximum IDs as a block is submitted prevents this griefing vector.

Finally, rather than a single Merkle root of a list of transactions, a list of _root header_ hashes is included. Each root header commits to a list of transactions (in other words, the block header still commits to a list of transactions, though indirectly), and is discussed in [the next section](#root-header).

Fields that are usually seen in layer-1 Proof-of-Work chains, such as a timestamp and a nonce, are omitted. The former is implicit in the form of the Ethereum block number, and the latter is unnecessary since work is not used in the rollup.

Root Header
---

Each [root header](../1.%20Data%20Structures/Roots.md) commits to a list of transactions directly in two forms, and contains additional metadata that will be discussed shortly. Roots are root headers plus the explicit list of transactions, but do not exist as an independent data structure.

A list of transactions is committed to as both a Merkle root and a simple hash. The simple hash is checked when a new root is submitted on-chain, but not the Merkle root. This avoids the need to Merkleize transactions all the time, and saves on gas costs. If the Merkle root is incorrect, this can be proven with [a fraud proof](../3.%20Provers/Malformed%20Block.md) (which uses the simple hash to authenticate the data that will be Merkleized).

> **Note:** Separating block submission into two steps—first submitting one or more roots, then submitting the block header that includes those roots—reduces the costs of a race condition where multiple block producers submit a block at the same time and only one is valid (and the other transactions would fail and cost gas). By making block submission extremely gas-cheap, this race condition is no a longer costly mistake. There is no race condition on submitting roots.

> **Note:** The size bound on the list of transactions is chosen such that Merkleizing any individual list of transactions can be done within the gas limit of a single Ethereum block (with a large margin of safety).

Two transaction fields are [_hoisted_](https://en.wikipedia.org/wiki/Loop-invariant_code_motion) into the root header: the fee token ID and the feerate. By enforcing that all transactions under a single root pay fees in the same token at the same rate, we can avoid needing to repeat these values for every transaction, and instead only specify them once in the root header.

> **Note:** Transactions still sign over the fee token ID and feerate values, to avoid malicious root submissions. The values are [_implicitly_](./../1.%20Data%20Structures/Transactions.md) part of the transaction data that is signed. See the next section for implicit vs explicit transaction data.

Transaction Leaves
---

The [transaction architecture](4.%20Transaction%20Architecture.md) can be found in the next page. It is recommended to read it first, before returning to complete this section.

Each [transaction leaf](../1.%20Data%20Structures/Transactions.md) (i.e. leaf in the Merkle tree of transactions that are committed to in a root header) contains all the required data to reconstruct the state transition defined by the transaction unambiguously.

1. A list of witnesses, which authorize spending a state element in this transaction.
1. A list of inputs and metadata (one metadata per input). Each input provides enough information to "unlock" the state element being spent, but does not explicitly identify the state element by ID.
1. A list of outputs, which each describe the spending conditions for a new state element.

_Metadata_ is inserted by the root submitter as a means of uniquely identifying the state element being spent at each input. For regular UTXOs this would be the block height, root index, transaction index, then output index. This replaces the traditional UTXO ID (usually: a hash of the transaction and output index) with a much more compact representation.

> **Note:** Metadata is malleable by the root submitter, and is thus not signed over by the transaction sender.

---

## File: src/v1.0.0/3. Concepts/0. Fundamentals/4. Transaction Architecture.md

Transaction Architecture
===

|                 |
| :------------------------------------------------------: |
| A transaction with up to eight inputs and eight outputs. |

A [transaction](../1.%20Data%20Structures/Transactions.md) in Fuel specifies a _state transition_: inputs tell which state elements are consumed and outputs tell which state elements are produced. As with any UTXO-based system, each state element can only be produced and consumed at most once. Modeling the rollup chain's state as a key-value store, this means that keys can never be re-used, and keys commit to values in some way.

> **Note:** Up to eight inputs and outputs are allowed per transaction, to keep the worst-case cost of fraud proofs low while simultaneously enabling a number of applications that require multiple inputs or outputs.

Each [input](../1.%20Data%20Structures/Inputs.md) specifies the state element to spend, and unlocks it. For plain UTXOs and deposits, this is the UTXO/deposit ID and a valid digital signature. For HTLC UTXOs, this is the UTXO ID and a preimage (if using the hashlock spending condition) and a valid digital signature.

Each [output](../1.%20Data%20Structures/Outputs.md) specifies the new state element to produce (including amounts, token type, etc.), and its spending conditions (recipient address, timelock and hashlock).

Transactions can be validated statelessly, and the state database only needs to be checked for the _existence_ of each consumed state element. In addition, there is no inherent limitation on which accounts sign a transaction, so a transaction can represent an atomic interaction between more than one user (e.g. an on-chain atomic exchange).

The _transaction ID_ (a unique identifier for each transaction) is computed as the [EIP-712 hash](./5.%20Serialization.md) of the hash of the transaction data _without witnesses_. We will see in the next section why excluding witness data has some nice properties.

Inputs: Witnesses and Metadata
---

|  |
| :-------------------------------------------------------: |
|                Input witness and metadata.                |

Each input is linked to a [witness](../1.%20Data%20Structures/Witness.md) (generalization of a digital signature) and [metadata](../1.%20Data%20Structures/Metadata.md).

Witnesses are either a digital signature, or an authorization from a smart contract on Ethereum (e.g. a smart contract wallet can be used to authorize Fuel transactions). In either case, authorization is performed on a transaction ID (as the in previous section, the non-witness transaction data), i.e. signatures are over the transaction ID.

> **Note:** Signing over the transaction ID means that the transaction only has to be hashed once when verified, regardless of the number of inputs or outputs. This avoids the [quadratic hashing issue seen in Bitcoin](https://bitcoin.stackexchange.com/questions/54548/scriptsig-content-during-signature-quadratic-hashing).

Each input specifies a state element to consume (i.e. a UTXO ID, or a deposit ID), which is a 32-byte hash. This value is part of the non-witness transaction data, and is signed over. However, when posting transactions on Ethereum, explicit state element identifiers are stripped and replaced by more compact _metadata_, which "point" to a unique entry in the ledger (or a deposit). In other words, metadata will point to an _exact_ output in the totally ordered outputs, transactions, roots, and blocks.

> **Note:** Given the one-to-one mapping between ledger entries and state element identifiers, it is easy to show the state element produced by an exact entry with a simple inclusion proof, leveraging the property that computing state element identifiers is a stateless operation.

> **Note:** Extending the above, transaction IDs are not immediately obvious with only the data posted to Ethereum, since state element identifiers are missing. However, they can be proven, and the transaction IDs computed, with inclusion proofs for the entires pointed to by metadata.

Segregated Witnesses
---

|  |
| :----------------------------------------------------: |
|                 Segregated witnesses.                  |

Fuel is designed with a form of _segregated witness_, where witness data is not bundled with inputs. While the previous sections provided intuition, they did not precisely describe where witnesses are placed in transactions.

Each input actually specifies a _witness index_ that authorizes spending the referenced state element. This means that multiple inputs could use the same witness, which greatly reduces the cost of spending multiple state elements owned by the same account.

Simple Send Example
---

|  |
| :-----------------------------------------: |
|               A simple send.                |

As an example, the above is a simple one-input two-output simple send. One output is returned to the sender as change (there is no special change output type, so it looks like any other output). The other is sent to the recipient.

---

## File: src/v1.0.0/3. Concepts/0. Fundamentals/5. Serialization.md

# Fuel EIP-712 Specification

This document describes the Fuel EIP-712 specification, including `encodeTypes`, and `encodeData` functions.
EIP-712 improves usability of off-chain message signatures for use on-chain by specifying a standard for hashing and signing of typed (semi-)structured data (not just bytes).

## encodeTypes

### Address

`encodeData`:

* require `Output.owner.length > 0`
* require `Output.owner.length <= 20`
* `Output.owner =`
  * `if Output.owner.length == 20 then Output.owner`
  * `else Output.owner[:Output.owner.length]`

### Input

```
Input(
    uint8 type,
    uint8 witnessReference
)
```

### InputDeposit

```
InputDeposit(
    uint8 type,
    uint8 witnessReference,
    address owner
)
```

### InputHTLC

```
InputHTLC(
    uint8 type,
    uint8 witnessReference,
    bytes32 preImage
)
```

#### Metadata

```
Metadata(
    uint32 blockHeight,
    uint8 rootIndex,
    uint16 transactionIndex,
    uint8 outputIndex
)
```

### MetadataDeposit

```
MetadataDeposit(
    uint32 token,
    uint32 blockNumber
)
```

### Output

```
Output(
    uint8 type,
    uint8 tokenLength,
    bytes1[] token,
    uint8 amountShift,
    uint8 amountLength,
    uint8[] amount,
    uint8 ownerLength,
    bytes1[] owner
)
```

encodeData for `Output`:

* require `amountLength <= 32`
* require `amountShift <= 256`
* require `((amountLength * 8) + amountShift) <= 256`
* `Output.amount = Output.amount.data[:Output.amountLength] << Output.amountShift`

### OutputHTLC

```
OutputHTLC(
    uint8 type,
    uint8 tokenLength,
    bytes1[] token,
    uint8 amountShift,
    uint8 amountLength,
    uint8[] amount,
    uint8 ownerLength,
    bytes1[] owner,
    bytes32 digest,
    uint32 expiry,
    uint8 returnOwnerLength,
    bytes1[] returnOwner
)
```

### OutputReturn

```
OutputReturn(
    uint8 type,
    uint16 dataLength,
    bytes1[] data
)
```

### Storage

Base type for stored types. Computes index into storage of 1-, 2-, or 3-element items:

* mapping key for 1-element item is: `keccak256(0, 64)`
* mapping key for 2-element item is: `keccak256(0, 96)`
* mapping key for 3-element item is: `keccak256(0, 128)`

### TransactionProof

```
TransactionProof(
    address blockProducer,
    bytes32 previousBlockHash,
    uint256 blockHeight,
    uint256 blockNumber,
    uint256 numTokens,
    uint256 numAddresses,
    uint16 rootsLength,
    bytes32[] roots,
    address rootProducer,
    bytes32 merkleTreeRoot,
    bytes32 commitmentHash,
    uint256 rootLength,
    uint256 feeToken,
    uint256 fee,
    uint16 rootIndex,
    uint16 merkleProofLength,
    bytes32[] merkleProof,
    uint8 inputOutputIndex,
    uint16 transactionIndex,
    uint16 transactionLength,
    bytes1[] transaction,
    uint8 dataLength,
    bytes32[] data,
    uint256 signatureFeeToken,
    uint256 signatureFee,
    address tokenAddress,
    address selector
)
```

### TransactionLeaf

```
TransactionLeaf(
    uint16 length,
    uint8 metadataLength,
    bytes8[] metadata,
    uint16 witnessesLength,
    bytes1[] witnesses,
    uint16 inputsLength,
    bytes1[] inputs,
    uint16 outputsLength,
    bytes1[] outputs
)
```

### UTXO

```
UTXO(
    bytes32 transactionId,
    uint256 outputIndex,
    uint256 outputType,
    bytes32 owner,
    uint256 amount,
    uint256 token,
    bytes32 digest,
    uint256 expiry,
    bytes32 returnOwner
)
```

### Witness

There is no explicit `Witness` type, only its sub-types of Signature, Caller, and  Producer.

```
Signature(
    uint8 type,
    bytes32 r,
    bytes32 s,
    uint8 v
)
```

```
Caller(
    uint8 type,
    address owner,
    uint32 blockNumber
)
```

```
Producer(
    uint8 type,
    bytes32 hash
)
```

## Special notes

### `chainID`

Fuel does not mandate the use of a `chainID` field.

Applications can rely on existing secure `chainID` approaches, including EIP-155 Simple replay attack protection and EIP-1344 ChainID opcode. EIP-155 includes a `chainID` in the computation of a transaction's signature, and EIP-1344 defines a `chainID` smart contract opcode. 
 
 An important sysops note is that the use of EIP-1344 in Fuel is fully backwards compatible with all chains which implement EIP-155 chain ID domain separator for transaction signing.  
 
## References
 
Vitalik Buterin, "EIP-155: Simple replay attack protection," Ethereum Improvement Proposals, no. 155, October 2016. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-155.
 
Richard Meissner, Bryant Eisenbach, "EIP-1344: ChainID opcode," Ethereum Improvement Proposals, no. 1344, August 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1344.

---

## File: src/v1.0.0/3. Concepts/0. Fundamentals/6. System Description Primer.md

System Description Primer
===

System Components
---

This page lists the different system components that are documented in the remainder of the `Concepts` section.

Data Structures
---

The core data structures are:
1. [Addresses](../1.%20Data%20Structures/Addresses.md): a registry for user account addresses.
1. [Blocks and block headers](../1.%20Data%20Structures/Blocks.md): top-level data structure.
1. [Deposits](../1.%20Data%20Structures/Deposits.md): deposits to Fuel from Ethereum.
1. [Inputs](../1.%20Data%20Structures/Inputs.md): transaction inputs.
1. [Metadata](../1.%20Data%20Structures/Metadata.md): point to state elements to consume.
1. [Outputs](../1.%20Data%20Structures/Outputs.md): transaction outputs.
1. [Roots and root headers](../1.%20Data%20Structures/Roots.md): commit to a batch of transactions.
1. [Tokens](../1.%20Data%20Structures/Tokens.md): a registry for token addresses.
1. [Transactions](../1.%20Data%20Structures/Transactions.md): transactions.
1. [Withdrawals](../1.%20Data%20Structures/Withdrawals.md): withdrawals from Fuel to Ethereum.
1. [Witnesses](./../1.%20Data%20Structures/Witness.md): authorize transactions.

Verifiers
---

If a fraud proof is submitted to the contract, it first needs to be validated for correct formatting. This is required to ensure that a maliciously-constructed fraud proof can never be processed, otherwise a valid block could be reverted. Parsing fraud proofs is handled by [verifiers](../2.%20Verifiers/Block%20Header.md).

Provers
---

Once a fraud proof has successfully been parsed by the appropriate verifier modules, it must be processed to prove that fraud occurred (or that the fraud proof is properly formatted but otherwise incorrect). This is handled by [provers](./../3.%20Provers/Double%20Spend.md).

Additional Modules
---

Outside the core components above, additional optional modules are provided to e.g. improve UX and add more functionality:
1. [Token funnels](../4.%20Additional%20Modules/Funnels.md): ephemeral contracts that accept token deposits without an `approve` step.

---

## File: src/v1.0.0/3. Concepts/0. Fundamentals/7. Deployment Parameters.md

Deployment Parameters
===

Constructor Parameters
---

Here we will describe the Fuel contract's constructor parameters.

| field name            | description                                                                                                                                                                                                                      |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **operator**          | `address`; The primary operator of the Fuel rollup. This account receives priority access on including roots in blocks production, however, anyone else may use roots with a delay specified by the `submissionDelay` parameter. |
| **finalizationDelay** | `uint256`; The time to finalization in Ethereum blocks.                                                                                                                                                                          |
| **submissionDelay**   | `uint256`; The number of Ethereum blocks a non-operator must wait before using a root in a block.                                                                                                                                |
| **penaltyDelay**      | `uint256`; The delay which the operator will face if they commit Fraud, until the time they may come back online as the primary operator.                                                                                        |
| **bondSize**          | `uint256`; The bond size required for block production, in wei.                                                                                                                                                                  |
| **name**              | `string`; The name string used for contract identification and EIP-712 hashing.                                                                                                                                                  |
| **version**           | `string`; The version of the contract used for identification and EIP-712 hashing.                                                                                                                                               |
| **chainId**           | `uint256`; The Ethereum network chain identifier used for identification, replay attack protection, and EIP-712 hashing.                                                                                                         |
| **genesis**           | `bytes32`; The registered genesis block hash. This property is simply for vanity and can be set to any value as the minimum referenced block is always > 0.                                                                      |

### Deploying in Operated Mode
If you would like to deploy a Fuel chain in operated mode, use non-zero values for `operator` and `submissionDelay`.

### Deploying in Un-operated Mode
If you would like to deploy Fuel in un-operated mode, where anyone may submit blocks at any time, use zero values for `operator` and `submissionDelay`.

### Finalization Delays
In any optimistic rollup, finalization delay is a critical security parameter. A longer value provides more robustness against miner censorship attacks, but will result in longer withdrawals.

We recommend 1 week at the minimum, or 2 weeks on the higher end, to protect against both chain congestion attacks and censorship attacks.

Rinkeby Testnet
---

Contract address: [0x669c63dDD6050838faf496F46EEb7378bff05d77](https://rinkeby.etherscan.io/address/0x669c63dDD6050838faf496F46EEb7378bff05d77)

Name: `rinkeby`

| field name            | value                                                                             |
| --------------------- | --------------------------------------------------------------------------------- |
| **operator**          | `0x0ea6b5edc8905c85514b3676703f1bfe6ec260ad`                                      |
| **finalizationDelay** | `93046` (one week)                                                                |
| **submissionDelay**   | `6646` (one day)                                                                  |
| **penaltyDelay**      | `0` (zero)                                                                        |
| **bondSize**          | `100000000000000000` (0.1 ETH)                                                    |
| **name**              | `Fuel`                                                                            |
| **version**           | `1.0.0`                                                                           |
| **chainId**           | `4`                                                                               |
| **genesis**           | `0x0000000000000000000000000000000000000000000000000000000000000000` (empty hash) |

---

## File: src/v1.0.0/3. Concepts/1. Data Structures/Addresses.md

Addresses
===

The address registry maintains a mapping of address (20 bytes) to address ID (unsigned integer up to and including 19 bytes). Each time a new address is registered, it is assigned the next address ID in sequence.

Note that registering an address is not necessary to send or receive funds on Fuel. It is a purely optional way of reducing transaction sizes (and thus costs).

---

## File: src/v1.0.0/3. Concepts/1. Data Structures/Blocks.md

Blocks
===

BlockHeader
---

| name                | type        | size | description                                         |
| ------------------- | ----------- | ---- | --------------------------------------------------- |
| `producer`          | `address`   | 20   | Address of block proposer committing this block.    |
| `previousBlockHash` | `bytes32`   | 32   | Previous block's header hash.                       |
| `height`            | `uint256`   | 32   | Block height.                                       |
| `blockNumber`       | `uint256`   | 32   | Ethereum block number when this block is committed. |
| `numTokens`         | `uint256`   | 32   | Maximum token ID used through this block.           |
| `numAddresses`      | `uint256`   | 32   | Maximum address ID used through this block          |
| `roots.length`      | `uint16`    | 2    | Number of transaction roots.                        |
| `roots`             | `bytes32[]` | 32*  | List of root header hashes.                         |

### Number of Tokens

Tokens IDs are registered contract-side to allow for more compact transactions. The maximum token ID used in this block and all previous blocks is included in the block header.

This is needed to prevent a griefing attack where a fraudulent rollup block is committed that spends a token ID that is not yet registered. The fraud proof can then be front-run with a transaction that registers the token ID, thereby invalidating the fraud proof.

See: [token registry](./Tokens.md).

### Number of Addresses

Address IDs are registered contract-side to allow for more compact transactions. The maximum address ID used in this block and all previous blocks is included in the block header.

This is needed to prevent a griefing attack where a fraudulent rollup block is committed that sends to an address ID that is not yet registered. The fraud proof can then be front-run with a transaction that registers the address ID, thereby invalidating the fraud proof.

See: [address registry](./Addresses.md).

### Roots

The block header includes a list of root header hashes, `roots`. Each individual root header hash is the hash of a [root header](./Roots.md), which commits to a list of transactions and other important metadata. For more information of why multiple roots are used instead of the more traditional single-transactions-root, see [Block Architecture](../0.%20Fundamentals/3.%20Block%20Architecture.md).

The number of root header hashes is upper-bounded by the `TRANSACTION_ROOTS_MAX` parameter (`128`).

Committing a New Block Header
---

When a new block header is produced and committed to Ethereum, the following checks **must** pass, and are enforced by the smart contract.

1. The height `blockHeight` must be greater than `0` and at most the tip height.
1. The previous block hash `previousBlockHash` must match the previous block hash at `blockHeight`.
1. The number of transaction roots `roots.length` must be greater than `0` and at most `TRANSACTION_ROOTS_MAX`.
1. Every root in `roots` must exist in the root registry.
1. If the operator is _not_ in _penalty mode_ (discussed below):
    1. If the block producer `producer` is not the operator:
        1. At least the [submission delay parameter](../0.%20Fundamentals/7.%20Deployment%20Parameters.md) Ethereum blocks must have elapsed since the root was submitted.

The penalty mode becomes active if a successful fraud proof against an operator-produced block is processed. It remains active for the [penalty delay parameter](./../0.%20Fundamentals/7.%20Deployment%20Parameters.md) Ethereum blocks.

---

## File: src/v1.0.0/3. Concepts/1. Data Structures/Deposits.md

Deposits
===

The deposit registry uniquely indexes deposits so they can be spent on Fuel.

Deposit
---

| name          | type      | size | description                             |
| ------------- | --------- | ---- | --------------------------------------- |
| `owner`       | `address` | 20   | Owner of deposit.                       |
| `token`       | `uint256` | 32   | 4-byte [Token ID](./Tokens.md).         |
| `blockNumber` | `uint256` | 32   | Ethereum block number deposit was made. |
| `value`       | `uint256` | 32   | Amount of tokens.                       |

Deposits are uniquely keyed by `{ owner, token, blockNumber }`, with value `value`.

Since the granularity of deposits is in Ethereum blocks, multiple deposits from the same owner of the same token in the same Ethereum block simply update the deposited amount.

Deposits can be spent no earlier than in a Fuel block committed in the next Ethereum block.

---

## File: src/v1.0.0/3. Concepts/1. Data Structures/Inputs.md

Inputs
===

Inputs indicate which state elements (usually: UTXOs) are consumed by a [transaction](./Transactions.md). Each state element can be consumed and produced at most once.

InputType
---

```
enum InputType : uint8 {
    Transfer = 0,
    Deposit = 1,
    HTLC = 2,
    Root = 3,
}
```

Input
---

| name           | type        | size | description                                                  |
| -------------- | ----------- | ---- | ------------------------------------------------------------ |
| `type`         | `InputType` | 1    | `InputType.Transfer` or `InputType.Root`.                    |
| `witnessIndex` | `uint8`     | 1    | Index of witness that authorizes spending the state element. |

There are no spending conditions on plain transfer UTXOs and root UTXOs (collected fees) other than a valid signature from the owner of the UTXO.

InputDeposit
---

| name           | type        | size | description                                            |
| -------------- | ----------- | ---- | ------------------------------------------------------ |
| `type`         | `InputType` | 1    | `InputType.Deposit`.                                   |
| `witnessIndex` | `uint8`     | 1    | Index of witness that authorizes spending the deposit. |
| `owner`        | `address`   | 20   | Deposit owner address.                                 |

There are no spending conditions on deposits other than a valid signature from the owner of the UTXO. The owner of the deposit must be provided as it is needed to compute the unique [deposit ID](./Deposits.md).

InputHTLC
---

| name           | type        | size | description                                                  |
| -------------- | ----------- | ---- | ------------------------------------------------------------ |
| `type`         | `InputType` | 1    | `InputType.HTLC`.                                            |
| `witnessIndex` | `uint8`     | 1    | Index of witness that authorizes spending the state element. |
| `preImage`     | `bytes32`   | 32   | Preimage of digest if spending through hashlock.             |

HTLC UTXOs require a valid signature from the owner of the UTXO. In addition, if using the hashlock condition, the preimage must be provided. If using the timelock condition, HTLC UTXOs are only spendable after the [output](./Outputs.md)'s timelock has expired.

---

## File: src/v1.0.0/3. Concepts/1. Data Structures/Metadata.md

Metadata
===

Each [transaction](./Transactions.md) can have metadata attached to it by the block producer. One metadata is attached per [input](./Inputs.md). This allows for fraud proofs without state commitments. (See also: [Compact Fraud Proofs for UTXO Chains Without Intermediate State Serialization](https://ethresear.ch/t/compact-fraud-proofs-for-utxo-chains-without-intermediate-state-serialization/5885).)

Note that all metadata objects are exactly `8` bytes.

Metadata
---

| name               | type     | size | description                  |
| ------------------ | -------- | ---- | ---------------------------- |
| `blockHeight`      | `uint32` | 4    | Rollup block height.         |
| `rootIndex`        | `uint8`  | 1    | Root index in block.         |
| `transactionIndex` | `uint16` | 2    | Transaction index in root.   |
| `outputIndex`      | `uint8`  | 1    | Output index in transaction. |

Metadata uniquely identifies an exact [output](./Outputs.md) in the ledger, first by the [block height](./Blocks.md), then the [root](./Roots.md), [transaction index](./Roots.md), and finally [output index](./Transactions.md). Essentially, metadata "references" an exact output. This allows for both compact fraud proofs without serializing the state, leveraging the property that UTXOs are produced and consumed at most once, and smaller transaction payloads than using [UTXO IDs](./Outputs.md) directly (a 32-byte hash).

MetadataDeposit
---

| name          | type     | size | description            |
| ------------- | -------- | ---- | ---------------------- |
| `token`       | `uint32` | 4    | Token ID.              |
| `blockNumber` | `uint32` | 4    | Ethereum block number. |

Deposit metadata partially uniquely identifies a [deposit](Deposits.md). The last part of the deposit registry key is the owner address, which can be recovered from the witness (of valid transactions).

---

## File: src/v1.0.0/3. Concepts/1. Data Structures/Outputs.md

Outputs
===

Outputs define which state elements (usually: UTXOs) are produced by a [transaction](./Transactions.md). Each state element can be produced and consumed at most once.

OutputType
---

```
enum OutputType : uint8 {
    Transfer = 0,
    Withdraw = 1,
    HTLC = 2,
    Return = 3,
}
```

Output
---

| name            | type         | size | description                                                                                                        |
| --------------- | ------------ | ---- | ------------------------------------------------------------------------------------------------------------------ |
| `type`          | `OutputType` | 1    | `OutputType.Transfer` or `OutputType.Withdraw`.                                                                    |
| `token.length`  | `uint8`      | 1    | Next field number of bytes.                                                                                        |
| `token`         | `bytes1[]`   | 1*   | The token ID (`<= 4` bytes). See: [token registry](./Tokens.md).                                                   |
| `amount.shift`  | `uint8`      | 1    | Amount shifted bytes. See: [serialization](../0.%20Fundamentals/5.%20Serialization.md).                            |
| `amount.length` | `uint8`      | 1    | Next field number of bytes.                                                                                        |
| `amount`        | `uint8[]`    | 1*   | Amount of tokens. See: [serialization](../0.%20Fundamentals/5.%20Serialization.md).                                |
| `owner.length`  | `uint8`      | 1    | Next field number of bytes.                                                                                        |
| `owner`         | `bytes1[]`   | 1*   | Either address ID (`<= 19` bytes) or address (`= 20` bytes) of recipient. See: [address registry](./Addresses.md). |

A simple transfer between two users on Fuel or a withdrawal from Fuel back to Ethereum.

OutputHTLC
---

| name                 | type         | size | description                                                                                                                    |
| -------------------- | ------------ | ---- | ------------------------------------------------------------------------------------------------------------------------------ |
| `type`               | `OutputType` | 1    | `OutputType.HTLC`.                                                                                                             |
| `token.length`       | `uint8`      | 1    | Next field number of bytes.                                                                                                    |
| `token`              | `bytes1[]`   | 1*   | The token ID (`<= 4` bytes). See: [token registry](./Tokens.md).                                                               |
| `amount.shift`       | `uint8`      | 1    | Amount shifted bytes. See: [serialization](../0.%20Fundamentals/5.%20Serialization.md).                                        |
| `amount.length`      | `uint8`      | 1    | Next field number of bytes.                                                                                                    |
| `amount`             | `uint8[]`    | 1*   | Amount of tokens. See: [serialization](../0.%20Fundamentals/5.%20Serialization.md).                                            |
| `owner.length`       | `uint8`      | 1    | Next field number of bytes.                                                                                                    |
| `owner`              | `bytes1[]`   | 1*   | Either address ID (`<= 19` bytes) or address (`= 20` bytes) of recipient. See: [address registry](./Addresses.md).             |
| `digest`             | `bytes32`    | 32   | Hashlock digest. The preimage to this digest must be revealed to spend this output.                                            |
| `expiry`             | `uint32`     | 4    | Timelock as an Ethereum block number.                                                                                          |
| `returnOwner.length` | `uint8`      | 1    | Next field number of bytes.                                                                                                    |
| `returnOwner`        | `bytes1[]`   | 1*   | Either address ID (`<= 19` bytes) or address (`= 20` bytes) of owner if HTLC expires. See: [address registry](./Addresses.md). |

The timelock expiry is an _absolute_ Ethereum block number. Any rollup block committed _at or after_ this Ethereum block number can spend the UTXO with the timelock condition.

See also: [HTLC explainer on Bitcoin Wiki](https://en.bitcoin.it/wiki/Hash_Time_Locked_Contracts).

OutputReturn
---

| name          | type         | size | description                                        |
| ------------- | ------------ | ---- | -------------------------------------------------- |
| `type`        | `OutputType` | 1    | `OutputType.Return`.                               |
| `data.length` | `uint16`     | 2    | Next field number of bytes.                        |
| `data`        | `bytes1[]`   | 1*   | Data blob. Between `1` and `512` bytes, inclusive. |

Return outputs are provably prunable, i.e. they are not inserted into the state (the UTXO set). They can be used to record and timestamp arbitrary information to the Fuel chain, useful for building applications with client-side execution.

See also: [Bitcoin's OP_RETURN](https://en.bitcoin.it/wiki/OP_RETURN).

UTXO
---

| name            | type      | size | description                                                                                |
| --------------- | --------- | ---- | ------------------------------------------------------------------------------------------ |
| `transactionId` | `bytes32` | 32   | [Transaction ID](./Transactions.md), the hash of the serialized unsigned transaction data. |
| `outputIndex`   | `uint256` | 32   | Index of output in transaction.                                                            |
| `outputType`    | `uint256` | 32   | Output's type.                                                                             |
| `owner`         | `bytes32` | 32   | Owner of UTXO, either a raw address or an [address ID](./Addresses.md).                    |
| `amount`        | `uint256` | 32   | Amount of tokens.                                                                          |
| `token`         | `uint256` | 32   | [Token ID](./Tokens.md).                                                                   |
| `digest`        | `bytes32` | 32   | HTLC only: hashlock.                                                                       |
| `expiry`        | `uint256` | 32   | HTLC only: timelock.                                                                       |
| `returnOwner`   | `bytes32` | 32   | HTLC only: return owner.                                                                   |

The UTXO ID is simply the hash of the UTXO.

The HTLC-only fields are set to zero (`0`) if the output is not an HTLC output.

---

## File: src/v1.0.0/3. Concepts/1. Data Structures/Roots.md

Roots
===

RootHeader
---

| name             | type      | size | description                                                       |
| ---------------- | --------- | ---- | ----------------------------------------------------------------- |
| `rootProducer`   | `address` | 20   | Address of root producer.                                         |
| `merkleTreeRoot` | `bytes32` | 32   | Claimed Merkle root of list of [transactions](./Transactions.md). |
| `commitmentHash` | `bytes32` | 32   | Simple hash of list of [transactions](./Transactions.md).         |
| `rootLength`     | `uint256` | 32   | Number of roots.                                                  |
| `feeToken`       | `uint256` | 32   | [Token ID](./Tokens.md) of all fees paid in this root.            |
| `fee`            | `uint256` | 32   | Feerate of all fees paid in this root.                            |

Each _root header_ commits to a list of transactions. Each _root_ is a root header and a list of transactions (and does not exist as a canonical data structure).  [Blocks](./Blocks.md) contain one or more root header hashes (i.e. hashes of root headers), and so implicitly commit to a list of transactions. For more information of why multiple roots are used instead of the more traditional single-transactions-root, see [Block Architecture](../0.%20Fundamentals/3.%20Block%20Architecture.md).

When committing a new root to the contract, the root header minus the `commitmentHash` is provided, along with a list of transactions. The `commitmentHash` is then computed by simply hashing the list of transactions. This means that root headers _claim_ a Merkle root of their transactions, which is assumed to be correct optimistically to save gas. If the claimed Merkle root is incorrect, [a fraud proof](../3.%20Provers/Malformed%20Block.md) can be constructed to show this.

The maximum size in bytes of the list of transactions in a single root is the `MAX_ROOT_SIZE` parameter (`57600`). This limit is placed to ensure that the transactions can always be Merkleized within the gas limit of a single Ethereum block in a fraud proof.

The maximum number of transactions in a single root is the `MAX_TRANSACTIONS_IN_ROOT` parameter (`2048`).

---

## File: src/v1.0.0/3. Concepts/1. Data Structures/Tokens.md

Tokens
===

The token registry maintains a mapping of token contract address (20 bytes) to token ID (unsigned integer up to and including 4 bytes). Each time a new token is registered, it is assigned the next token ID in sequence.

New tokens deposited to the contract are automatically assigned a new token ID without any additional interaction.

Native ether (ETH) has token ID `0`.

---

## File: src/v1.0.0/3. Concepts/1. Data Structures/Transactions.md

Transactions
===

Transactions consume [inputs](./Inputs.md) and produce [outputs](./Outputs.md).

UnsignedTransaction
---

| name                | type        | size | description                                  |
| ------------------- | ----------- | ---- | -------------------------------------------- |
| `inputs.length`     | `uint16`    | 2    | Next field number of bytes.                  |
| `inputs`            | `bytes1[]`  | 1*   | List of [inputs](./Inputs.md).               |
| `outputs.length`    | `uint16`    | 2    | Next field number of bytes.                  |
| `outputs`           | `bytes1[]`  | 1*   | List of [outputs](./Outputs.md).             |
| `data.length`       | `uint8`     | 1    | Next field number of elements.               |
| `data`              | `bytes32[]` | 32*  | Implicit unique identifier of what to spend. |
| `signatureFeeToken` | `uint256`   | 32   | Implicit [fee token ID](./Roots.md).         |
| `signatureFee`      | `uint256`   | 32   | Implicit [fee rate](./Roots.md).             |

Transaction data that is signed off-chain. The unsigned transaction data is [serialized](../0.%20Fundamentals/5.%20Serialization.md) then hashed to get a unique transaction ID, which is then signed over to get a [witness](./Witness.md). Essentially, each witness authorizes an _entire_ transaction. This scheme avoids the [quadratic hashing issue present in Bitcoin](https://bitcointalk.org/index.php?topic=102487.0).

Implicit data (`data`) is one 32-byte hash _per input_, and uniquely identifies what is being spent by that input (a [UTXO ID](./Outputs.md) or a [deposit ID](./Deposits.md)).

The transaction ID is the [EIP-712 hash](../0.%20Fundamentals/5.%20Serialization.md) of the hash of the [serialized](../0.%20Fundamentals/5.%20Serialization.md) unsigned transaction data.

TransactionLeaf
---

| name               | type       | size | description                        |
| ------------------ | ---------- | ---- | ---------------------------------- |
| `length`           | `uint16`   | 2    | Total length of leaf in bytes.     |
| `metadata.length`  | `uint8`    | 1    | Next field number of elements.     |
| `metadata`         | `bytes8[]` | 8*   | List of metadata, one per input.   |
| `witnesses.length` | `uint16`   | 2    | Next field number of bytes.        |
| `witnesses`        | `bytes1[]` | 1*   | List of [witnesses](./Witness.md). |
| `inputs.length`    | `uint16`   | 2    | Next field number of bytes.        |
| `inputs`           | `bytes1[]` | 1*   | List of [inputs](./Inputs.md).     |
| `outputs.length`   | `uint16`   | 2    | Next field number of bytes.        |
| `outputs`          | `bytes1[]` | 1*   | List of [outputs](./Outputs.md).   |

A leaf in a transaction [Merkle tree](./../2.%20Verifiers/Merkle%20Proof.md), which is committed to in a [root](./Roots.md).

Note that the implicit data is not included in the leaf, as it can be reconstructed from metadata. Rather, the root producer replaces the larger data (state element) with the smaller metadata (a pointer to an entry in the ledger or a deposit).

Note that the implicit fee token ID and feerate are not included in the leaf. Since the value of those fields must be identical for all transaction under a root, they can be hoisted and declared once [at the root header level](./Roots.md).

The minimum transaction leaf size in bytes is set by the parameter `TRANSACTION_SIZE_MIN` (`44`).
The maximum transaction leaf size in bytes is set by the parameter `TRANSACTION_SIZE_MAX` (`896`).
The maximum number of inputs in a single transaction is `INPUTS_MAX` (`8`).
The maximum number of outputs in a single transaction is `OUTPUTS_MAX` (`8`).

---

## File: src/v1.0.0/3. Concepts/1. Data Structures/Withdrawals.md

Withdrawals
===

Withdrawal Metadata
---

| name                  | padded type | compact type | size | description                                                                |
| --------------------- | ----------- | ------------ | ---- | -------------------------------------------------------------------------- |
| `rootIndex`           | `uint256`   | `uint32`     | 4    | Index of root in list of roots.                                            |
| `transactionLeafHash` | `bytes32`   | `bytes32`    | 32   | Hash of transaction leaf in tree rooted at `rootIndex`.                    |
| `outputIndex`         | `bytes32`   | `uint8`      | 1    | Index of output in list of outputs of transaction in the transaction leaf. |

Withdrawal metadata is represented in padded form on Ethereum to simplify processing, and compact form on Fuel. The ID of a withdrawal is the hash of the padded-form withdrawal metadata.

A withdrawal registry keep track of whether a withdrawal has been processed or not (a Boolean value), indexed by the rollup block height and unique withdrawal ID. "Processed" withdrawals are completed withdrawals (i.e. the tokens have been withdrawn from the contract).

---

## File: src/v1.0.0/3. Concepts/1. Data Structures/Witness.md

Witness
===

WitnessType
---

```
enum WitnessType : uint8 {
    Signature = 0,
    Caller = 1,
    Producer = 2,
}
```

Witnesses come in different types, depending on the origin of the authorization.

Signature
---

| name   | type          | size | description          |
| ------ | ------------- | ---- | -------------------- |
| `type` | `WitnessType` | 1    | Witness type.        |
| `r`    | `bytes32`     | 32   | Signature `r` value. |
| `s`    | `bytes32`     | 32   | Signature `s` value. |
| `v`    | `uint8`       | 1    | Signature `v` value. |

This is a normal signature that signs over the [transaction ID](./Transactions.md) to authorize.

See: [EIP-155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md).

Caller
---

| name          | type          | size | description                                      |
| ------------- | ------------- | ---- | ------------------------------------------------ |
| `type`        | `WitnessType` | 1    | Witness type.                                    |
| `owner`       | `address`     | 20   | Caller address.                                  |
| `blockNumber` | `uint32`      | 4    | Ethereum block number witness was registered at. |

This witness type is for when a contract on Ethereum authorizes a Fuel transaction. One use is smart contract wallets, rather than externally-owned accounts, authorizing transactions.

Caller witnesses in the witness registry are indexed by owner and block number.

Producer
---

| name   | type          | size | description                     |
| ------ | ------------- | ---- | ------------------------------- |
| `type` | `WitnessType` | 1    | Witness type.                   |
| `hash` | `bytes32`     | 32   | Transaction ID being witnessed. |

Block producers can spend fee outputs (i.e. [Root outputs](./Roots.md)) in blocks they produce without an explicit signature.

---

## File: src/v1.0.0/3. Concepts/2. Verifiers/Block Header.md

Verifier: Block Headers
===

Validates the [block header](../1.%20Data%20Structures/Blocks.md) component of a [transaction proof](./Transaction%20Proof.md) is properly formatted.

1. The hash of the block header must be the block hash at `proof.blockHeader.blockHeight`.
1. If checking for finalizable block, then:
    1. The current block number must be at least the block number `proof.blockHeader.blockNumber`.
1. If checking for not-finalizable block, then:
    1. The current block number must be less than the block number `proof.blockHeader.blockNumber`.

Additional checks must pass if the [root header](./../1.%20Data%20Structures/Roots.md) component of a transaction proof is also being validated at the same time.

1. The root index `proof.rootIndex` must be less than the number of roots `proof.blockHeader.roots.length`.
1. The hash of the root header `proof.rootHeader` must match the root header at index `proof.rootIndex`.

---

## File: src/v1.0.0/3. Concepts/2. Verifiers/Data.md

Verifier: Data
===

Validates the [data](./../1.%20Data%20Structures/Transactions.md) component of a [transaction proof](./Transaction%20Proof.md) is properly formatted.

The data field in an [unsigned transaction](./../1.%20Data%20Structures/Transactions.md) is a list of the unique state elements that are being consumed by the inputs. Since the key for these state elements (a hash) commits to sufficient information to verify their values, we simply need to provide the preimage to each hash.

For each provided state element `stateElement` and each data `data` in the list of proof data `proof.data`:
1. The hash of `stateElement` must match `data`.

Note that `stateElement` can come in [different types](./Inputs.md), depending on the type of the input (i.e. what is being spent).

---

## File: src/v1.0.0/3. Concepts/2. Verifiers/Inputs.md

Verifier: Inputs
===

Validates the [inputs](../2.%20Verifiers/Inputs.md) component of a [transaction proof](./Transaction%20Proof.md) is properly formatted.

One additional proof per input in the primary transaction proof `proof` must be provided, the list `inputProofs`.

For each input in `proof.transaction.inputs` and `inputProof` in `inputProofs`, indexed by `index`:
1. If input's [type](../1.%20Data%20Structures/Inputs.md) is `Transfer` or `HTLC`:
   1. The transaction proof `inputProof` must be [validated](./Transaction%20Proof.md).
   1. The output metadata of `inputProof` must match the metadata of input (i.e. they must be pointing to the same entry in the ledger).
   1. The UTXO ID being produced by the output of `inputProof` must match `proof.data[index]`.
1. If input's [type](../1.%20Data%20Structures/Inputs.md) is `Deposit`:
   1. The deposit object `inputProof` must be validated:
       1. The [deposit ID](./../1.%20Data%20Structures/Deposits.md) of `inputProof` must match `proof.data[index]`.
1. If input's [type](../1.%20Data%20Structures/Inputs.md) is `Root`:
   1. The transaction proof `inputProof` must be [validated](./Transaction%20Proof.md).
   1. The UTXO ID being produced by the output of `inputProof` must match `proof.data[index]`.

---

## File: src/v1.0.0/3. Concepts/2. Verifiers/Merkle Proof.md

Verifier: Merkle Proofs
===

[Verifies the Merkle proof](https://crypto.stackexchange.com/questions/31871/what-is-the-canonical-way-of-creating-merkle-tree-branches) component of a [transaction proof](./Transaction%20Proof.md).

1. The tree height `proof.merkleProof.length` must be less than `MERKLE_TREE_HEIGHT_MAX` (`256`).
1. Hash transaction leaf `proof.transaction` to get current hash as the leaf hash.
1. For height `i` between `0` and ``proof.merkleProof.length - 1`:
    1. Hash the current hash with its sibling from the Merkle proof. If the `i`th bit of `proof.transactionIndex` is `0`, the sibling is on the right. If it's `1`, the sibling is on the left.
1. The resultant Merkle root must match `proof.rootHeader.merkleTreeRoot`.

Note: when constructing the tree, the number of nodes at a given level may not be even. In such case, the default value `EMPTY_LEAF_HASH` (`0x0000000000000000000000000000000000000000000000000000000000000000`) is used as the sibling hash value.

---

## File: src/v1.0.0/3. Concepts/2. Verifiers/Transaction Proof.md

Verifier: Transaction Proofs
===

Validates a transaction proof is properly formatted.

1. The header of the transaction proof [must be valid](./Block%20Header.md).
1. The Merkle proof of the transaction proof [must be valid](./Merkle%20Proof.md).
1. The length of the transaction leaf `transaction.length` must be greater than `0`.

TransactionProof
---

| name                 | type                                                           | size     | description                                                              |
| -------------------- | -------------------------------------------------------------- | -------- | ------------------------------------------------------------------------ |
| `blockHeader`        | [BlockHeader](../1.%20Data%20Structures/Blocks.md)             | variable | Block header substructure.                                               |
| `rootHeader`         | [RootHeader](../1.%20Data%20Structures/Roots.md)               | variable | Root header substructure.                                                |
| `rootIndex`          | `uint16`                                                       | 2        | Root index.                                                              |
| `merkleProof.length` | `uint16`                                                       | 2        | Number of nodes in Merkle proof.                                         |
| `merkleProof`        | `bytes32[]`                                                    | 32*      | [Merkle inclusion proof](./Merkle%20Proof.md).                           |
| `inputIndex`         | `uint8`                                                        | 1        | Input index.                                                             |
| `outputIndex`        | `uint8`                                                        | 1        | Output index.                                                            |
| `transactionIndex`   | `uint16`                                                       | 2        | Transaction index.                                                       |
| `transaction`        | [TransactionLeaf](./../1.%20Data%20Structures/Transactions.md) | variable | Transaction leaf substructure.                                           |
| `data.length`        | `uint8`                                                        | 1        | Next field number of elements.                                           |
| `data`               | `bytes32[]`                                                    | 32*      | List of state elements being spent.                                      |
| `signatureFeeToken`  | `uint256`                                                      | 32       | Implicit [fee token ID](../1.%20Data%20Structures/Roots.md).             |
| `signatureFee`       | `uint256`                                                      | 32       | Implicit [fee rate](./../1.%20Data%20Structures/Roots.md).               |
| `token`              | `address`                                                      | 20       | Token address, used for [invalid sum](../3.%20Provers/Invalid%20Sum.md). |
| `returnOwner`        | `address`                                                      | 20       | For HTLC outputs only, the return owner.                                 |

---

## File: src/v1.0.0/3. Concepts/2. Verifiers/Witness.md

Verifier: Witnesses
===

Validates the [witness](../1.%20Data%20Structures/Witness.md) component of a [transaction proof](./Transaction%20Proof.md) is properly formatted.

This is needed to ensure that the preimage to the transaction ID provided in the transaction proof `proof` (i.e. the [unsigned transaction](./../1.%20Data%20Structures/Transactions.md)) is actually valid. [Data](./../1.%20Data%20Structures/Transactions.md) is elided when being posting transactions to Ethereum, so the integrity of the data provided in the proof must be checked.

For the provided state element `stateElement`, `witness = proof.transaction.witnesses[0]`, and `input = proof.transaction.inputs[0]`:
1. If `witness`'s type is `Signature`:
    1. Recover the address with signature `witness` and the transaction ID of computed from `proof.transaction` and `proof.data[0]` as message.
    1. If `input`'s [type](../1.%20Data%20Structures/Inputs.md) is `Transfer` or `HTLC`:
        1. The recovered address must match `stateElement.owner`.
    1. If `input`'s [type](../1.%20Data%20Structures/Inputs.md) is `Deposit`:
        1. The recovered address must match `stateElement.owner`.
    1. If `input`'s [type](../1.%20Data%20Structures/Inputs.md) is `Root`:
        1. The recovered address must match `proof.blockProducer`.
1. If `witness`'s type is `Caller`:
    1. The [witness registered](../1.%20Data%20Structures/Witness.md) indexed by `stateElement.owner` and `stateElement.blockNumber` must match the transaction ID of computed from `proof.transaction` and `proof.data[0]`
1. If `witness`'s type is `Producer`:
    1. The `stateElement.hash` must match the transaction ID of computed from `proof.transaction` and `proof.data[0]`.

Note that `stateElement` can come in [different types](./Inputs.md), depending on the type of the input (i.e. what is being spent).

---

## File: src/v1.0.0/3. Concepts/3. Provers/Double Spend.md

Prover: Double Spends
===

Proves that a double spend occurred.

Two valid [transaction proofs](../2.%20Verifiers/Transaction%20Proof.md) must be provided.
1. The input metadata for each transaction proof must be different.
1. The referenced input metadata (i.e. the spent state element) for each transaction proof must match.

---

## File: src/v1.0.0/3. Concepts/3. Provers/Invalid Input.md

Prover: Invalid Inputs
===

Proves that an [input](./../1.%20Data%20Structures/Inputs.md) was invalid, i.e. a non-existent state element was spent.

A valid [transaction proof](../2.%20Verifiers/Transaction%20Proof.md), `proof`, must be provided. In addition, a valid [transaction proof block header](././../2.%20Verifiers/Block%20Header.md) for the output being spent, `inputProof` must be provided. Since this output might not exist, the transaction proof does not need to be valid, only the block header.
1. Get input `input` as `proof.transaction.inputs(proof.inputIndex)`.
1. If the input's [type](../1.%20Data%20Structures/Inputs.md) is `Deposit`:
    1. The deposit with that [deposit ID](./../1.%20Data%20Structures/Deposits.md) must have amount of `0` (i.e. a non-deposit is being spent).
1. Get metadata `metadata` as `proof.transaction.metadata[proof.inputIndex]`.
1. The metadata's root index `metadata.rootIndex` must be at least `inputProof.rootHeader.rootLength` (i.e. metadata root index out of bounds).
1. If the input's [type](../1.%20Data%20Structures/Inputs.md) is `Transfer` or `HTLC`:
    1. If the input proof is for the rightmost leaf in the root's transaction tree, then the metadata's transaction index `metadata.transactionIndex` must be greater than `inputProof.transactionIndex`. It's impossible to provide an inclusion proof for an out-of-bounds transaction, so this check serves as a check for this condition.
    1. The transaction leaf must be non-empty, i.e. `inputProof.transaction.length` must be greater than `0`.
    1. The metadata's output index `metadata.outputIndex` must be at least `inputProof.transaction.outputs.length()` (i.e. metadata output index out of bounds).
    1. The output's [type](./../1.%20Data%20Structures/Outputs.md) must be `Withdraw` or `Return` (i.e. spending a [non-spendable output](../1.%20Data%20Structures/Outputs.md)).
    1. If the input's [type](../1.%20Data%20Structures/Inputs.md) is `Transfer`:
        1. The output's type must not be `Transfer` (i.e. type mismatch).
    1. If the input's [type](../1.%20Data%20Structures/Inputs.md) is `HTLC`:
        1. The output's type must not be `HTLC` (i.e. type mismatch).
        1. If `proof.blockHeader.blockNumber` is less than `inputProof.transaction.outputs(inputProof.outputIndex).expiry` (i.e. the timelock has not expired):
            1. The hashlock digest `inputProof.transaction.outputs(inputProof.outputIndex).digest` must not match the hash of the preimage `input.preImage` (i.e. invalid preimage).

---

## File: src/v1.0.0/3. Concepts/3. Provers/Invalid Sum.md

Prover: Invalid Sums
===

Proves that a transaction spent more than allowed (i.e. sum of outputs > sum of inputs + fees).

A valid [transaction proof](../2.%20Verifiers/Transaction%20Proof.md), must be provided. The proof's [witness must also be valid](./../2.%20Verifiers/Witness.md). The proof's [data must also be valid](../2.%20Verifiers/Data.md).
1. For the provided token ID, the sum of the inputs must be greater than the sum of the outputs plus fees.
    1. Fees for a transaction are calculated as the feerate `proof.fee` times the transaction leaf length `proof.transaction.length`.

---

## File: src/v1.0.0/3. Concepts/3. Provers/Invalid Transaction.md

Prover: Invalid Transactions
===

Proves that a transaction was malformed. This involves attempting to parse the transaction leaf.

A valid [transaction proof](../2.%20Verifiers/Transaction%20Proof.md), `proof`, must be provided.
1. Get the transaction leaf component of the proof, `leaf = proof.transaction`.
1. Metadata count `leaf.metadata.length` must be less than `0` or more than [`INPUTS_MAX`](../1.%20Data%20Structures/Transactions.md).
1. As a sanity check, witnesses length in bytes `leaf.witnesses.length` must be less than `0` or more than `TRANSACTION_SIZE_MAX`. Same for inputs length `leaf.inputs.length` and outputs length `leaf.outputs.length`.
1. The leaf length `leaf.length` must be at less than [`TRANSACTION_SIZE_MIN`](../1.%20Data%20Structures/Transactions.md) or more than [`TRANSACTION_SIZE_MAX`](../1.%20Data%20Structures/Transactions.md).
1. The leaf total length `leaf.length+2` (since the `leaf.length` field itself [is `2` bytes](../1.%20Data%20Structures/Transactions.md)) must not match that size of the leaf component of the proof.

The witnesses are parsed:
1. For each witness, shift by the length of the witness:
    1. If the witness type is `Caller`:
        1. The transaction ID from the [witness registry](../1.%20Data%20Structures/Witness.md) at the witness ID must be `0` (i.e. the witness has not bee registered).
        1. The block number of the witness must be at least the block number in `proof` (i.e. the witness was not registered _strictly before_ the block was committed).
1. The number of parsed witnesses must be greater than [`INPUTS_MAX`](../1.%20Data%20Structures/Transactions.md).
1. The parsed length of witnesses must not match `leaf.witnesses.length`.

The inputs are parsed:
1. For each input, shift by the length of the input:
    1. The input type must be out of [bounds](../1.%20Data%20Structures/Inputs.md).
    1. The witness reference index `input.witnessIndex` must be out of bounds (i.e. at least the number of witnesses).
1. The number of parsed inputs must be greater than [`INPUTS_MAX`](../1.%20Data%20Structures/Transactions.md).
1. The parsed length of inputs must not match `leaf.inputs.length`.

The outputs are parsed:
1. For each output, shift by the length of the output:
    1. The output type must be out of [bounds](../1.%20Data%20Structures/Outputs.md).
    1. If the output type is `Transfer`, `Withdraw`, or `HTLC`:
        1. The output [token and amount fields](../1.%20Data%20Structures/Outputs.md) must be out of bounds.
        1. The output [owner field](../1.%20Data%20Structures/Outputs.md) must be out of bounds.
    1. If the output type is `HTLC`:
        1. the output [return owner field](../1.%20Data%20Structures/Outputs.md) must be out of bounds.
    1. If the output type is `Return`:
        1. The data length must be out of [bounds](../1.%20Data%20Structures/Outputs.md).
1. The number of parsed outputs must be greater than [`OUTPUTS_MAX`](../1.%20Data%20Structures/Transactions.md).
1. The parsed length of outputs must not match `leaf.outputs.length`.

The sizes are parsed:
1. The number of metadata elements must not match the number of inputs.

The metadata are parsed:
1. For each metadata, shift by [the length of the metadata](../1.%20Data%20Structures/Metadata.md):
    1. The metadata [fields](../1.%20Data%20Structures/Metadata.md) must be out of bounds.
1. The parsed length of metadata must not match `leaf.metadata.length`.

---

## File: src/v1.0.0/3. Concepts/3. Provers/Invalid Witness.md

Prover: Invalid Witnesses
===

Proves that a witness was invalid, and that a spend wasn't authorized.

A [transaction proof](./../1.%20Data%20Structures/Transactions.md) with [valid inputs](./../2.%20Verifiers/Inputs.md) must be provided. In addition, a list of state elements (one for each input of the transaction) must be provided.
1. For each input:
    1. The owner of the input must not match the owner of the corresponding state element.

---

## File: src/v1.0.0/3. Concepts/3. Provers/Malformed Block.md

Prover: Malformed Blocks
===

Proves that a [block](./../1.%20Data%20Structures/Blocks.md) was malformed. Given initial checks when [committing a new block](./../1.%20Data%20Structures/Blocks.md), the only case is when the Merkle root claimed in a [root header](./../1.%20Data%20Structures/Roots.md) is incorrectly computed.

1. A valid [block header](./../2.%20Verifiers/Block%20Header.md) and [root header](../1.%20Data%20Structures/Roots.md) must be provided, along with the original list of [transaction leaves](../1.%20Data%20Structures/Roots.md) committed to in the root header.
1. [Merkleizing](../2.%20Verifiers/Merkle%20Proof.md) the transaction leaves must not match the `merkleTreeRoot` field in the root header.

---

## File: src/v1.0.0/3. Concepts/4. Additional Modules/Funnels.md

Token Funnels
===

The usual flow for using an [ERC-20 token](https://github.com/ethereum/EIPs/issues/20) with a contract is to first `approve` an amount of tokens to transfer, then use `transferFrom` to actually transfer the tokens. In addition to poor UX, this has a number of issues:
1. Approving with a non-zero approved balance [allows an adversary to front-run the approval](https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729) and essential double-transfer tokens.
1. Users transferring tokens directly to a contract with `transfer` lose them, as the contract has no way of processing the transfer. This has resulted in [millions of dollars being burned](https://github.com/ethereum/eips/issues/223) through user error.

We provide a _token funnel_, a contract that can accept direct transfers magically. Intuitively, the funnel contract's deterministic [`CREATE2`](https://eips.ethereum.org/EIPS/eip-1014) address itself is a commitment to a deposit to Fuel (generally, the hash of: the sender address, the token type, and the token amount). After transferring tokens to this address, the funnel contract can be deployed at any time to transfer to deposit properly to Fuel, then immediately self-destruct.

Readers familiar with Bitcoin might notice this bears many similarities to [Pay-to-Script-Hash](https://en.bitcoin.it/wiki/Pay_to_script_hash).

Specific implementation details can be found [here](https://github.com/FuelLabs/fuel/blob/master/src/Funnel.yulp).

---

## File: src/v1.0.0/4. Tools and Applications/0. Fast Withdrawals.md

Fast Withdrawals
===

Withdrawals must normally wait [`finalizationDelay`](../3.%20Concepts/0.%20Fundamentals/7.%20Deployment%20Parameters.md) Ethereum blocks until the rollup block they are included in is finalized, at which point the funds can be withdrawn. As the finalization delay is supposed to be set quite long to be robust against censorship attacks and short-term chain congestion, this leads to poor UX. We can do better!

Fungible assets (ETH, ERC-20 tokens) can be withdrawn immediately with an [atomic swap](https://arxiv.org/abs/1801.09515) powered by [HTLCs](https://en.bitcoin.it/wiki/Hash_Time_Locked_Contracts), which is [one of the transaction output types](../3.%20Concepts/1.%20Data%20Structures/Outputs.md) Fuel supports.

Liquidity providers can offer up liquidity to users wanting to withdraw quickly, in exchange for a fee. Unlike lending protocols that are popular in DeFi, liquidity providers for fast withdrawals have zero systemic risk if they fully validate Fuel blocks before accepting a swap, as [valid blocks are guaranteed to finalize and they can always catch invalid blocks](./../3.%20Concepts/0.%20Fundamentals/2.%20Security%20Analysis.md).

---

## File: src/v1.0.0/4. Tools and Applications/1. Token Minting.md

Mass Token Minting
===

Minting and distributing tokens to a large number of users is a fairly common pattern, especially for community-driven applications and rewards or reputation points. Generally, tokens of this form are distributed in a permissioned manner by a central party, as un-gameable global reputation is non-trivial. However, once the tokens have been distributed they cannot be reclaimed by the issuer.

While it is certainly possible to do this relatively inexpensively by using one-to-many transactions (as Fuel supports [up to eight inputs and eight outputs](../3.%20Concepts/0.%20Fundamentals/4.%20Transaction%20Architecture.md) per transactions), we can do even better!

First, let us consider how one would make distributing such tokens cheaper on Ethereum today.  There are two easy, concrete methods:
1. The issuer pre-signs an authorization to mint a certain number of tokens for a particular user. She then sends the user the pre-signed authorization, which the user can redeem to the token contract for tokens. In this case, the issuer does not pay anything to distribute the token, as gas costs are covered by the user.
1. The issuer posts a _commitment_ (e.g. a Merkle root) of new coin balances to the token contract, which is an `O(1)`-cost operation. Users can then withdraw their tokens with a Merkle inclusion proof. In this case, the issuer pays a constant cost to distribute tokens, regardless of the number of tokens or users.

These schemes do not work on [Fuel v1](../5.%20Future%20Roadmap/1.%20Planned%20Features.md), as generic smart contracts are not supported. But what if we combined some of the aspects of the two approaches?

|  |
| :----------------------------------------------------: |
|              Pre-signed transaction tree.              |

The scheme is actually quite simple:
1. The issuer mints all the tokens at once on Ethereum, as a batch.
1. The tokens are deposited to Fuel.
1. The issuer now has a single UTXO (or rather, a deposit) with exactly the number of tokens they want to distribute.
1. The issuer recursively pre-signs transactions that split this UTXO into eight outputs _that are returned to the same address_. This forms a tree of pre-signed transactions, as shown in the diagram above.
1. Once the leaves are reached, each output is sent to the appropriate user's address. Users are then given the Merkle branch of pre-signed transactions to the transaction that would send them tokens.
1. A user that wishes to redeem their tokens broadcasts the branch of pre-signed transactions to Fuel (or, more specifically, the transactions that haven't yet been included on Fuel from potential previous users that do the same), then spends the appropriate output with a new (potentially fee-paying) transaction.

> **Note:** The issuer does _not_ send the pre-signed transactions to Fuel. Indeed, the pre-signed transactions do not pay any fees and so would not be included barring out-of-bounds negotiation. Rather, the user pays fees for an entire branch of pre-signed transactions using [Child-Pays-For-Parent (CPFP)](https://en.bitcoin.it/wiki/Transaction_fees#Feerates_for_dependent_transactions_.28child-pays-for-parent.29).

Readers familiar with Bitcoin's [CTV (BIP-119)](https://github.com/bitcoin/bips/blob/master/bip-0119.mediawiki) proposal should find this scheme very similar. However, rather than being enforced with on-chain rules, the commitment to a tree of transactions is simply an off-chain promise.

> **Note:** The threat model for distributing _tokens_ in this manner is not necessarily weaker than that of using a contract on Ethereum to enforce some rules. In this mass token minting scheme, the issuer could double-spend their pre-signed transactions. Notice however that the issuer in any case could simply just _not issue_ the tokens in the first place, as distribution is permissioned, to the same effect.

> **Note:** Equivalent functionality to [CTV (BIP-119)](https://github.com/bitcoin/bips/blob/master/bip-0119.mediawiki) is on the roadmap [as a future addition with covenants](../5.%20Future%20Roadmap/1.%20Planned%20Features.md).

---

## File: src/v1.0.0/4. Tools and Applications/2. Subscriptions.md

Subscriptions
===

Recurring cancellable subscriptions can be accomplished through pre-signed transactions with [HTLCs](./../3.%20Concepts/1.%20Data%20Structures/Outputs.md).

For a two-time recurring subscription, Alice can construct transactions as follows:

|  |
| :--------------------------------------------------: |
|        Subscription pre-signed transactions.         |

Each pre-signed transaction spends the HTLC UTXO of its parent after the timelock expires (which is set to the subscription period, e.g. 1 month for a monthly subscription). The transaction burns a portion of this UTXO (or otherwise pays for the subscription), and outputs the remainder to a new HTLC whose timelock is offset by another period. At any time, Alice can cancel the recurring payments by spending the HTLC UTXO with the hashlock condition, which is set to return the funds to an address she controls. Her wallet stores the preimage, or it can even be deterministically generated from her private key, e.g. by signing over the subscription identifier.

An additional output can be added to pay fees to the block producer, but that is an implementation detail.

---

## File: src/v1.0.0/4. Tools and Applications/3. Non-Custodial Exchanges.md

Non-Custodial Exchanges
===

|  |
| :-----------------------------------: |
|     Exchange settlement on Fuel.      |

Non-custodial exchanges can be built by anyone on top of Fuel today. The order book is kept, and matching is done, off-chain, with settlement of each order happening on Fuel as a multi-user transaction.

In this example, Alice and Bob each consume one of their UTXOs in a transaction, which swaps the owner of each asset to produce two new UTXOs. (Fees and change are an implementation detail.) Note that since users sign over _an entire transaction_, there is no possibility of theft. Alice and Bob can each sign the transaction individually, and any time before the transaction is confirmed, can spend their UTXO in a different transaction to cancel the order.

---

## File: src/v1.0.0/5. Future Roadmap/1. Planned Features.md

Roadmap
===

Fuel v0
---

Released as testnet at the beginning of 2020 ([announcement](https://medium.com/@fuellabs/announcing-the-fuel-v0-open-beta-565a2d340fc3)).

[Source code](https://github.com/FuelLabs/fuel-core).

Features:
- UTXO-based optimistic rollup
- Support simple transfers, deposits, and withdrawals
- [Burner wallet integration](https://medium.com/@fuellabs/burner-wallet-fuel-7b8ce8e54aff)
- [Reddit community points transfer and swap demo](https://reddit.com/r/CryptoCurrency/comments/gonjm3/tldr_moons_and_bricks_go_brrr/)

Fuel v1
---

Current release, as testnet.

[Source code](https://github.com/FuelLabs/fuel).

Features in addition to [v0](#fuel-v0):
- Optimize transaction format, reducing transaction sizes by ~50%
- Contract refactoring in [Yul+](https://github.com/FuelLabs/yulp) for additional gas cost savings
- Support HTLC and Return outputs
- Extra module: Token funnel
- Additional client-side applications:
    - mass token minting
    - liquidity provider for fast withdrawals
    - non-custodial exchange

Fuel v1.5
---

Future release, expected EOY 2020.

Features in addition to [v1](#fuel-v1):
- BLS signature aggregation (bringing TPS to 1,500-2,000)
- Native NFT support
- Optimistic mass migration

Fuel v2
---

Future released, expected 2021.

Features in addition to [v1.5](#fuel-v15):
- Predicate scripting
- Covenants
- Configurable state introspection (for Ethereum-style smart contracts)

---

## File: .github/workflows/markdown_link_checker.yml

name: Check Markdown links

on: push

jobs:
  markdown-link-check:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Create config file
        run: |
          echo "{ \"replacementPatterns\": [ { \"pattern\": \"^/\", \"replacement\": \"/github/workspace/\" } ] }" > config.json
      - name: Check links
        uses: gaurav-nelson/github-action-markdown-link-check@1.0.4
        with:
          config-file: config.json